ActivityManagerService.java revision 83520b95124e0fcaaf3154a7a267f6be0205bc74
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.content.pm.PackageManager.PERMISSION_GRANTED;
20import static com.android.internal.util.XmlUtils.readBooleanAttribute;
21import static com.android.internal.util.XmlUtils.readIntAttribute;
22import static com.android.internal.util.XmlUtils.readLongAttribute;
23import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
24import static com.android.internal.util.XmlUtils.writeIntAttribute;
25import static com.android.internal.util.XmlUtils.writeLongAttribute;
26import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
27import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
28import static org.xmlpull.v1.XmlPullParser.START_TAG;
29import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
30
31import android.Manifest;
32import android.app.AppOpsManager;
33import android.app.IActivityContainer;
34import android.app.IActivityContainerCallback;
35import android.appwidget.AppWidgetManager;
36import android.graphics.Rect;
37import android.os.BatteryStats;
38import android.os.PersistableBundle;
39import android.service.voice.IVoiceInteractionSession;
40import android.util.ArrayMap;
41
42import com.android.internal.R;
43import com.android.internal.annotations.GuardedBy;
44import com.android.internal.app.IAppOpsService;
45import com.android.internal.app.IVoiceInteractor;
46import com.android.internal.app.ProcessMap;
47import com.android.internal.app.ProcessStats;
48import com.android.internal.content.PackageMonitor;
49import com.android.internal.os.BackgroundThread;
50import com.android.internal.os.BatteryStatsImpl;
51import com.android.internal.os.ProcessCpuTracker;
52import com.android.internal.os.TransferPipe;
53import com.android.internal.os.Zygote;
54import com.android.internal.util.FastPrintWriter;
55import com.android.internal.util.FastXmlSerializer;
56import com.android.internal.util.MemInfoReader;
57import com.android.internal.util.Preconditions;
58import com.android.server.AppOpsService;
59import com.android.server.AttributeCache;
60import com.android.server.IntentResolver;
61import com.android.server.LocalServices;
62import com.android.server.ServiceThread;
63import com.android.server.SystemService;
64import com.android.server.SystemServiceManager;
65import com.android.server.Watchdog;
66import com.android.server.am.ActivityStack.ActivityState;
67import com.android.server.firewall.IntentFirewall;
68import com.android.server.pm.UserManagerService;
69import com.android.server.wm.AppTransition;
70import com.android.server.wm.WindowManagerService;
71import com.google.android.collect.Lists;
72import com.google.android.collect.Maps;
73
74import libcore.io.IoUtils;
75
76import org.xmlpull.v1.XmlPullParser;
77import org.xmlpull.v1.XmlPullParserException;
78import org.xmlpull.v1.XmlSerializer;
79
80import android.app.Activity;
81import android.app.ActivityManager;
82import android.app.ActivityManager.RunningTaskInfo;
83import android.app.ActivityManager.StackInfo;
84import android.app.ActivityManagerInternal;
85import android.app.ActivityManagerNative;
86import android.app.ActivityOptions;
87import android.app.ActivityThread;
88import android.app.AlertDialog;
89import android.app.AppGlobals;
90import android.app.ApplicationErrorReport;
91import android.app.Dialog;
92import android.app.IActivityController;
93import android.app.IApplicationThread;
94import android.app.IInstrumentationWatcher;
95import android.app.INotificationManager;
96import android.app.IProcessObserver;
97import android.app.IServiceConnection;
98import android.app.IStopUserCallback;
99import android.app.IUiAutomationConnection;
100import android.app.IUserSwitchObserver;
101import android.app.Instrumentation;
102import android.app.Notification;
103import android.app.NotificationManager;
104import android.app.PendingIntent;
105import android.app.backup.IBackupManager;
106import android.content.ActivityNotFoundException;
107import android.content.BroadcastReceiver;
108import android.content.ClipData;
109import android.content.ComponentCallbacks2;
110import android.content.ComponentName;
111import android.content.ContentProvider;
112import android.content.ContentResolver;
113import android.content.Context;
114import android.content.DialogInterface;
115import android.content.IContentProvider;
116import android.content.IIntentReceiver;
117import android.content.IIntentSender;
118import android.content.Intent;
119import android.content.IntentFilter;
120import android.content.IntentSender;
121import android.content.pm.ActivityInfo;
122import android.content.pm.ApplicationInfo;
123import android.content.pm.ConfigurationInfo;
124import android.content.pm.IPackageDataObserver;
125import android.content.pm.IPackageManager;
126import android.content.pm.InstrumentationInfo;
127import android.content.pm.PackageInfo;
128import android.content.pm.PackageManager;
129import android.content.pm.ParceledListSlice;
130import android.content.pm.UserInfo;
131import android.content.pm.PackageManager.NameNotFoundException;
132import android.content.pm.PathPermission;
133import android.content.pm.ProviderInfo;
134import android.content.pm.ResolveInfo;
135import android.content.pm.ServiceInfo;
136import android.content.res.CompatibilityInfo;
137import android.content.res.Configuration;
138import android.graphics.Bitmap;
139import android.net.Proxy;
140import android.net.ProxyInfo;
141import android.net.Uri;
142import android.os.Binder;
143import android.os.Build;
144import android.os.Bundle;
145import android.os.Debug;
146import android.os.DropBoxManager;
147import android.os.Environment;
148import android.os.FactoryTest;
149import android.os.FileObserver;
150import android.os.FileUtils;
151import android.os.Handler;
152import android.os.IBinder;
153import android.os.IPermissionController;
154import android.os.IRemoteCallback;
155import android.os.IUserManager;
156import android.os.Looper;
157import android.os.Message;
158import android.os.Parcel;
159import android.os.ParcelFileDescriptor;
160import android.os.Process;
161import android.os.RemoteCallbackList;
162import android.os.RemoteException;
163import android.os.SELinux;
164import android.os.ServiceManager;
165import android.os.StrictMode;
166import android.os.SystemClock;
167import android.os.SystemProperties;
168import android.os.UpdateLock;
169import android.os.UserHandle;
170import android.provider.Settings;
171import android.text.format.DateUtils;
172import android.text.format.Time;
173import android.util.AtomicFile;
174import android.util.EventLog;
175import android.util.Log;
176import android.util.Pair;
177import android.util.PrintWriterPrinter;
178import android.util.Slog;
179import android.util.SparseArray;
180import android.util.TimeUtils;
181import android.util.Xml;
182import android.view.Gravity;
183import android.view.LayoutInflater;
184import android.view.View;
185import android.view.WindowManager;
186
187import java.io.BufferedInputStream;
188import java.io.BufferedOutputStream;
189import java.io.DataInputStream;
190import java.io.DataOutputStream;
191import java.io.File;
192import java.io.FileDescriptor;
193import java.io.FileInputStream;
194import java.io.FileNotFoundException;
195import java.io.FileOutputStream;
196import java.io.IOException;
197import java.io.InputStreamReader;
198import java.io.PrintWriter;
199import java.io.StringWriter;
200import java.lang.ref.WeakReference;
201import java.util.ArrayList;
202import java.util.Arrays;
203import java.util.Collections;
204import java.util.Comparator;
205import java.util.HashMap;
206import java.util.HashSet;
207import java.util.Iterator;
208import java.util.List;
209import java.util.Locale;
210import java.util.Map;
211import java.util.Set;
212import java.util.concurrent.atomic.AtomicBoolean;
213import java.util.concurrent.atomic.AtomicLong;
214
215public final class ActivityManagerService extends ActivityManagerNative
216        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
217    private static final String USER_DATA_DIR = "/data/user/";
218    static final String TAG = "ActivityManager";
219    static final String TAG_MU = "ActivityManagerServiceMU";
220    static final boolean DEBUG = false;
221    static final boolean localLOGV = DEBUG;
222    static final boolean DEBUG_BACKUP = localLOGV || false;
223    static final boolean DEBUG_BROADCAST = localLOGV || false;
224    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
225    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
226    static final boolean DEBUG_CLEANUP = localLOGV || false;
227    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
228    static final boolean DEBUG_FOCUS = false;
229    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
230    static final boolean DEBUG_MU = localLOGV || false;
231    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
232    static final boolean DEBUG_LRU = localLOGV || false;
233    static final boolean DEBUG_PAUSE = localLOGV || false;
234    static final boolean DEBUG_POWER = localLOGV || false;
235    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
236    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
237    static final boolean DEBUG_PROCESSES = localLOGV || false;
238    static final boolean DEBUG_PROVIDER = localLOGV || false;
239    static final boolean DEBUG_RESULTS = localLOGV || false;
240    static final boolean DEBUG_SERVICE = localLOGV || false;
241    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
242    static final boolean DEBUG_STACK = localLOGV || false;
243    static final boolean DEBUG_SWITCH = localLOGV || false;
244    static final boolean DEBUG_TASKS = localLOGV || false;
245    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
246    static final boolean DEBUG_TRANSITION = localLOGV || false;
247    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
248    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
249    static final boolean DEBUG_VISBILITY = localLOGV || false;
250    static final boolean DEBUG_PSS = localLOGV || false;
251    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
252    static final boolean VALIDATE_TOKENS = false;
253    static final boolean SHOW_ACTIVITY_START_TIME = true;
254
255    // Control over CPU and battery monitoring.
256    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
257    static final boolean MONITOR_CPU_USAGE = true;
258    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
259    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
260    static final boolean MONITOR_THREAD_CPU_USAGE = false;
261
262    // The flags that are set for all calls we make to the package manager.
263    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
264
265    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
266
267    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
268
269    // Maximum number of recent tasks that we can remember.
270    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20;
271
272    // Amount of time after a call to stopAppSwitches() during which we will
273    // prevent further untrusted switches from happening.
274    static final long APP_SWITCH_DELAY_TIME = 5*1000;
275
276    // How long we wait for a launched process to attach to the activity manager
277    // before we decide it's never going to come up for real.
278    static final int PROC_START_TIMEOUT = 10*1000;
279
280    // How long we wait for a launched process to attach to the activity manager
281    // before we decide it's never going to come up for real, when the process was
282    // started with a wrapper for instrumentation (such as Valgrind) because it
283    // could take much longer than usual.
284    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
285
286    // How long to wait after going idle before forcing apps to GC.
287    static final int GC_TIMEOUT = 5*1000;
288
289    // The minimum amount of time between successive GC requests for a process.
290    static final int GC_MIN_INTERVAL = 60*1000;
291
292    // The minimum amount of time between successive PSS requests for a process.
293    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
294
295    // The minimum amount of time between successive PSS requests for a process
296    // when the request is due to the memory state being lowered.
297    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
298
299    // The rate at which we check for apps using excessive power -- 15 mins.
300    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
301
302    // The minimum sample duration we will allow before deciding we have
303    // enough data on wake locks to start killing things.
304    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
305
306    // The minimum sample duration we will allow before deciding we have
307    // enough data on CPU usage to start killing things.
308    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
309
310    // How long we allow a receiver to run before giving up on it.
311    static final int BROADCAST_FG_TIMEOUT = 10*1000;
312    static final int BROADCAST_BG_TIMEOUT = 60*1000;
313
314    // How long we wait until we timeout on key dispatching.
315    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
316
317    // How long we wait until we timeout on key dispatching during instrumentation.
318    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
319
320    // Amount of time we wait for observers to handle a user switch before
321    // giving up on them and unfreezing the screen.
322    static final int USER_SWITCH_TIMEOUT = 2*1000;
323
324    // Maximum number of users we allow to be running at a time.
325    static final int MAX_RUNNING_USERS = 3;
326
327    // How long to wait in getAssistContextExtras for the activity and foreground services
328    // to respond with the result.
329    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
330
331    // Maximum number of persisted Uri grants a package is allowed
332    static final int MAX_PERSISTED_URI_GRANTS = 128;
333
334    static final int MY_PID = Process.myPid();
335
336    static final String[] EMPTY_STRING_ARRAY = new String[0];
337
338    // How many bytes to write into the dropbox log before truncating
339    static final int DROPBOX_MAX_SIZE = 256 * 1024;
340
341    /** All system services */
342    SystemServiceManager mSystemServiceManager;
343
344    /** Run all ActivityStacks through this */
345    ActivityStackSupervisor mStackSupervisor;
346
347    public IntentFirewall mIntentFirewall;
348
349    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
350    // default actuion automatically.  Important for devices without direct input
351    // devices.
352    private boolean mShowDialogs = true;
353
354    /**
355     * Description of a request to start a new activity, which has been held
356     * due to app switches being disabled.
357     */
358    static class PendingActivityLaunch {
359        final ActivityRecord r;
360        final ActivityRecord sourceRecord;
361        final int startFlags;
362        final ActivityStack stack;
363
364        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
365                int _startFlags, ActivityStack _stack) {
366            r = _r;
367            sourceRecord = _sourceRecord;
368            startFlags = _startFlags;
369            stack = _stack;
370        }
371    }
372
373    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
374            = new ArrayList<PendingActivityLaunch>();
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    final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
411
412    public class PendingAssistExtras extends Binder implements Runnable {
413        public final ActivityRecord activity;
414        public boolean haveResult = false;
415        public Bundle result = null;
416        public PendingAssistExtras(ActivityRecord _activity) {
417            activity = _activity;
418        }
419        @Override
420        public void run() {
421            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
422            synchronized (this) {
423                haveResult = true;
424                notifyAll();
425            }
426        }
427    }
428
429    final ArrayList<PendingAssistExtras> mPendingAssistExtras
430            = new ArrayList<PendingAssistExtras>();
431
432    /**
433     * Process management.
434     */
435    final ProcessList mProcessList = new ProcessList();
436
437    /**
438     * All of the applications we currently have running organized by name.
439     * The keys are strings of the application package name (as
440     * returned by the package manager), and the keys are ApplicationRecord
441     * objects.
442     */
443    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
444
445    /**
446     * Tracking long-term execution of processes to look for abuse and other
447     * bad app behavior.
448     */
449    final ProcessStatsService mProcessStats;
450
451    /**
452     * The currently running isolated processes.
453     */
454    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
455
456    /**
457     * Counter for assigning isolated process uids, to avoid frequently reusing the
458     * same ones.
459     */
460    int mNextIsolatedProcessUid = 0;
461
462    /**
463     * The currently running heavy-weight process, if any.
464     */
465    ProcessRecord mHeavyWeightProcess = null;
466
467    /**
468     * The last time that various processes have crashed.
469     */
470    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
471
472    /**
473     * Information about a process that is currently marked as bad.
474     */
475    static final class BadProcessInfo {
476        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
477            this.time = time;
478            this.shortMsg = shortMsg;
479            this.longMsg = longMsg;
480            this.stack = stack;
481        }
482
483        final long time;
484        final String shortMsg;
485        final String longMsg;
486        final String stack;
487    }
488
489    /**
490     * Set of applications that we consider to be bad, and will reject
491     * incoming broadcasts from (which the user has no control over).
492     * Processes are added to this set when they have crashed twice within
493     * a minimum amount of time; they are removed from it when they are
494     * later restarted (hopefully due to some user action).  The value is the
495     * time it was added to the list.
496     */
497    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
498
499    /**
500     * All of the processes we currently have running organized by pid.
501     * The keys are the pid running the application.
502     *
503     * <p>NOTE: This object is protected by its own lock, NOT the global
504     * activity manager lock!
505     */
506    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
507
508    /**
509     * All of the processes that have been forced to be foreground.  The key
510     * is the pid of the caller who requested it (we hold a death
511     * link on it).
512     */
513    abstract class ForegroundToken implements IBinder.DeathRecipient {
514        int pid;
515        IBinder token;
516    }
517    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
518
519    /**
520     * List of records for processes that someone had tried to start before the
521     * system was ready.  We don't start them at that point, but ensure they
522     * are started by the time booting is complete.
523     */
524    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
525
526    /**
527     * List of persistent applications that are in the process
528     * of being started.
529     */
530    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
531
532    /**
533     * Processes that are being forcibly torn down.
534     */
535    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
536
537    /**
538     * List of running applications, sorted by recent usage.
539     * The first entry in the list is the least recently used.
540     */
541    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
542
543    /**
544     * Where in mLruProcesses that the processes hosting activities start.
545     */
546    int mLruProcessActivityStart = 0;
547
548    /**
549     * Where in mLruProcesses that the processes hosting services start.
550     * This is after (lower index) than mLruProcessesActivityStart.
551     */
552    int mLruProcessServiceStart = 0;
553
554    /**
555     * List of processes that should gc as soon as things are idle.
556     */
557    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
558
559    /**
560     * Processes we want to collect PSS data from.
561     */
562    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
563
564    /**
565     * Last time we requested PSS data of all processes.
566     */
567    long mLastFullPssTime = SystemClock.uptimeMillis();
568
569    /**
570     * This is the process holding what we currently consider to be
571     * the "home" activity.
572     */
573    ProcessRecord mHomeProcess;
574
575    /**
576     * This is the process holding the activity the user last visited that
577     * is in a different process from the one they are currently in.
578     */
579    ProcessRecord mPreviousProcess;
580
581    /**
582     * The time at which the previous process was last visible.
583     */
584    long mPreviousProcessVisibleTime;
585
586    /**
587     * Which uses have been started, so are allowed to run code.
588     */
589    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
590
591    /**
592     * LRU list of history of current users.  Most recently current is at the end.
593     */
594    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
595
596    /**
597     * Constant array of the users that are currently started.
598     */
599    int[] mStartedUserArray = new int[] { 0 };
600
601    /**
602     * Registered observers of the user switching mechanics.
603     */
604    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
605            = new RemoteCallbackList<IUserSwitchObserver>();
606
607    /**
608     * Currently active user switch.
609     */
610    Object mCurUserSwitchCallback;
611
612    /**
613     * Packages that the user has asked to have run in screen size
614     * compatibility mode instead of filling the screen.
615     */
616    final CompatModePackages mCompatModePackages;
617
618    /**
619     * Set of IntentSenderRecord objects that are currently active.
620     */
621    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
622            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
623
624    /**
625     * Fingerprints (hashCode()) of stack traces that we've
626     * already logged DropBox entries for.  Guarded by itself.  If
627     * something (rogue user app) forces this over
628     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
629     */
630    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
631    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
632
633    /**
634     * Strict Mode background batched logging state.
635     *
636     * The string buffer is guarded by itself, and its lock is also
637     * used to determine if another batched write is already
638     * in-flight.
639     */
640    private final StringBuilder mStrictModeBuffer = new StringBuilder();
641
642    /**
643     * Keeps track of all IIntentReceivers that have been registered for
644     * broadcasts.  Hash keys are the receiver IBinder, hash value is
645     * a ReceiverList.
646     */
647    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
648            new HashMap<IBinder, ReceiverList>();
649
650    /**
651     * Resolver for broadcast intents to registered receivers.
652     * Holds BroadcastFilter (subclass of IntentFilter).
653     */
654    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
655            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
656        @Override
657        protected boolean allowFilterResult(
658                BroadcastFilter filter, List<BroadcastFilter> dest) {
659            IBinder target = filter.receiverList.receiver.asBinder();
660            for (int i=dest.size()-1; i>=0; i--) {
661                if (dest.get(i).receiverList.receiver.asBinder() == target) {
662                    return false;
663                }
664            }
665            return true;
666        }
667
668        @Override
669        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
670            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
671                    || userId == filter.owningUserId) {
672                return super.newResult(filter, match, userId);
673            }
674            return null;
675        }
676
677        @Override
678        protected BroadcastFilter[] newArray(int size) {
679            return new BroadcastFilter[size];
680        }
681
682        @Override
683        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
684            return packageName.equals(filter.packageName);
685        }
686    };
687
688    /**
689     * State of all active sticky broadcasts per user.  Keys are the action of the
690     * sticky Intent, values are an ArrayList of all broadcasted intents with
691     * that action (which should usually be one).  The SparseArray is keyed
692     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
693     * for stickies that are sent to all users.
694     */
695    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
696            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
697
698    final ActiveServices mServices;
699
700    /**
701     * Backup/restore process management
702     */
703    String mBackupAppName = null;
704    BackupRecord mBackupTarget = null;
705
706    final ProviderMap mProviderMap;
707
708    /**
709     * List of content providers who have clients waiting for them.  The
710     * application is currently being launched and the provider will be
711     * removed from this list once it is published.
712     */
713    final ArrayList<ContentProviderRecord> mLaunchingProviders
714            = new ArrayList<ContentProviderRecord>();
715
716    /**
717     * File storing persisted {@link #mGrantedUriPermissions}.
718     */
719    private final AtomicFile mGrantFile;
720
721    /** XML constants used in {@link #mGrantFile} */
722    private static final String TAG_URI_GRANTS = "uri-grants";
723    private static final String TAG_URI_GRANT = "uri-grant";
724    private static final String ATTR_USER_HANDLE = "userHandle";
725    private static final String ATTR_SOURCE_PKG = "sourcePkg";
726    private static final String ATTR_TARGET_PKG = "targetPkg";
727    private static final String ATTR_URI = "uri";
728    private static final String ATTR_MODE_FLAGS = "modeFlags";
729    private static final String ATTR_CREATED_TIME = "createdTime";
730    private static final String ATTR_PREFIX = "prefix";
731
732    /**
733     * Global set of specific {@link Uri} permissions that have been granted.
734     * This optimized lookup structure maps from {@link UriPermission#targetUid}
735     * to {@link UriPermission#uri} to {@link UriPermission}.
736     */
737    @GuardedBy("this")
738    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
739            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
740
741    public static class GrantUri {
742        public final Uri uri;
743        public final boolean prefix;
744
745        public GrantUri(Uri uri, boolean prefix) {
746            this.uri = uri;
747            this.prefix = prefix;
748        }
749
750        @Override
751        public int hashCode() {
752            return toString().hashCode();
753        }
754
755        @Override
756        public boolean equals(Object o) {
757            if (o instanceof GrantUri) {
758                GrantUri other = (GrantUri) o;
759                return uri.equals(other.uri) && prefix == other.prefix;
760            }
761            return false;
762        }
763
764        @Override
765        public String toString() {
766            if (prefix) {
767                return uri.toString() + " [prefix]";
768            } else {
769                return uri.toString();
770            }
771        }
772    }
773
774    CoreSettingsObserver mCoreSettingsObserver;
775
776    /**
777     * Thread-local storage used to carry caller permissions over through
778     * indirect content-provider access.
779     */
780    private class Identity {
781        public int pid;
782        public int uid;
783
784        Identity(int _pid, int _uid) {
785            pid = _pid;
786            uid = _uid;
787        }
788    }
789
790    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
791
792    /**
793     * All information we have collected about the runtime performance of
794     * any user id that can impact battery performance.
795     */
796    final BatteryStatsService mBatteryStatsService;
797
798    /**
799     * Information about component usage
800     */
801    final UsageStatsService mUsageStatsService;
802
803    /**
804     * Information about and control over application operations
805     */
806    final AppOpsService mAppOpsService;
807
808    /**
809     * Current configuration information.  HistoryRecord objects are given
810     * a reference to this object to indicate which configuration they are
811     * currently running in, so this object must be kept immutable.
812     */
813    Configuration mConfiguration = new Configuration();
814
815    /**
816     * Current sequencing integer of the configuration, for skipping old
817     * configurations.
818     */
819    int mConfigurationSeq = 0;
820
821    /**
822     * Hardware-reported OpenGLES version.
823     */
824    final int GL_ES_VERSION;
825
826    /**
827     * List of initialization arguments to pass to all processes when binding applications to them.
828     * For example, references to the commonly used services.
829     */
830    HashMap<String, IBinder> mAppBindArgs;
831
832    /**
833     * Temporary to avoid allocations.  Protected by main lock.
834     */
835    final StringBuilder mStringBuilder = new StringBuilder(256);
836
837    /**
838     * Used to control how we initialize the service.
839     */
840    ComponentName mTopComponent;
841    String mTopAction = Intent.ACTION_MAIN;
842    String mTopData;
843    boolean mProcessesReady = false;
844    boolean mSystemReady = false;
845    boolean mBooting = false;
846    boolean mWaitingUpdate = false;
847    boolean mDidUpdate = false;
848    boolean mOnBattery = false;
849    boolean mLaunchWarningShown = false;
850
851    Context mContext;
852
853    int mFactoryTest;
854
855    boolean mCheckedForSetup;
856
857    /**
858     * The time at which we will allow normal application switches again,
859     * after a call to {@link #stopAppSwitches()}.
860     */
861    long mAppSwitchesAllowedTime;
862
863    /**
864     * This is set to true after the first switch after mAppSwitchesAllowedTime
865     * is set; any switches after that will clear the time.
866     */
867    boolean mDidAppSwitch;
868
869    /**
870     * Last time (in realtime) at which we checked for power usage.
871     */
872    long mLastPowerCheckRealtime;
873
874    /**
875     * Last time (in uptime) at which we checked for power usage.
876     */
877    long mLastPowerCheckUptime;
878
879    /**
880     * Set while we are wanting to sleep, to prevent any
881     * activities from being started/resumed.
882     */
883    private boolean mSleeping = false;
884
885    /**
886     * Set while we are running a voice interaction.  This overrides
887     * sleeping while it is active.
888     */
889    private boolean mRunningVoice = false;
890
891    /**
892     * State of external calls telling us if the device is asleep.
893     */
894    private boolean mWentToSleep = false;
895
896    /**
897     * State of external call telling us if the lock screen is shown.
898     */
899    private boolean mLockScreenShown = false;
900
901    /**
902     * Set if we are shutting down the system, similar to sleeping.
903     */
904    boolean mShuttingDown = false;
905
906    /**
907     * Current sequence id for oom_adj computation traversal.
908     */
909    int mAdjSeq = 0;
910
911    /**
912     * Current sequence id for process LRU updating.
913     */
914    int mLruSeq = 0;
915
916    /**
917     * Keep track of the non-cached/empty process we last found, to help
918     * determine how to distribute cached/empty processes next time.
919     */
920    int mNumNonCachedProcs = 0;
921
922    /**
923     * Keep track of the number of cached hidden procs, to balance oom adj
924     * distribution between those and empty procs.
925     */
926    int mNumCachedHiddenProcs = 0;
927
928    /**
929     * Keep track of the number of service processes we last found, to
930     * determine on the next iteration which should be B services.
931     */
932    int mNumServiceProcs = 0;
933    int mNewNumAServiceProcs = 0;
934    int mNewNumServiceProcs = 0;
935
936    /**
937     * Allow the current computed overall memory level of the system to go down?
938     * This is set to false when we are killing processes for reasons other than
939     * memory management, so that the now smaller process list will not be taken as
940     * an indication that memory is tighter.
941     */
942    boolean mAllowLowerMemLevel = false;
943
944    /**
945     * The last computed memory level, for holding when we are in a state that
946     * processes are going away for other reasons.
947     */
948    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
949
950    /**
951     * The last total number of process we have, to determine if changes actually look
952     * like a shrinking number of process due to lower RAM.
953     */
954    int mLastNumProcesses;
955
956    /**
957     * The uptime of the last time we performed idle maintenance.
958     */
959    long mLastIdleTime = SystemClock.uptimeMillis();
960
961    /**
962     * Total time spent with RAM that has been added in the past since the last idle time.
963     */
964    long mLowRamTimeSinceLastIdle = 0;
965
966    /**
967     * If RAM is currently low, when that horrible situation started.
968     */
969    long mLowRamStartTime = 0;
970
971    /**
972     * For reporting to battery stats the current top application.
973     */
974    private String mCurResumedPackage = null;
975    private int mCurResumedUid = -1;
976
977    /**
978     * For reporting to battery stats the apps currently running foreground
979     * service.  The ProcessMap is package/uid tuples; each of these contain
980     * an array of the currently foreground processes.
981     */
982    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
983            = new ProcessMap<ArrayList<ProcessRecord>>();
984
985    /**
986     * This is set if we had to do a delayed dexopt of an app before launching
987     * it, to increase the ANR timeouts in that case.
988     */
989    boolean mDidDexOpt;
990
991    /**
992     * Set if the systemServer made a call to enterSafeMode.
993     */
994    boolean mSafeMode;
995
996    String mDebugApp = null;
997    boolean mWaitForDebugger = false;
998    boolean mDebugTransient = false;
999    String mOrigDebugApp = null;
1000    boolean mOrigWaitForDebugger = false;
1001    boolean mAlwaysFinishActivities = false;
1002    IActivityController mController = null;
1003    String mProfileApp = null;
1004    ProcessRecord mProfileProc = null;
1005    String mProfileFile;
1006    ParcelFileDescriptor mProfileFd;
1007    int mProfileType = 0;
1008    boolean mAutoStopProfiler = false;
1009    String mOpenGlTraceApp = null;
1010
1011    static class ProcessChangeItem {
1012        static final int CHANGE_ACTIVITIES = 1<<0;
1013        static final int CHANGE_PROCESS_STATE = 1<<1;
1014        int changes;
1015        int uid;
1016        int pid;
1017        int processState;
1018        boolean foregroundActivities;
1019    }
1020
1021    final RemoteCallbackList<IProcessObserver> mProcessObservers
1022            = new RemoteCallbackList<IProcessObserver>();
1023    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1024
1025    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1026            = new ArrayList<ProcessChangeItem>();
1027    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1028            = new ArrayList<ProcessChangeItem>();
1029
1030    /**
1031     * Runtime CPU use collection thread.  This object's lock is used to
1032     * protect all related state.
1033     */
1034    final Thread mProcessCpuThread;
1035
1036    /**
1037     * Used to collect process stats when showing not responding dialog.
1038     * Protected by mProcessCpuThread.
1039     */
1040    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1041            MONITOR_THREAD_CPU_USAGE);
1042    final AtomicLong mLastCpuTime = new AtomicLong(0);
1043    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1044
1045    long mLastWriteTime = 0;
1046
1047    /**
1048     * Used to retain an update lock when the foreground activity is in
1049     * immersive mode.
1050     */
1051    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1052
1053    /**
1054     * Set to true after the system has finished booting.
1055     */
1056    boolean mBooted = false;
1057
1058    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1059    int mProcessLimitOverride = -1;
1060
1061    WindowManagerService mWindowManager;
1062
1063    final ActivityThread mSystemThread;
1064
1065    int mCurrentUserId = 0;
1066    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1067    private UserManagerService mUserManager;
1068
1069    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1070        final ProcessRecord mApp;
1071        final int mPid;
1072        final IApplicationThread mAppThread;
1073
1074        AppDeathRecipient(ProcessRecord app, int pid,
1075                IApplicationThread thread) {
1076            if (localLOGV) Slog.v(
1077                TAG, "New death recipient " + this
1078                + " for thread " + thread.asBinder());
1079            mApp = app;
1080            mPid = pid;
1081            mAppThread = thread;
1082        }
1083
1084        @Override
1085        public void binderDied() {
1086            if (localLOGV) Slog.v(
1087                TAG, "Death received in " + this
1088                + " for thread " + mAppThread.asBinder());
1089            synchronized(ActivityManagerService.this) {
1090                appDiedLocked(mApp, mPid, mAppThread);
1091            }
1092        }
1093    }
1094
1095    static final int SHOW_ERROR_MSG = 1;
1096    static final int SHOW_NOT_RESPONDING_MSG = 2;
1097    static final int SHOW_FACTORY_ERROR_MSG = 3;
1098    static final int UPDATE_CONFIGURATION_MSG = 4;
1099    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1100    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1101    static final int SERVICE_TIMEOUT_MSG = 12;
1102    static final int UPDATE_TIME_ZONE = 13;
1103    static final int SHOW_UID_ERROR_MSG = 14;
1104    static final int IM_FEELING_LUCKY_MSG = 15;
1105    static final int PROC_START_TIMEOUT_MSG = 20;
1106    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1107    static final int KILL_APPLICATION_MSG = 22;
1108    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1109    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1110    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1111    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1112    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1113    static final int CLEAR_DNS_CACHE_MSG = 28;
1114    static final int UPDATE_HTTP_PROXY_MSG = 29;
1115    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1116    static final int DISPATCH_PROCESSES_CHANGED = 31;
1117    static final int DISPATCH_PROCESS_DIED = 32;
1118    static final int REPORT_MEM_USAGE_MSG = 33;
1119    static final int REPORT_USER_SWITCH_MSG = 34;
1120    static final int CONTINUE_USER_SWITCH_MSG = 35;
1121    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1122    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1123    static final int PERSIST_URI_GRANTS_MSG = 38;
1124    static final int REQUEST_ALL_PSS_MSG = 39;
1125    static final int START_PROFILES_MSG = 40;
1126    static final int UPDATE_TIME = 41;
1127    static final int SYSTEM_USER_START_MSG = 42;
1128    static final int SYSTEM_USER_CURRENT_MSG = 43;
1129
1130    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1131    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1132    static final int FIRST_COMPAT_MODE_MSG = 300;
1133    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1134
1135    AlertDialog mUidAlert;
1136    CompatModeDialog mCompatModeDialog;
1137    long mLastMemUsageReportTime = 0;
1138
1139    /**
1140     * Flag whether the current user is a "monkey", i.e. whether
1141     * the UI is driven by a UI automation tool.
1142     */
1143    private boolean mUserIsMonkey;
1144
1145    final ServiceThread mHandlerThread;
1146    final MainHandler mHandler;
1147
1148    final class MainHandler extends Handler {
1149        public MainHandler(Looper looper) {
1150            super(looper, null, true);
1151        }
1152
1153        @Override
1154        public void handleMessage(Message msg) {
1155            switch (msg.what) {
1156            case SHOW_ERROR_MSG: {
1157                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1158                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1159                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1160                synchronized (ActivityManagerService.this) {
1161                    ProcessRecord proc = (ProcessRecord)data.get("app");
1162                    AppErrorResult res = (AppErrorResult) data.get("result");
1163                    if (proc != null && proc.crashDialog != null) {
1164                        Slog.e(TAG, "App already has crash dialog: " + proc);
1165                        if (res != null) {
1166                            res.set(0);
1167                        }
1168                        return;
1169                    }
1170                    if (!showBackground && UserHandle.getAppId(proc.uid)
1171                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1172                            && proc.pid != MY_PID) {
1173                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1174                        if (res != null) {
1175                            res.set(0);
1176                        }
1177                        return;
1178                    }
1179                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1180                        Dialog d = new AppErrorDialog(mContext,
1181                                ActivityManagerService.this, res, proc);
1182                        d.show();
1183                        proc.crashDialog = d;
1184                    } else {
1185                        // The device is asleep, so just pretend that the user
1186                        // saw a crash dialog and hit "force quit".
1187                        if (res != null) {
1188                            res.set(0);
1189                        }
1190                    }
1191                }
1192
1193                ensureBootCompleted();
1194            } break;
1195            case SHOW_NOT_RESPONDING_MSG: {
1196                synchronized (ActivityManagerService.this) {
1197                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1198                    ProcessRecord proc = (ProcessRecord)data.get("app");
1199                    if (proc != null && proc.anrDialog != null) {
1200                        Slog.e(TAG, "App already has anr dialog: " + proc);
1201                        return;
1202                    }
1203
1204                    Intent intent = new Intent("android.intent.action.ANR");
1205                    if (!mProcessesReady) {
1206                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1207                                | Intent.FLAG_RECEIVER_FOREGROUND);
1208                    }
1209                    broadcastIntentLocked(null, null, intent,
1210                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1211                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1212
1213                    if (mShowDialogs) {
1214                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1215                                mContext, proc, (ActivityRecord)data.get("activity"),
1216                                msg.arg1 != 0);
1217                        d.show();
1218                        proc.anrDialog = d;
1219                    } else {
1220                        // Just kill the app if there is no dialog to be shown.
1221                        killAppAtUsersRequest(proc, null);
1222                    }
1223                }
1224
1225                ensureBootCompleted();
1226            } break;
1227            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1228                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1229                synchronized (ActivityManagerService.this) {
1230                    ProcessRecord proc = (ProcessRecord) data.get("app");
1231                    if (proc == null) {
1232                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1233                        break;
1234                    }
1235                    if (proc.crashDialog != null) {
1236                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1237                        return;
1238                    }
1239                    AppErrorResult res = (AppErrorResult) data.get("result");
1240                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1241                        Dialog d = new StrictModeViolationDialog(mContext,
1242                                ActivityManagerService.this, res, proc);
1243                        d.show();
1244                        proc.crashDialog = d;
1245                    } else {
1246                        // The device is asleep, so just pretend that the user
1247                        // saw a crash dialog and hit "force quit".
1248                        res.set(0);
1249                    }
1250                }
1251                ensureBootCompleted();
1252            } break;
1253            case SHOW_FACTORY_ERROR_MSG: {
1254                Dialog d = new FactoryErrorDialog(
1255                    mContext, msg.getData().getCharSequence("msg"));
1256                d.show();
1257                ensureBootCompleted();
1258            } break;
1259            case UPDATE_CONFIGURATION_MSG: {
1260                final ContentResolver resolver = mContext.getContentResolver();
1261                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1262            } break;
1263            case GC_BACKGROUND_PROCESSES_MSG: {
1264                synchronized (ActivityManagerService.this) {
1265                    performAppGcsIfAppropriateLocked();
1266                }
1267            } break;
1268            case WAIT_FOR_DEBUGGER_MSG: {
1269                synchronized (ActivityManagerService.this) {
1270                    ProcessRecord app = (ProcessRecord)msg.obj;
1271                    if (msg.arg1 != 0) {
1272                        if (!app.waitedForDebugger) {
1273                            Dialog d = new AppWaitingForDebuggerDialog(
1274                                    ActivityManagerService.this,
1275                                    mContext, app);
1276                            app.waitDialog = d;
1277                            app.waitedForDebugger = true;
1278                            d.show();
1279                        }
1280                    } else {
1281                        if (app.waitDialog != null) {
1282                            app.waitDialog.dismiss();
1283                            app.waitDialog = null;
1284                        }
1285                    }
1286                }
1287            } break;
1288            case SERVICE_TIMEOUT_MSG: {
1289                if (mDidDexOpt) {
1290                    mDidDexOpt = false;
1291                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1292                    nmsg.obj = msg.obj;
1293                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1294                    return;
1295                }
1296                mServices.serviceTimeout((ProcessRecord)msg.obj);
1297            } break;
1298            case UPDATE_TIME_ZONE: {
1299                synchronized (ActivityManagerService.this) {
1300                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1301                        ProcessRecord r = mLruProcesses.get(i);
1302                        if (r.thread != null) {
1303                            try {
1304                                r.thread.updateTimeZone();
1305                            } catch (RemoteException ex) {
1306                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1307                            }
1308                        }
1309                    }
1310                }
1311            } break;
1312            case CLEAR_DNS_CACHE_MSG: {
1313                synchronized (ActivityManagerService.this) {
1314                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1315                        ProcessRecord r = mLruProcesses.get(i);
1316                        if (r.thread != null) {
1317                            try {
1318                                r.thread.clearDnsCache();
1319                            } catch (RemoteException ex) {
1320                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1321                            }
1322                        }
1323                    }
1324                }
1325            } break;
1326            case UPDATE_HTTP_PROXY_MSG: {
1327                ProxyInfo proxy = (ProxyInfo)msg.obj;
1328                String host = "";
1329                String port = "";
1330                String exclList = "";
1331                Uri pacFileUrl = Uri.EMPTY;
1332                if (proxy != null) {
1333                    host = proxy.getHost();
1334                    port = Integer.toString(proxy.getPort());
1335                    exclList = proxy.getExclusionListAsString();
1336                    pacFileUrl = proxy.getPacFileUrl();
1337                }
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.setHttpProxy(host, port, exclList, pacFileUrl);
1344                            } catch (RemoteException ex) {
1345                                Slog.w(TAG, "Failed to update http proxy for: " +
1346                                        r.info.processName);
1347                            }
1348                        }
1349                    }
1350                }
1351            } break;
1352            case SHOW_UID_ERROR_MSG: {
1353                String title = "System UIDs Inconsistent";
1354                String text = "UIDs on the system are inconsistent, you need to wipe your"
1355                        + " data partition or your device will be unstable.";
1356                Log.e(TAG, title + ": " + text);
1357                if (mShowDialogs) {
1358                    // XXX This is a temporary dialog, no need to localize.
1359                    AlertDialog d = new BaseErrorDialog(mContext);
1360                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1361                    d.setCancelable(false);
1362                    d.setTitle(title);
1363                    d.setMessage(text);
1364                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1365                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1366                    mUidAlert = d;
1367                    d.show();
1368                }
1369            } break;
1370            case IM_FEELING_LUCKY_MSG: {
1371                if (mUidAlert != null) {
1372                    mUidAlert.dismiss();
1373                    mUidAlert = null;
1374                }
1375            } break;
1376            case PROC_START_TIMEOUT_MSG: {
1377                if (mDidDexOpt) {
1378                    mDidDexOpt = false;
1379                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1380                    nmsg.obj = msg.obj;
1381                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1382                    return;
1383                }
1384                ProcessRecord app = (ProcessRecord)msg.obj;
1385                synchronized (ActivityManagerService.this) {
1386                    processStartTimedOutLocked(app);
1387                }
1388            } break;
1389            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1390                synchronized (ActivityManagerService.this) {
1391                    doPendingActivityLaunchesLocked(true);
1392                }
1393            } break;
1394            case KILL_APPLICATION_MSG: {
1395                synchronized (ActivityManagerService.this) {
1396                    int appid = msg.arg1;
1397                    boolean restart = (msg.arg2 == 1);
1398                    Bundle bundle = (Bundle)msg.obj;
1399                    String pkg = bundle.getString("pkg");
1400                    String reason = bundle.getString("reason");
1401                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1402                            false, UserHandle.USER_ALL, reason);
1403                }
1404            } break;
1405            case FINALIZE_PENDING_INTENT_MSG: {
1406                ((PendingIntentRecord)msg.obj).completeFinalize();
1407            } break;
1408            case POST_HEAVY_NOTIFICATION_MSG: {
1409                INotificationManager inm = NotificationManager.getService();
1410                if (inm == null) {
1411                    return;
1412                }
1413
1414                ActivityRecord root = (ActivityRecord)msg.obj;
1415                ProcessRecord process = root.app;
1416                if (process == null) {
1417                    return;
1418                }
1419
1420                try {
1421                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1422                    String text = mContext.getString(R.string.heavy_weight_notification,
1423                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1424                    Notification notification = new Notification();
1425                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1426                    notification.when = 0;
1427                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1428                    notification.tickerText = text;
1429                    notification.defaults = 0; // please be quiet
1430                    notification.sound = null;
1431                    notification.vibrate = null;
1432                    notification.setLatestEventInfo(context, text,
1433                            mContext.getText(R.string.heavy_weight_notification_detail),
1434                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1435                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1436                                    new UserHandle(root.userId)));
1437
1438                    try {
1439                        int[] outId = new int[1];
1440                        inm.enqueueNotificationWithTag("android", "android", null,
1441                                R.string.heavy_weight_notification,
1442                                notification, outId, root.userId);
1443                    } catch (RuntimeException e) {
1444                        Slog.w(ActivityManagerService.TAG,
1445                                "Error showing notification for heavy-weight app", e);
1446                    } catch (RemoteException e) {
1447                    }
1448                } catch (NameNotFoundException e) {
1449                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1450                }
1451            } break;
1452            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1453                INotificationManager inm = NotificationManager.getService();
1454                if (inm == null) {
1455                    return;
1456                }
1457                try {
1458                    inm.cancelNotificationWithTag("android", null,
1459                            R.string.heavy_weight_notification,  msg.arg1);
1460                } catch (RuntimeException e) {
1461                    Slog.w(ActivityManagerService.TAG,
1462                            "Error canceling notification for service", e);
1463                } catch (RemoteException e) {
1464                }
1465            } break;
1466            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1467                synchronized (ActivityManagerService.this) {
1468                    checkExcessivePowerUsageLocked(true);
1469                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1470                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1471                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1472                }
1473            } break;
1474            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1475                synchronized (ActivityManagerService.this) {
1476                    ActivityRecord ar = (ActivityRecord)msg.obj;
1477                    if (mCompatModeDialog != null) {
1478                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1479                                ar.info.applicationInfo.packageName)) {
1480                            return;
1481                        }
1482                        mCompatModeDialog.dismiss();
1483                        mCompatModeDialog = null;
1484                    }
1485                    if (ar != null && false) {
1486                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1487                                ar.packageName)) {
1488                            int mode = mCompatModePackages.computeCompatModeLocked(
1489                                    ar.info.applicationInfo);
1490                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1491                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1492                                mCompatModeDialog = new CompatModeDialog(
1493                                        ActivityManagerService.this, mContext,
1494                                        ar.info.applicationInfo);
1495                                mCompatModeDialog.show();
1496                            }
1497                        }
1498                    }
1499                }
1500                break;
1501            }
1502            case DISPATCH_PROCESSES_CHANGED: {
1503                dispatchProcessesChanged();
1504                break;
1505            }
1506            case DISPATCH_PROCESS_DIED: {
1507                final int pid = msg.arg1;
1508                final int uid = msg.arg2;
1509                dispatchProcessDied(pid, uid);
1510                break;
1511            }
1512            case REPORT_MEM_USAGE_MSG: {
1513                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1514                Thread thread = new Thread() {
1515                    @Override public void run() {
1516                        final SparseArray<ProcessMemInfo> infoMap
1517                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1518                        for (int i=0, N=memInfos.size(); i<N; i++) {
1519                            ProcessMemInfo mi = memInfos.get(i);
1520                            infoMap.put(mi.pid, mi);
1521                        }
1522                        updateCpuStatsNow();
1523                        synchronized (mProcessCpuThread) {
1524                            final int N = mProcessCpuTracker.countStats();
1525                            for (int i=0; i<N; i++) {
1526                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1527                                if (st.vsize > 0) {
1528                                    long pss = Debug.getPss(st.pid, null);
1529                                    if (pss > 0) {
1530                                        if (infoMap.indexOfKey(st.pid) < 0) {
1531                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1532                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1533                                            mi.pss = pss;
1534                                            memInfos.add(mi);
1535                                        }
1536                                    }
1537                                }
1538                            }
1539                        }
1540
1541                        long totalPss = 0;
1542                        for (int i=0, N=memInfos.size(); i<N; i++) {
1543                            ProcessMemInfo mi = memInfos.get(i);
1544                            if (mi.pss == 0) {
1545                                mi.pss = Debug.getPss(mi.pid, null);
1546                            }
1547                            totalPss += mi.pss;
1548                        }
1549                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1550                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1551                                if (lhs.oomAdj != rhs.oomAdj) {
1552                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1553                                }
1554                                if (lhs.pss != rhs.pss) {
1555                                    return lhs.pss < rhs.pss ? 1 : -1;
1556                                }
1557                                return 0;
1558                            }
1559                        });
1560
1561                        StringBuilder tag = new StringBuilder(128);
1562                        StringBuilder stack = new StringBuilder(128);
1563                        tag.append("Low on memory -- ");
1564                        appendMemBucket(tag, totalPss, "total", false);
1565                        appendMemBucket(stack, totalPss, "total", true);
1566
1567                        StringBuilder logBuilder = new StringBuilder(1024);
1568                        logBuilder.append("Low on memory:\n");
1569
1570                        boolean firstLine = true;
1571                        int lastOomAdj = Integer.MIN_VALUE;
1572                        for (int i=0, N=memInfos.size(); i<N; i++) {
1573                            ProcessMemInfo mi = memInfos.get(i);
1574
1575                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1576                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1577                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1578                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1579                                if (lastOomAdj != mi.oomAdj) {
1580                                    lastOomAdj = mi.oomAdj;
1581                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1582                                        tag.append(" / ");
1583                                    }
1584                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1585                                        if (firstLine) {
1586                                            stack.append(":");
1587                                            firstLine = false;
1588                                        }
1589                                        stack.append("\n\t at ");
1590                                    } else {
1591                                        stack.append("$");
1592                                    }
1593                                } else {
1594                                    tag.append(" ");
1595                                    stack.append("$");
1596                                }
1597                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1598                                    appendMemBucket(tag, mi.pss, mi.name, false);
1599                                }
1600                                appendMemBucket(stack, mi.pss, mi.name, true);
1601                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1602                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1603                                    stack.append("(");
1604                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1605                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1606                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1607                                            stack.append(":");
1608                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1609                                        }
1610                                    }
1611                                    stack.append(")");
1612                                }
1613                            }
1614
1615                            logBuilder.append("  ");
1616                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1617                            logBuilder.append(' ');
1618                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1619                            logBuilder.append(' ');
1620                            ProcessList.appendRamKb(logBuilder, mi.pss);
1621                            logBuilder.append(" kB: ");
1622                            logBuilder.append(mi.name);
1623                            logBuilder.append(" (");
1624                            logBuilder.append(mi.pid);
1625                            logBuilder.append(") ");
1626                            logBuilder.append(mi.adjType);
1627                            logBuilder.append('\n');
1628                            if (mi.adjReason != null) {
1629                                logBuilder.append("                      ");
1630                                logBuilder.append(mi.adjReason);
1631                                logBuilder.append('\n');
1632                            }
1633                        }
1634
1635                        logBuilder.append("           ");
1636                        ProcessList.appendRamKb(logBuilder, totalPss);
1637                        logBuilder.append(" kB: TOTAL\n");
1638
1639                        long[] infos = new long[Debug.MEMINFO_COUNT];
1640                        Debug.getMemInfo(infos);
1641                        logBuilder.append("  MemInfo: ");
1642                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1643                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1644                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1645                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1646                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1647                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1648                            logBuilder.append("  ZRAM: ");
1649                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1650                            logBuilder.append(" kB RAM, ");
1651                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1652                            logBuilder.append(" kB swap total, ");
1653                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1654                            logBuilder.append(" kB swap free\n");
1655                        }
1656                        Slog.i(TAG, logBuilder.toString());
1657
1658                        StringBuilder dropBuilder = new StringBuilder(1024);
1659                        /*
1660                        StringWriter oomSw = new StringWriter();
1661                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1662                        StringWriter catSw = new StringWriter();
1663                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1664                        String[] emptyArgs = new String[] { };
1665                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1666                        oomPw.flush();
1667                        String oomString = oomSw.toString();
1668                        */
1669                        dropBuilder.append(stack);
1670                        dropBuilder.append('\n');
1671                        dropBuilder.append('\n');
1672                        dropBuilder.append(logBuilder);
1673                        dropBuilder.append('\n');
1674                        /*
1675                        dropBuilder.append(oomString);
1676                        dropBuilder.append('\n');
1677                        */
1678                        StringWriter catSw = new StringWriter();
1679                        synchronized (ActivityManagerService.this) {
1680                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1681                            String[] emptyArgs = new String[] { };
1682                            catPw.println();
1683                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1684                            catPw.println();
1685                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1686                                    false, false, null);
1687                            catPw.println();
1688                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1689                            catPw.flush();
1690                        }
1691                        dropBuilder.append(catSw.toString());
1692                        addErrorToDropBox("lowmem", null, "system_server", null,
1693                                null, tag.toString(), dropBuilder.toString(), null, null);
1694                        //Slog.i(TAG, "Sent to dropbox:");
1695                        //Slog.i(TAG, dropBuilder.toString());
1696                        synchronized (ActivityManagerService.this) {
1697                            long now = SystemClock.uptimeMillis();
1698                            if (mLastMemUsageReportTime < now) {
1699                                mLastMemUsageReportTime = now;
1700                            }
1701                        }
1702                    }
1703                };
1704                thread.start();
1705                break;
1706            }
1707            case REPORT_USER_SWITCH_MSG: {
1708                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1709                break;
1710            }
1711            case CONTINUE_USER_SWITCH_MSG: {
1712                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1713                break;
1714            }
1715            case USER_SWITCH_TIMEOUT_MSG: {
1716                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1717                break;
1718            }
1719            case IMMERSIVE_MODE_LOCK_MSG: {
1720                final boolean nextState = (msg.arg1 != 0);
1721                if (mUpdateLock.isHeld() != nextState) {
1722                    if (DEBUG_IMMERSIVE) {
1723                        final ActivityRecord r = (ActivityRecord) msg.obj;
1724                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1725                    }
1726                    if (nextState) {
1727                        mUpdateLock.acquire();
1728                    } else {
1729                        mUpdateLock.release();
1730                    }
1731                }
1732                break;
1733            }
1734            case PERSIST_URI_GRANTS_MSG: {
1735                writeGrantedUriPermissions();
1736                break;
1737            }
1738            case REQUEST_ALL_PSS_MSG: {
1739                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1740                break;
1741            }
1742            case START_PROFILES_MSG: {
1743                synchronized (ActivityManagerService.this) {
1744                    startProfilesLocked();
1745                }
1746                break;
1747            }
1748            case UPDATE_TIME: {
1749                synchronized (ActivityManagerService.this) {
1750                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1751                        ProcessRecord r = mLruProcesses.get(i);
1752                        if (r.thread != null) {
1753                            try {
1754                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1755                            } catch (RemoteException ex) {
1756                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1757                            }
1758                        }
1759                    }
1760                }
1761                break;
1762            }
1763            case SYSTEM_USER_START_MSG: {
1764                mSystemServiceManager.startUser(msg.arg1);
1765                break;
1766            }
1767            case SYSTEM_USER_CURRENT_MSG: {
1768                mSystemServiceManager.switchUser(msg.arg1);
1769                break;
1770            }
1771            }
1772        }
1773    };
1774
1775    static final int COLLECT_PSS_BG_MSG = 1;
1776
1777    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1778        @Override
1779        public void handleMessage(Message msg) {
1780            switch (msg.what) {
1781            case COLLECT_PSS_BG_MSG: {
1782                int i=0, num=0;
1783                long start = SystemClock.uptimeMillis();
1784                long[] tmp = new long[1];
1785                do {
1786                    ProcessRecord proc;
1787                    int procState;
1788                    int pid;
1789                    synchronized (ActivityManagerService.this) {
1790                        if (i >= mPendingPssProcesses.size()) {
1791                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1792                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1793                            mPendingPssProcesses.clear();
1794                            return;
1795                        }
1796                        proc = mPendingPssProcesses.get(i);
1797                        procState = proc.pssProcState;
1798                        if (proc.thread != null && procState == proc.setProcState) {
1799                            pid = proc.pid;
1800                        } else {
1801                            proc = null;
1802                            pid = 0;
1803                        }
1804                        i++;
1805                    }
1806                    if (proc != null) {
1807                        long pss = Debug.getPss(pid, tmp);
1808                        synchronized (ActivityManagerService.this) {
1809                            if (proc.thread != null && proc.setProcState == procState
1810                                    && proc.pid == pid) {
1811                                num++;
1812                                proc.lastPssTime = SystemClock.uptimeMillis();
1813                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1814                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1815                                        + ": " + pss + " lastPss=" + proc.lastPss
1816                                        + " state=" + ProcessList.makeProcStateString(procState));
1817                                if (proc.initialIdlePss == 0) {
1818                                    proc.initialIdlePss = pss;
1819                                }
1820                                proc.lastPss = pss;
1821                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1822                                    proc.lastCachedPss = pss;
1823                                }
1824                            }
1825                        }
1826                    }
1827                } while (true);
1828            }
1829            }
1830        }
1831    };
1832
1833    /**
1834     * Monitor for package changes and update our internal state.
1835     */
1836    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1837        @Override
1838        public void onPackageRemoved(String packageName, int uid) {
1839            // Remove all tasks with activities in the specified package from the list of recent tasks
1840            synchronized (ActivityManagerService.this) {
1841                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1842                    TaskRecord tr = mRecentTasks.get(i);
1843                    ComponentName cn = tr.intent.getComponent();
1844                    if (cn != null && cn.getPackageName().equals(packageName)) {
1845                        // If the package name matches, remove the task and kill the process
1846                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1847                    }
1848                }
1849            }
1850        }
1851
1852        @Override
1853        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1854            onPackageModified(packageName);
1855            return true;
1856        }
1857
1858        @Override
1859        public void onPackageModified(String packageName) {
1860            final PackageManager pm = mContext.getPackageManager();
1861            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1862                    new ArrayList<Pair<Intent, Integer>>();
1863            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1864            // Copy the list of recent tasks so that we don't hold onto the lock on
1865            // ActivityManagerService for long periods while checking if components exist.
1866            synchronized (ActivityManagerService.this) {
1867                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1868                    TaskRecord tr = mRecentTasks.get(i);
1869                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1870                }
1871            }
1872            // Check the recent tasks and filter out all tasks with components that no longer exist.
1873            Intent tmpI = new Intent();
1874            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1875                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1876                ComponentName cn = p.first.getComponent();
1877                if (cn != null && cn.getPackageName().equals(packageName)) {
1878                    try {
1879                        // Add the task to the list to remove if the component no longer exists
1880                        tmpI.setComponent(cn);
1881                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1882                            tasksToRemove.add(p.second);
1883                        }
1884                    } catch (Exception e) {}
1885                }
1886            }
1887            // Prune all the tasks with removed components from the list of recent tasks
1888            synchronized (ActivityManagerService.this) {
1889                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1890                    // Remove the task but don't kill the process (since other components in that
1891                    // package may still be running and in the background)
1892                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1893                }
1894            }
1895        }
1896
1897        @Override
1898        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1899            // Force stop the specified packages
1900            if (packages != null) {
1901                for (String pkg : packages) {
1902                    synchronized (ActivityManagerService.this) {
1903                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
1904                                "finished booting")) {
1905                            return true;
1906                        }
1907                    }
1908                }
1909            }
1910            return false;
1911        }
1912    };
1913
1914    public void setSystemProcess() {
1915        try {
1916            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1917            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1918            ServiceManager.addService("meminfo", new MemBinder(this));
1919            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1920            ServiceManager.addService("dbinfo", new DbBinder(this));
1921            if (MONITOR_CPU_USAGE) {
1922                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1923            }
1924            ServiceManager.addService("permission", new PermissionController(this));
1925
1926            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1927                    "android", STOCK_PM_FLAGS);
1928            mSystemThread.installSystemApplicationInfo(info);
1929
1930            synchronized (this) {
1931                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
1932                app.persistent = true;
1933                app.pid = MY_PID;
1934                app.maxAdj = ProcessList.SYSTEM_ADJ;
1935                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1936                mProcessNames.put(app.processName, app.uid, app);
1937                synchronized (mPidsSelfLocked) {
1938                    mPidsSelfLocked.put(app.pid, app);
1939                }
1940                updateLruProcessLocked(app, false, null);
1941                updateOomAdjLocked();
1942            }
1943        } catch (PackageManager.NameNotFoundException e) {
1944            throw new RuntimeException(
1945                    "Unable to find android system package", e);
1946        }
1947    }
1948
1949    public void setWindowManager(WindowManagerService wm) {
1950        mWindowManager = wm;
1951        mStackSupervisor.setWindowManager(wm);
1952    }
1953
1954    public void startObservingNativeCrashes() {
1955        final NativeCrashListener ncl = new NativeCrashListener(this);
1956        ncl.start();
1957    }
1958
1959    public IAppOpsService getAppOpsService() {
1960        return mAppOpsService;
1961    }
1962
1963    static class MemBinder extends Binder {
1964        ActivityManagerService mActivityManagerService;
1965        MemBinder(ActivityManagerService activityManagerService) {
1966            mActivityManagerService = activityManagerService;
1967        }
1968
1969        @Override
1970        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1971            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1972                    != PackageManager.PERMISSION_GRANTED) {
1973                pw.println("Permission Denial: can't dump meminfo from from pid="
1974                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1975                        + " without permission " + android.Manifest.permission.DUMP);
1976                return;
1977            }
1978
1979            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1980        }
1981    }
1982
1983    static class GraphicsBinder extends Binder {
1984        ActivityManagerService mActivityManagerService;
1985        GraphicsBinder(ActivityManagerService activityManagerService) {
1986            mActivityManagerService = activityManagerService;
1987        }
1988
1989        @Override
1990        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1991            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1992                    != PackageManager.PERMISSION_GRANTED) {
1993                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1994                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1995                        + " without permission " + android.Manifest.permission.DUMP);
1996                return;
1997            }
1998
1999            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2000        }
2001    }
2002
2003    static class DbBinder extends Binder {
2004        ActivityManagerService mActivityManagerService;
2005        DbBinder(ActivityManagerService activityManagerService) {
2006            mActivityManagerService = activityManagerService;
2007        }
2008
2009        @Override
2010        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2011            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2012                    != PackageManager.PERMISSION_GRANTED) {
2013                pw.println("Permission Denial: can't dump dbinfo from from pid="
2014                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2015                        + " without permission " + android.Manifest.permission.DUMP);
2016                return;
2017            }
2018
2019            mActivityManagerService.dumpDbInfo(fd, pw, args);
2020        }
2021    }
2022
2023    static class CpuBinder extends Binder {
2024        ActivityManagerService mActivityManagerService;
2025        CpuBinder(ActivityManagerService activityManagerService) {
2026            mActivityManagerService = activityManagerService;
2027        }
2028
2029        @Override
2030        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2031            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2032                    != PackageManager.PERMISSION_GRANTED) {
2033                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2034                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2035                        + " without permission " + android.Manifest.permission.DUMP);
2036                return;
2037            }
2038
2039            synchronized (mActivityManagerService.mProcessCpuThread) {
2040                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2041                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2042                        SystemClock.uptimeMillis()));
2043            }
2044        }
2045    }
2046
2047    public static final class Lifecycle extends SystemService {
2048        private final ActivityManagerService mService;
2049
2050        public Lifecycle(Context context) {
2051            super(context);
2052            mService = new ActivityManagerService(context);
2053        }
2054
2055        @Override
2056        public void onStart() {
2057            mService.start();
2058        }
2059
2060        public ActivityManagerService getService() {
2061            return mService;
2062        }
2063    }
2064
2065    // Note: This method is invoked on the main thread but may need to attach various
2066    // handlers to other threads.  So take care to be explicit about the looper.
2067    public ActivityManagerService(Context systemContext) {
2068        mContext = systemContext;
2069        mFactoryTest = FactoryTest.getMode();
2070        mSystemThread = ActivityThread.currentActivityThread();
2071
2072        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2073
2074        mHandlerThread = new ServiceThread(TAG,
2075                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2076        mHandlerThread.start();
2077        mHandler = new MainHandler(mHandlerThread.getLooper());
2078
2079        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2080                "foreground", BROADCAST_FG_TIMEOUT, false);
2081        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2082                "background", BROADCAST_BG_TIMEOUT, true);
2083        mBroadcastQueues[0] = mFgBroadcastQueue;
2084        mBroadcastQueues[1] = mBgBroadcastQueue;
2085
2086        mServices = new ActiveServices(this);
2087        mProviderMap = new ProviderMap(this);
2088
2089        // TODO: Move creation of battery stats service outside of activity manager service.
2090        File dataDir = Environment.getDataDirectory();
2091        File systemDir = new File(dataDir, "system");
2092        systemDir.mkdirs();
2093        mBatteryStatsService = new BatteryStatsService(new File(
2094                systemDir, "batterystats.bin").toString(), mHandler);
2095        mBatteryStatsService.getActiveStatistics().readLocked();
2096        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2097        mOnBattery = DEBUG_POWER ? true
2098                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2099        mBatteryStatsService.getActiveStatistics().setCallback(this);
2100
2101        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2102
2103        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
2104        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2105
2106        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2107
2108        // User 0 is the first and only user that runs at boot.
2109        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2110        mUserLru.add(Integer.valueOf(0));
2111        updateStartedUserArrayLocked();
2112
2113        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2114            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2115
2116        mConfiguration.setToDefaults();
2117        mConfiguration.setLocale(Locale.getDefault());
2118
2119        mConfigurationSeq = mConfiguration.seq = 1;
2120        mProcessCpuTracker.init();
2121
2122        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2123        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2124        mStackSupervisor = new ActivityStackSupervisor(this);
2125
2126        mProcessCpuThread = new Thread("CpuTracker") {
2127            @Override
2128            public void run() {
2129                while (true) {
2130                    try {
2131                        try {
2132                            synchronized(this) {
2133                                final long now = SystemClock.uptimeMillis();
2134                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2135                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2136                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2137                                //        + ", write delay=" + nextWriteDelay);
2138                                if (nextWriteDelay < nextCpuDelay) {
2139                                    nextCpuDelay = nextWriteDelay;
2140                                }
2141                                if (nextCpuDelay > 0) {
2142                                    mProcessCpuMutexFree.set(true);
2143                                    this.wait(nextCpuDelay);
2144                                }
2145                            }
2146                        } catch (InterruptedException e) {
2147                        }
2148                        updateCpuStatsNow();
2149                    } catch (Exception e) {
2150                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2151                    }
2152                }
2153            }
2154        };
2155
2156        Watchdog.getInstance().addMonitor(this);
2157        Watchdog.getInstance().addThread(mHandler);
2158    }
2159
2160    public void setSystemServiceManager(SystemServiceManager mgr) {
2161        mSystemServiceManager = mgr;
2162    }
2163
2164    private void start() {
2165        mProcessCpuThread.start();
2166
2167        mBatteryStatsService.publish(mContext);
2168        mUsageStatsService.publish(mContext);
2169        mAppOpsService.publish(mContext);
2170
2171        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2172    }
2173
2174    @Override
2175    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2176            throws RemoteException {
2177        if (code == SYSPROPS_TRANSACTION) {
2178            // We need to tell all apps about the system property change.
2179            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2180            synchronized(this) {
2181                final int NP = mProcessNames.getMap().size();
2182                for (int ip=0; ip<NP; ip++) {
2183                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2184                    final int NA = apps.size();
2185                    for (int ia=0; ia<NA; ia++) {
2186                        ProcessRecord app = apps.valueAt(ia);
2187                        if (app.thread != null) {
2188                            procs.add(app.thread.asBinder());
2189                        }
2190                    }
2191                }
2192            }
2193
2194            int N = procs.size();
2195            for (int i=0; i<N; i++) {
2196                Parcel data2 = Parcel.obtain();
2197                try {
2198                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2199                } catch (RemoteException e) {
2200                }
2201                data2.recycle();
2202            }
2203        }
2204        try {
2205            return super.onTransact(code, data, reply, flags);
2206        } catch (RuntimeException e) {
2207            // The activity manager only throws security exceptions, so let's
2208            // log all others.
2209            if (!(e instanceof SecurityException)) {
2210                Slog.wtf(TAG, "Activity Manager Crash", e);
2211            }
2212            throw e;
2213        }
2214    }
2215
2216    void updateCpuStats() {
2217        final long now = SystemClock.uptimeMillis();
2218        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2219            return;
2220        }
2221        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2222            synchronized (mProcessCpuThread) {
2223                mProcessCpuThread.notify();
2224            }
2225        }
2226    }
2227
2228    void updateCpuStatsNow() {
2229        synchronized (mProcessCpuThread) {
2230            mProcessCpuMutexFree.set(false);
2231            final long now = SystemClock.uptimeMillis();
2232            boolean haveNewCpuStats = false;
2233
2234            if (MONITOR_CPU_USAGE &&
2235                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2236                mLastCpuTime.set(now);
2237                haveNewCpuStats = true;
2238                mProcessCpuTracker.update();
2239                //Slog.i(TAG, mProcessCpu.printCurrentState());
2240                //Slog.i(TAG, "Total CPU usage: "
2241                //        + mProcessCpu.getTotalCpuPercent() + "%");
2242
2243                // Slog the cpu usage if the property is set.
2244                if ("true".equals(SystemProperties.get("events.cpu"))) {
2245                    int user = mProcessCpuTracker.getLastUserTime();
2246                    int system = mProcessCpuTracker.getLastSystemTime();
2247                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2248                    int irq = mProcessCpuTracker.getLastIrqTime();
2249                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2250                    int idle = mProcessCpuTracker.getLastIdleTime();
2251
2252                    int total = user + system + iowait + irq + softIrq + idle;
2253                    if (total == 0) total = 1;
2254
2255                    EventLog.writeEvent(EventLogTags.CPU,
2256                            ((user+system+iowait+irq+softIrq) * 100) / total,
2257                            (user * 100) / total,
2258                            (system * 100) / total,
2259                            (iowait * 100) / total,
2260                            (irq * 100) / total,
2261                            (softIrq * 100) / total);
2262                }
2263            }
2264
2265            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2266            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2267            synchronized(bstats) {
2268                synchronized(mPidsSelfLocked) {
2269                    if (haveNewCpuStats) {
2270                        if (mOnBattery) {
2271                            int perc = bstats.startAddingCpuLocked();
2272                            int totalUTime = 0;
2273                            int totalSTime = 0;
2274                            final int N = mProcessCpuTracker.countStats();
2275                            for (int i=0; i<N; i++) {
2276                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2277                                if (!st.working) {
2278                                    continue;
2279                                }
2280                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2281                                int otherUTime = (st.rel_utime*perc)/100;
2282                                int otherSTime = (st.rel_stime*perc)/100;
2283                                totalUTime += otherUTime;
2284                                totalSTime += otherSTime;
2285                                if (pr != null) {
2286                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2287                                    if (ps == null || !ps.isActive()) {
2288                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2289                                                pr.info.uid, pr.processName);
2290                                    }
2291                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2292                                            st.rel_stime-otherSTime);
2293                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2294                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2295                                } else {
2296                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2297                                    if (ps == null || !ps.isActive()) {
2298                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2299                                                bstats.mapUid(st.uid), st.name);
2300                                    }
2301                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2302                                            st.rel_stime-otherSTime);
2303                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2304                                }
2305                            }
2306                            bstats.finishAddingCpuLocked(perc, totalUTime,
2307                                    totalSTime, cpuSpeedTimes);
2308                        }
2309                    }
2310                }
2311
2312                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2313                    mLastWriteTime = now;
2314                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2315                }
2316            }
2317        }
2318    }
2319
2320    @Override
2321    public void batteryNeedsCpuUpdate() {
2322        updateCpuStatsNow();
2323    }
2324
2325    @Override
2326    public void batteryPowerChanged(boolean onBattery) {
2327        // When plugging in, update the CPU stats first before changing
2328        // the plug state.
2329        updateCpuStatsNow();
2330        synchronized (this) {
2331            synchronized(mPidsSelfLocked) {
2332                mOnBattery = DEBUG_POWER ? true : onBattery;
2333            }
2334        }
2335    }
2336
2337    /**
2338     * Initialize the application bind args. These are passed to each
2339     * process when the bindApplication() IPC is sent to the process. They're
2340     * lazily setup to make sure the services are running when they're asked for.
2341     */
2342    private HashMap<String, IBinder> getCommonServicesLocked() {
2343        if (mAppBindArgs == null) {
2344            mAppBindArgs = new HashMap<String, IBinder>();
2345
2346            // Setup the application init args
2347            mAppBindArgs.put("package", ServiceManager.getService("package"));
2348            mAppBindArgs.put("window", ServiceManager.getService("window"));
2349            mAppBindArgs.put(Context.ALARM_SERVICE,
2350                    ServiceManager.getService(Context.ALARM_SERVICE));
2351        }
2352        return mAppBindArgs;
2353    }
2354
2355    final void setFocusedActivityLocked(ActivityRecord r) {
2356        if (mFocusedActivity != r) {
2357            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2358            mFocusedActivity = r;
2359            if (r.task != null && r.task.voiceInteractor != null) {
2360                startRunningVoiceLocked();
2361            } else {
2362                finishRunningVoiceLocked();
2363            }
2364            mStackSupervisor.setFocusedStack(r);
2365            if (r != null) {
2366                mWindowManager.setFocusedApp(r.appToken, true);
2367            }
2368            applyUpdateLockStateLocked(r);
2369        }
2370    }
2371
2372    final void clearFocusedActivity(ActivityRecord r) {
2373        if (mFocusedActivity == r) {
2374            mFocusedActivity = null;
2375        }
2376    }
2377
2378    @Override
2379    public void setFocusedStack(int stackId) {
2380        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2381        synchronized (ActivityManagerService.this) {
2382            ActivityStack stack = mStackSupervisor.getStack(stackId);
2383            if (stack != null) {
2384                ActivityRecord r = stack.topRunningActivityLocked(null);
2385                if (r != null) {
2386                    setFocusedActivityLocked(r);
2387                }
2388            }
2389        }
2390    }
2391
2392    @Override
2393    public void notifyActivityDrawn(IBinder token) {
2394        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2395        synchronized (this) {
2396            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2397            if (r != null) {
2398                r.task.stack.notifyActivityDrawnLocked(r);
2399            }
2400        }
2401    }
2402
2403    final void applyUpdateLockStateLocked(ActivityRecord r) {
2404        // Modifications to the UpdateLock state are done on our handler, outside
2405        // the activity manager's locks.  The new state is determined based on the
2406        // state *now* of the relevant activity record.  The object is passed to
2407        // the handler solely for logging detail, not to be consulted/modified.
2408        final boolean nextState = r != null && r.immersive;
2409        mHandler.sendMessage(
2410                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2411    }
2412
2413    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2414        Message msg = Message.obtain();
2415        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2416        msg.obj = r.task.askedCompatMode ? null : r;
2417        mHandler.sendMessage(msg);
2418    }
2419
2420    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2421            String what, Object obj, ProcessRecord srcApp) {
2422        app.lastActivityTime = now;
2423
2424        if (app.activities.size() > 0) {
2425            // Don't want to touch dependent processes that are hosting activities.
2426            return index;
2427        }
2428
2429        int lrui = mLruProcesses.lastIndexOf(app);
2430        if (lrui < 0) {
2431            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2432                    + what + " " + obj + " from " + srcApp);
2433            return index;
2434        }
2435
2436        if (lrui >= index) {
2437            // Don't want to cause this to move dependent processes *back* in the
2438            // list as if they were less frequently used.
2439            return index;
2440        }
2441
2442        if (lrui >= mLruProcessActivityStart) {
2443            // Don't want to touch dependent processes that are hosting activities.
2444            return index;
2445        }
2446
2447        mLruProcesses.remove(lrui);
2448        if (index > 0) {
2449            index--;
2450        }
2451        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2452                + " in LRU list: " + app);
2453        mLruProcesses.add(index, app);
2454        return index;
2455    }
2456
2457    final void removeLruProcessLocked(ProcessRecord app) {
2458        int lrui = mLruProcesses.lastIndexOf(app);
2459        if (lrui >= 0) {
2460            if (lrui <= mLruProcessActivityStart) {
2461                mLruProcessActivityStart--;
2462            }
2463            if (lrui <= mLruProcessServiceStart) {
2464                mLruProcessServiceStart--;
2465            }
2466            mLruProcesses.remove(lrui);
2467        }
2468    }
2469
2470    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2471            ProcessRecord client) {
2472        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2473                || app.treatLikeActivity;
2474        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2475        if (!activityChange && hasActivity) {
2476            // The process has activities, so we are only allowing activity-based adjustments
2477            // to move it.  It should be kept in the front of the list with other
2478            // processes that have activities, and we don't want those to change their
2479            // order except due to activity operations.
2480            return;
2481        }
2482
2483        mLruSeq++;
2484        final long now = SystemClock.uptimeMillis();
2485        app.lastActivityTime = now;
2486
2487        // First a quick reject: if the app is already at the position we will
2488        // put it, then there is nothing to do.
2489        if (hasActivity) {
2490            final int N = mLruProcesses.size();
2491            if (N > 0 && mLruProcesses.get(N-1) == app) {
2492                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2493                return;
2494            }
2495        } else {
2496            if (mLruProcessServiceStart > 0
2497                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2498                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2499                return;
2500            }
2501        }
2502
2503        int lrui = mLruProcesses.lastIndexOf(app);
2504
2505        if (app.persistent && lrui >= 0) {
2506            // We don't care about the position of persistent processes, as long as
2507            // they are in the list.
2508            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2509            return;
2510        }
2511
2512        /* In progress: compute new position first, so we can avoid doing work
2513           if the process is not actually going to move.  Not yet working.
2514        int addIndex;
2515        int nextIndex;
2516        boolean inActivity = false, inService = false;
2517        if (hasActivity) {
2518            // Process has activities, put it at the very tipsy-top.
2519            addIndex = mLruProcesses.size();
2520            nextIndex = mLruProcessServiceStart;
2521            inActivity = true;
2522        } else if (hasService) {
2523            // Process has services, put it at the top of the service list.
2524            addIndex = mLruProcessActivityStart;
2525            nextIndex = mLruProcessServiceStart;
2526            inActivity = true;
2527            inService = true;
2528        } else  {
2529            // Process not otherwise of interest, it goes to the top of the non-service area.
2530            addIndex = mLruProcessServiceStart;
2531            if (client != null) {
2532                int clientIndex = mLruProcesses.lastIndexOf(client);
2533                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2534                        + app);
2535                if (clientIndex >= 0 && addIndex > clientIndex) {
2536                    addIndex = clientIndex;
2537                }
2538            }
2539            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2540        }
2541
2542        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2543                + mLruProcessActivityStart + "): " + app);
2544        */
2545
2546        if (lrui >= 0) {
2547            if (lrui < mLruProcessActivityStart) {
2548                mLruProcessActivityStart--;
2549            }
2550            if (lrui < mLruProcessServiceStart) {
2551                mLruProcessServiceStart--;
2552            }
2553            /*
2554            if (addIndex > lrui) {
2555                addIndex--;
2556            }
2557            if (nextIndex > lrui) {
2558                nextIndex--;
2559            }
2560            */
2561            mLruProcesses.remove(lrui);
2562        }
2563
2564        /*
2565        mLruProcesses.add(addIndex, app);
2566        if (inActivity) {
2567            mLruProcessActivityStart++;
2568        }
2569        if (inService) {
2570            mLruProcessActivityStart++;
2571        }
2572        */
2573
2574        int nextIndex;
2575        if (hasActivity) {
2576            final int N = mLruProcesses.size();
2577            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2578                // Process doesn't have activities, but has clients with
2579                // activities...  move it up, but one below the top (the top
2580                // should always have a real activity).
2581                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2582                mLruProcesses.add(N-1, app);
2583                // To keep it from spamming the LRU list (by making a bunch of clients),
2584                // we will push down any other entries owned by the app.
2585                final int uid = app.info.uid;
2586                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2587                    ProcessRecord subProc = mLruProcesses.get(i);
2588                    if (subProc.info.uid == uid) {
2589                        // We want to push this one down the list.  If the process after
2590                        // it is for the same uid, however, don't do so, because we don't
2591                        // want them internally to be re-ordered.
2592                        if (mLruProcesses.get(i-1).info.uid != uid) {
2593                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2594                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2595                            ProcessRecord tmp = mLruProcesses.get(i);
2596                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2597                            mLruProcesses.set(i-1, tmp);
2598                            i--;
2599                        }
2600                    } else {
2601                        // A gap, we can stop here.
2602                        break;
2603                    }
2604                }
2605            } else {
2606                // Process has activities, put it at the very tipsy-top.
2607                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2608                mLruProcesses.add(app);
2609            }
2610            nextIndex = mLruProcessServiceStart;
2611        } else if (hasService) {
2612            // Process has services, put it at the top of the service list.
2613            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2614            mLruProcesses.add(mLruProcessActivityStart, app);
2615            nextIndex = mLruProcessServiceStart;
2616            mLruProcessActivityStart++;
2617        } else  {
2618            // Process not otherwise of interest, it goes to the top of the non-service area.
2619            int index = mLruProcessServiceStart;
2620            if (client != null) {
2621                // If there is a client, don't allow the process to be moved up higher
2622                // in the list than that client.
2623                int clientIndex = mLruProcesses.lastIndexOf(client);
2624                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2625                        + " when updating " + app);
2626                if (clientIndex <= lrui) {
2627                    // Don't allow the client index restriction to push it down farther in the
2628                    // list than it already is.
2629                    clientIndex = lrui;
2630                }
2631                if (clientIndex >= 0 && index > clientIndex) {
2632                    index = clientIndex;
2633                }
2634            }
2635            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2636            mLruProcesses.add(index, app);
2637            nextIndex = index-1;
2638            mLruProcessActivityStart++;
2639            mLruProcessServiceStart++;
2640        }
2641
2642        // If the app is currently using a content provider or service,
2643        // bump those processes as well.
2644        for (int j=app.connections.size()-1; j>=0; j--) {
2645            ConnectionRecord cr = app.connections.valueAt(j);
2646            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2647                    && cr.binding.service.app != null
2648                    && cr.binding.service.app.lruSeq != mLruSeq
2649                    && !cr.binding.service.app.persistent) {
2650                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2651                        "service connection", cr, app);
2652            }
2653        }
2654        for (int j=app.conProviders.size()-1; j>=0; j--) {
2655            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2656            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2657                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2658                        "provider reference", cpr, app);
2659            }
2660        }
2661    }
2662
2663    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2664        if (uid == Process.SYSTEM_UID) {
2665            // The system gets to run in any process.  If there are multiple
2666            // processes with the same uid, just pick the first (this
2667            // should never happen).
2668            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2669            if (procs == null) return null;
2670            final int N = procs.size();
2671            for (int i = 0; i < N; i++) {
2672                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2673            }
2674        }
2675        ProcessRecord proc = mProcessNames.get(processName, uid);
2676        if (false && proc != null && !keepIfLarge
2677                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2678                && proc.lastCachedPss >= 4000) {
2679            // Turn this condition on to cause killing to happen regularly, for testing.
2680            if (proc.baseProcessTracker != null) {
2681                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2682            }
2683            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2684                    + "k from cached");
2685        } else if (proc != null && !keepIfLarge
2686                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2687                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2688            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2689            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2690                if (proc.baseProcessTracker != null) {
2691                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2692                }
2693                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2694                        + "k from cached");
2695            }
2696        }
2697        return proc;
2698    }
2699
2700    void ensurePackageDexOpt(String packageName) {
2701        IPackageManager pm = AppGlobals.getPackageManager();
2702        try {
2703            if (pm.performDexOpt(packageName)) {
2704                mDidDexOpt = true;
2705            }
2706        } catch (RemoteException e) {
2707        }
2708    }
2709
2710    boolean isNextTransitionForward() {
2711        int transit = mWindowManager.getPendingAppTransition();
2712        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2713                || transit == AppTransition.TRANSIT_TASK_OPEN
2714                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2715    }
2716
2717    final ProcessRecord startProcessLocked(String processName,
2718            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2719            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2720            boolean isolated, boolean keepIfLarge) {
2721        ProcessRecord app;
2722        if (!isolated) {
2723            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2724        } else {
2725            // If this is an isolated process, it can't re-use an existing process.
2726            app = null;
2727        }
2728        // We don't have to do anything more if:
2729        // (1) There is an existing application record; and
2730        // (2) The caller doesn't think it is dead, OR there is no thread
2731        //     object attached to it so we know it couldn't have crashed; and
2732        // (3) There is a pid assigned to it, so it is either starting or
2733        //     already running.
2734        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2735                + " app=" + app + " knownToBeDead=" + knownToBeDead
2736                + " thread=" + (app != null ? app.thread : null)
2737                + " pid=" + (app != null ? app.pid : -1));
2738        if (app != null && app.pid > 0) {
2739            if (!knownToBeDead || app.thread == null) {
2740                // We already have the app running, or are waiting for it to
2741                // come up (we have a pid but not yet its thread), so keep it.
2742                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2743                // If this is a new package in the process, add the package to the list
2744                app.addPackage(info.packageName, mProcessStats);
2745                return app;
2746            }
2747
2748            // An application record is attached to a previous process,
2749            // clean it up now.
2750            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2751            handleAppDiedLocked(app, true, true);
2752        }
2753
2754        String hostingNameStr = hostingName != null
2755                ? hostingName.flattenToShortString() : null;
2756
2757        if (!isolated) {
2758            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2759                // If we are in the background, then check to see if this process
2760                // is bad.  If so, we will just silently fail.
2761                if (mBadProcesses.get(info.processName, info.uid) != null) {
2762                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2763                            + "/" + info.processName);
2764                    return null;
2765                }
2766            } else {
2767                // When the user is explicitly starting a process, then clear its
2768                // crash count so that we won't make it bad until they see at
2769                // least one crash dialog again, and make the process good again
2770                // if it had been bad.
2771                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2772                        + "/" + info.processName);
2773                mProcessCrashTimes.remove(info.processName, info.uid);
2774                if (mBadProcesses.get(info.processName, info.uid) != null) {
2775                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2776                            UserHandle.getUserId(info.uid), info.uid,
2777                            info.processName);
2778                    mBadProcesses.remove(info.processName, info.uid);
2779                    if (app != null) {
2780                        app.bad = false;
2781                    }
2782                }
2783            }
2784        }
2785
2786        if (app == null) {
2787            app = newProcessRecordLocked(info, processName, isolated);
2788            if (app == null) {
2789                Slog.w(TAG, "Failed making new process record for "
2790                        + processName + "/" + info.uid + " isolated=" + isolated);
2791                return null;
2792            }
2793            mProcessNames.put(processName, app.uid, app);
2794            if (isolated) {
2795                mIsolatedProcesses.put(app.uid, app);
2796            }
2797        } else {
2798            // If this is a new package in the process, add the package to the list
2799            app.addPackage(info.packageName, mProcessStats);
2800        }
2801
2802        // If the system is not ready yet, then hold off on starting this
2803        // process until it is.
2804        if (!mProcessesReady
2805                && !isAllowedWhileBooting(info)
2806                && !allowWhileBooting) {
2807            if (!mProcessesOnHold.contains(app)) {
2808                mProcessesOnHold.add(app);
2809            }
2810            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2811            return app;
2812        }
2813
2814        startProcessLocked(app, hostingType, hostingNameStr);
2815        return (app.pid != 0) ? app : null;
2816    }
2817
2818    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2819        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2820    }
2821
2822    private final void startProcessLocked(ProcessRecord app,
2823            String hostingType, String hostingNameStr) {
2824        if (app.pid > 0 && app.pid != MY_PID) {
2825            synchronized (mPidsSelfLocked) {
2826                mPidsSelfLocked.remove(app.pid);
2827                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2828            }
2829            app.setPid(0);
2830        }
2831
2832        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2833                "startProcessLocked removing on hold: " + app);
2834        mProcessesOnHold.remove(app);
2835
2836        updateCpuStats();
2837
2838        try {
2839            int uid = app.uid;
2840
2841            int[] gids = null;
2842            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2843            if (!app.isolated) {
2844                int[] permGids = null;
2845                try {
2846                    final PackageManager pm = mContext.getPackageManager();
2847                    permGids = pm.getPackageGids(app.info.packageName);
2848
2849                    if (Environment.isExternalStorageEmulated()) {
2850                        if (pm.checkPermission(
2851                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2852                                app.info.packageName) == PERMISSION_GRANTED) {
2853                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2854                        } else {
2855                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2856                        }
2857                    }
2858                } catch (PackageManager.NameNotFoundException e) {
2859                    Slog.w(TAG, "Unable to retrieve gids", e);
2860                }
2861
2862                /*
2863                 * Add shared application GID so applications can share some
2864                 * resources like shared libraries
2865                 */
2866                if (permGids == null) {
2867                    gids = new int[1];
2868                } else {
2869                    gids = new int[permGids.length + 1];
2870                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2871                }
2872                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2873            }
2874            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2875                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2876                        && mTopComponent != null
2877                        && app.processName.equals(mTopComponent.getPackageName())) {
2878                    uid = 0;
2879                }
2880                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2881                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2882                    uid = 0;
2883                }
2884            }
2885            int debugFlags = 0;
2886            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2887                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2888                // Also turn on CheckJNI for debuggable apps. It's quite
2889                // awkward to turn on otherwise.
2890                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2891            }
2892            // Run the app in safe mode if its manifest requests so or the
2893            // system is booted in safe mode.
2894            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2895                mSafeMode == true) {
2896                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2897            }
2898            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2899                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2900            }
2901            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2902                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2903            }
2904            if ("1".equals(SystemProperties.get("debug.assert"))) {
2905                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2906            }
2907
2908            String requiredAbi = app.info.requiredCpuAbi;
2909            if (requiredAbi == null) {
2910                requiredAbi = Build.SUPPORTED_ABIS[0];
2911            }
2912
2913            // Start the process.  It will either succeed and return a result containing
2914            // the PID of the new process, or else throw a RuntimeException.
2915            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2916                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2917                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
2918
2919            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2920            synchronized (bs) {
2921                if (bs.isOnBattery()) {
2922                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2923                }
2924            }
2925
2926            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2927                    UserHandle.getUserId(uid), startResult.pid, uid,
2928                    app.processName, hostingType,
2929                    hostingNameStr != null ? hostingNameStr : "");
2930
2931            if (app.persistent) {
2932                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2933            }
2934
2935            StringBuilder buf = mStringBuilder;
2936            buf.setLength(0);
2937            buf.append("Start proc ");
2938            buf.append(app.processName);
2939            buf.append(" for ");
2940            buf.append(hostingType);
2941            if (hostingNameStr != null) {
2942                buf.append(" ");
2943                buf.append(hostingNameStr);
2944            }
2945            buf.append(": pid=");
2946            buf.append(startResult.pid);
2947            buf.append(" uid=");
2948            buf.append(uid);
2949            buf.append(" gids={");
2950            if (gids != null) {
2951                for (int gi=0; gi<gids.length; gi++) {
2952                    if (gi != 0) buf.append(", ");
2953                    buf.append(gids[gi]);
2954
2955                }
2956            }
2957            buf.append("}");
2958            Slog.i(TAG, buf.toString());
2959            app.setPid(startResult.pid);
2960            app.usingWrapper = startResult.usingWrapper;
2961            app.removed = false;
2962            synchronized (mPidsSelfLocked) {
2963                this.mPidsSelfLocked.put(startResult.pid, app);
2964                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2965                msg.obj = app;
2966                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2967                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2968            }
2969            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
2970                    app.processName, app.info.uid);
2971            if (app.isolated) {
2972                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2973            }
2974        } catch (RuntimeException e) {
2975            // XXX do better error recovery.
2976            app.setPid(0);
2977            Slog.e(TAG, "Failure starting process " + app.processName, e);
2978        }
2979    }
2980
2981    void updateUsageStats(ActivityRecord component, boolean resumed) {
2982        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
2983        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2984        if (resumed) {
2985            mUsageStatsService.noteResumeComponent(component.realActivity);
2986            synchronized (stats) {
2987                stats.noteActivityResumedLocked(component.app.uid);
2988            }
2989        } else {
2990            mUsageStatsService.notePauseComponent(component.realActivity);
2991            synchronized (stats) {
2992                stats.noteActivityPausedLocked(component.app.uid);
2993            }
2994        }
2995    }
2996
2997    Intent getHomeIntent() {
2998        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
2999        intent.setComponent(mTopComponent);
3000        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3001            intent.addCategory(Intent.CATEGORY_HOME);
3002        }
3003        return intent;
3004    }
3005
3006    boolean startHomeActivityLocked(int userId) {
3007        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3008                && mTopAction == null) {
3009            // We are running in factory test mode, but unable to find
3010            // the factory test app, so just sit around displaying the
3011            // error message and don't try to start anything.
3012            return false;
3013        }
3014        Intent intent = getHomeIntent();
3015        ActivityInfo aInfo =
3016            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3017        if (aInfo != null) {
3018            intent.setComponent(new ComponentName(
3019                    aInfo.applicationInfo.packageName, aInfo.name));
3020            // Don't do this if the home app is currently being
3021            // instrumented.
3022            aInfo = new ActivityInfo(aInfo);
3023            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3024            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3025                    aInfo.applicationInfo.uid, true);
3026            if (app == null || app.instrumentationClass == null) {
3027                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3028                mStackSupervisor.startHomeActivity(intent, aInfo);
3029            }
3030        }
3031
3032        return true;
3033    }
3034
3035    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3036        ActivityInfo ai = null;
3037        ComponentName comp = intent.getComponent();
3038        try {
3039            if (comp != null) {
3040                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3041            } else {
3042                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3043                        intent,
3044                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3045                            flags, userId);
3046
3047                if (info != null) {
3048                    ai = info.activityInfo;
3049                }
3050            }
3051        } catch (RemoteException e) {
3052            // ignore
3053        }
3054
3055        return ai;
3056    }
3057
3058    /**
3059     * Starts the "new version setup screen" if appropriate.
3060     */
3061    void startSetupActivityLocked() {
3062        // Only do this once per boot.
3063        if (mCheckedForSetup) {
3064            return;
3065        }
3066
3067        // We will show this screen if the current one is a different
3068        // version than the last one shown, and we are not running in
3069        // low-level factory test mode.
3070        final ContentResolver resolver = mContext.getContentResolver();
3071        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3072                Settings.Global.getInt(resolver,
3073                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3074            mCheckedForSetup = true;
3075
3076            // See if we should be showing the platform update setup UI.
3077            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3078            List<ResolveInfo> ris = mContext.getPackageManager()
3079                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3080
3081            // We don't allow third party apps to replace this.
3082            ResolveInfo ri = null;
3083            for (int i=0; ris != null && i<ris.size(); i++) {
3084                if ((ris.get(i).activityInfo.applicationInfo.flags
3085                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3086                    ri = ris.get(i);
3087                    break;
3088                }
3089            }
3090
3091            if (ri != null) {
3092                String vers = ri.activityInfo.metaData != null
3093                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3094                        : null;
3095                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3096                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3097                            Intent.METADATA_SETUP_VERSION);
3098                }
3099                String lastVers = Settings.Secure.getString(
3100                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3101                if (vers != null && !vers.equals(lastVers)) {
3102                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3103                    intent.setComponent(new ComponentName(
3104                            ri.activityInfo.packageName, ri.activityInfo.name));
3105                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3106                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3107                }
3108            }
3109        }
3110    }
3111
3112    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3113        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3114    }
3115
3116    void enforceNotIsolatedCaller(String caller) {
3117        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3118            throw new SecurityException("Isolated process not allowed to call " + caller);
3119        }
3120    }
3121
3122    @Override
3123    public int getFrontActivityScreenCompatMode() {
3124        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3125        synchronized (this) {
3126            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3127        }
3128    }
3129
3130    @Override
3131    public void setFrontActivityScreenCompatMode(int mode) {
3132        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3133                "setFrontActivityScreenCompatMode");
3134        synchronized (this) {
3135            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3136        }
3137    }
3138
3139    @Override
3140    public int getPackageScreenCompatMode(String packageName) {
3141        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3142        synchronized (this) {
3143            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3144        }
3145    }
3146
3147    @Override
3148    public void setPackageScreenCompatMode(String packageName, int mode) {
3149        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3150                "setPackageScreenCompatMode");
3151        synchronized (this) {
3152            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3153        }
3154    }
3155
3156    @Override
3157    public boolean getPackageAskScreenCompat(String packageName) {
3158        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3159        synchronized (this) {
3160            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3161        }
3162    }
3163
3164    @Override
3165    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3166        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3167                "setPackageAskScreenCompat");
3168        synchronized (this) {
3169            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3170        }
3171    }
3172
3173    private void dispatchProcessesChanged() {
3174        int N;
3175        synchronized (this) {
3176            N = mPendingProcessChanges.size();
3177            if (mActiveProcessChanges.length < N) {
3178                mActiveProcessChanges = new ProcessChangeItem[N];
3179            }
3180            mPendingProcessChanges.toArray(mActiveProcessChanges);
3181            mAvailProcessChanges.addAll(mPendingProcessChanges);
3182            mPendingProcessChanges.clear();
3183            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3184        }
3185
3186        int i = mProcessObservers.beginBroadcast();
3187        while (i > 0) {
3188            i--;
3189            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3190            if (observer != null) {
3191                try {
3192                    for (int j=0; j<N; j++) {
3193                        ProcessChangeItem item = mActiveProcessChanges[j];
3194                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3195                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3196                                    + item.pid + " uid=" + item.uid + ": "
3197                                    + item.foregroundActivities);
3198                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3199                                    item.foregroundActivities);
3200                        }
3201                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3202                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3203                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3204                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3205                        }
3206                    }
3207                } catch (RemoteException e) {
3208                }
3209            }
3210        }
3211        mProcessObservers.finishBroadcast();
3212    }
3213
3214    private void dispatchProcessDied(int pid, int uid) {
3215        int i = mProcessObservers.beginBroadcast();
3216        while (i > 0) {
3217            i--;
3218            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3219            if (observer != null) {
3220                try {
3221                    observer.onProcessDied(pid, uid);
3222                } catch (RemoteException e) {
3223                }
3224            }
3225        }
3226        mProcessObservers.finishBroadcast();
3227    }
3228
3229    final void doPendingActivityLaunchesLocked(boolean doResume) {
3230        final int N = mPendingActivityLaunches.size();
3231        if (N <= 0) {
3232            return;
3233        }
3234        for (int i=0; i<N; i++) {
3235            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3236            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
3237                    doResume && i == (N-1), null);
3238        }
3239        mPendingActivityLaunches.clear();
3240    }
3241
3242    @Override
3243    public final int startActivity(IApplicationThread caller, String callingPackage,
3244            Intent intent, String resolvedType, IBinder resultTo,
3245            String resultWho, int requestCode, int startFlags,
3246            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3247        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3248                resultWho, requestCode,
3249                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3250    }
3251
3252    @Override
3253    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3254            Intent intent, String resolvedType, IBinder resultTo,
3255            String resultWho, int requestCode, int startFlags,
3256            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3257        enforceNotIsolatedCaller("startActivity");
3258        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3259                false, true, "startActivity", null);
3260        // TODO: Switch to user app stacks here.
3261        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3262                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3263                null, null, options, userId, null);
3264    }
3265
3266    @Override
3267    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3268            Intent intent, String resolvedType, IBinder resultTo,
3269            String resultWho, int requestCode, int startFlags, String profileFile,
3270            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3271        enforceNotIsolatedCaller("startActivityAndWait");
3272        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3273                false, true, "startActivityAndWait", null);
3274        WaitResult res = new WaitResult();
3275        // TODO: Switch to user app stacks here.
3276        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3277                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3278                res, null, options, UserHandle.getCallingUserId(), null);
3279        return res;
3280    }
3281
3282    @Override
3283    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3284            Intent intent, String resolvedType, IBinder resultTo,
3285            String resultWho, int requestCode, int startFlags, Configuration config,
3286            Bundle options, int userId) {
3287        enforceNotIsolatedCaller("startActivityWithConfig");
3288        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3289                false, true, "startActivityWithConfig", null);
3290        // TODO: Switch to user app stacks here.
3291        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3292                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3293                null, null, null, config, options, userId, null);
3294        return ret;
3295    }
3296
3297    @Override
3298    public int startActivityIntentSender(IApplicationThread caller,
3299            IntentSender intent, Intent fillInIntent, String resolvedType,
3300            IBinder resultTo, String resultWho, int requestCode,
3301            int flagsMask, int flagsValues, Bundle options) {
3302        enforceNotIsolatedCaller("startActivityIntentSender");
3303        // Refuse possible leaked file descriptors
3304        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3305            throw new IllegalArgumentException("File descriptors passed in Intent");
3306        }
3307
3308        IIntentSender sender = intent.getTarget();
3309        if (!(sender instanceof PendingIntentRecord)) {
3310            throw new IllegalArgumentException("Bad PendingIntent object");
3311        }
3312
3313        PendingIntentRecord pir = (PendingIntentRecord)sender;
3314
3315        synchronized (this) {
3316            // If this is coming from the currently resumed activity, it is
3317            // effectively saying that app switches are allowed at this point.
3318            final ActivityStack stack = getFocusedStack();
3319            if (stack.mResumedActivity != null &&
3320                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3321                mAppSwitchesAllowedTime = 0;
3322            }
3323        }
3324        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3325                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3326        return ret;
3327    }
3328
3329    @Override
3330    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3331            Intent intent, String resolvedType, IVoiceInteractionSession session,
3332            IVoiceInteractor interactor, int startFlags, String profileFile,
3333            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3334        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3335                != PackageManager.PERMISSION_GRANTED) {
3336            String msg = "Permission Denial: startVoiceActivity() from pid="
3337                    + Binder.getCallingPid()
3338                    + ", uid=" + Binder.getCallingUid()
3339                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3340            Slog.w(TAG, msg);
3341            throw new SecurityException(msg);
3342        }
3343        if (session == null || interactor == null) {
3344            throw new NullPointerException("null session or interactor");
3345        }
3346        userId = handleIncomingUser(callingPid, callingUid, userId,
3347                false, true, "startVoiceActivity", null);
3348        // TODO: Switch to user app stacks here.
3349        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3350                resolvedType, session, interactor, null, null, 0, startFlags,
3351                profileFile, profileFd, null, null, options, userId, null);
3352    }
3353
3354    @Override
3355    public boolean startNextMatchingActivity(IBinder callingActivity,
3356            Intent intent, Bundle options) {
3357        // Refuse possible leaked file descriptors
3358        if (intent != null && intent.hasFileDescriptors() == true) {
3359            throw new IllegalArgumentException("File descriptors passed in Intent");
3360        }
3361
3362        synchronized (this) {
3363            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3364            if (r == null) {
3365                ActivityOptions.abort(options);
3366                return false;
3367            }
3368            if (r.app == null || r.app.thread == null) {
3369                // The caller is not running...  d'oh!
3370                ActivityOptions.abort(options);
3371                return false;
3372            }
3373            intent = new Intent(intent);
3374            // The caller is not allowed to change the data.
3375            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3376            // And we are resetting to find the next component...
3377            intent.setComponent(null);
3378
3379            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3380
3381            ActivityInfo aInfo = null;
3382            try {
3383                List<ResolveInfo> resolves =
3384                    AppGlobals.getPackageManager().queryIntentActivities(
3385                            intent, r.resolvedType,
3386                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3387                            UserHandle.getCallingUserId());
3388
3389                // Look for the original activity in the list...
3390                final int N = resolves != null ? resolves.size() : 0;
3391                for (int i=0; i<N; i++) {
3392                    ResolveInfo rInfo = resolves.get(i);
3393                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3394                            && rInfo.activityInfo.name.equals(r.info.name)) {
3395                        // We found the current one...  the next matching is
3396                        // after it.
3397                        i++;
3398                        if (i<N) {
3399                            aInfo = resolves.get(i).activityInfo;
3400                        }
3401                        if (debug) {
3402                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3403                                    + "/" + r.info.name);
3404                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3405                                    + "/" + aInfo.name);
3406                        }
3407                        break;
3408                    }
3409                }
3410            } catch (RemoteException e) {
3411            }
3412
3413            if (aInfo == null) {
3414                // Nobody who is next!
3415                ActivityOptions.abort(options);
3416                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3417                return false;
3418            }
3419
3420            intent.setComponent(new ComponentName(
3421                    aInfo.applicationInfo.packageName, aInfo.name));
3422            intent.setFlags(intent.getFlags()&~(
3423                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3424                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3425                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3426                    Intent.FLAG_ACTIVITY_NEW_TASK));
3427
3428            // Okay now we need to start the new activity, replacing the
3429            // currently running activity.  This is a little tricky because
3430            // we want to start the new one as if the current one is finished,
3431            // but not finish the current one first so that there is no flicker.
3432            // And thus...
3433            final boolean wasFinishing = r.finishing;
3434            r.finishing = true;
3435
3436            // Propagate reply information over to the new activity.
3437            final ActivityRecord resultTo = r.resultTo;
3438            final String resultWho = r.resultWho;
3439            final int requestCode = r.requestCode;
3440            r.resultTo = null;
3441            if (resultTo != null) {
3442                resultTo.removeResultsLocked(r, resultWho, requestCode);
3443            }
3444
3445            final long origId = Binder.clearCallingIdentity();
3446            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3447                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3448                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3449                    options, false, null, null);
3450            Binder.restoreCallingIdentity(origId);
3451
3452            r.finishing = wasFinishing;
3453            if (res != ActivityManager.START_SUCCESS) {
3454                return false;
3455            }
3456            return true;
3457        }
3458    }
3459
3460    final int startActivityInPackage(int uid, String callingPackage,
3461            Intent intent, String resolvedType, IBinder resultTo,
3462            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3463                    IActivityContainer container) {
3464
3465        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3466                false, true, "startActivityInPackage", null);
3467
3468        // TODO: Switch to user app stacks here.
3469        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3470                null, null, resultTo, resultWho, requestCode, startFlags,
3471                null, null, null, null, options, userId, container);
3472        return ret;
3473    }
3474
3475    @Override
3476    public final int startActivities(IApplicationThread caller, String callingPackage,
3477            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3478            int userId) {
3479        enforceNotIsolatedCaller("startActivities");
3480        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3481                false, true, "startActivity", null);
3482        // TODO: Switch to user app stacks here.
3483        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3484                resolvedTypes, resultTo, options, userId);
3485        return ret;
3486    }
3487
3488    final int startActivitiesInPackage(int uid, String callingPackage,
3489            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3490            Bundle options, int userId) {
3491
3492        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3493                false, true, "startActivityInPackage", null);
3494        // TODO: Switch to user app stacks here.
3495        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3496                resultTo, options, userId);
3497        return ret;
3498    }
3499
3500    final void addRecentTaskLocked(TaskRecord task) {
3501        int N = mRecentTasks.size();
3502        // Quick case: check if the top-most recent task is the same.
3503        if (N > 0 && mRecentTasks.get(0) == task) {
3504            return;
3505        }
3506        // Another quick case: never add voice sessions.
3507        if (task.voiceSession != null) {
3508            return;
3509        }
3510        // Remove any existing entries that are the same kind of task.
3511        final Intent intent = task.intent;
3512        final boolean document = intent != null && intent.isDocument();
3513        for (int i=0; i<N; i++) {
3514            TaskRecord tr = mRecentTasks.get(i);
3515            if (task != tr) {
3516                if (task.userId != tr.userId) {
3517                    continue;
3518                }
3519                final Intent trIntent = tr.intent;
3520                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3521                    (intent == null || !intent.filterEquals(trIntent))) {
3522                    continue;
3523                }
3524                if (document || trIntent != null && trIntent.isDocument()) {
3525                    // Document tasks do not match other tasks.
3526                    continue;
3527                }
3528            }
3529
3530            // Either task and tr are the same or, their affinities match or their intents match
3531            // and neither of them is a document.
3532            tr.disposeThumbnail();
3533            mRecentTasks.remove(i);
3534            i--;
3535            N--;
3536            if (task.intent == null) {
3537                // If the new recent task we are adding is not fully
3538                // specified, then replace it with the existing recent task.
3539                task = tr;
3540            }
3541        }
3542        if (N >= MAX_RECENT_TASKS) {
3543            mRecentTasks.remove(N-1).disposeThumbnail();
3544        }
3545        mRecentTasks.add(0, task);
3546    }
3547
3548    @Override
3549    public void reportActivityFullyDrawn(IBinder token) {
3550        synchronized (this) {
3551            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3552            if (r == null) {
3553                return;
3554            }
3555            r.reportFullyDrawnLocked();
3556        }
3557    }
3558
3559    @Override
3560    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3561        synchronized (this) {
3562            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3563            if (r == null) {
3564                return;
3565            }
3566            final long origId = Binder.clearCallingIdentity();
3567            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3568            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3569                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3570            if (config != null) {
3571                r.frozenBeforeDestroy = true;
3572                if (!updateConfigurationLocked(config, r, false, false)) {
3573                    mStackSupervisor.resumeTopActivitiesLocked();
3574                }
3575            }
3576            Binder.restoreCallingIdentity(origId);
3577        }
3578    }
3579
3580    @Override
3581    public int getRequestedOrientation(IBinder token) {
3582        synchronized (this) {
3583            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3584            if (r == null) {
3585                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3586            }
3587            return mWindowManager.getAppOrientation(r.appToken);
3588        }
3589    }
3590
3591    /**
3592     * This is the internal entry point for handling Activity.finish().
3593     *
3594     * @param token The Binder token referencing the Activity we want to finish.
3595     * @param resultCode Result code, if any, from this Activity.
3596     * @param resultData Result data (Intent), if any, from this Activity.
3597     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3598     *            the root Activity in the task.
3599     *
3600     * @return Returns true if the activity successfully finished, or false if it is still running.
3601     */
3602    @Override
3603    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3604            boolean finishTask) {
3605        // Refuse possible leaked file descriptors
3606        if (resultData != null && resultData.hasFileDescriptors() == true) {
3607            throw new IllegalArgumentException("File descriptors passed in Intent");
3608        }
3609
3610        synchronized(this) {
3611            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3612            if (r == null) {
3613                return true;
3614            }
3615            // Keep track of the root activity of the task before we finish it
3616            TaskRecord tr = r.task;
3617            ActivityRecord rootR = tr.getRootActivity();
3618            if (mController != null) {
3619                // Find the first activity that is not finishing.
3620                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3621                if (next != null) {
3622                    // ask watcher if this is allowed
3623                    boolean resumeOK = true;
3624                    try {
3625                        resumeOK = mController.activityResuming(next.packageName);
3626                    } catch (RemoteException e) {
3627                        mController = null;
3628                        Watchdog.getInstance().setActivityController(null);
3629                    }
3630
3631                    if (!resumeOK) {
3632                        return false;
3633                    }
3634                }
3635            }
3636            final long origId = Binder.clearCallingIdentity();
3637            try {
3638                boolean res;
3639                if (finishTask && r == rootR) {
3640                    // If requested, remove the task that is associated to this activity only if it
3641                    // was the root activity in the task.  The result code and data is ignored because
3642                    // we don't support returning them across task boundaries.
3643                    res = removeTaskByIdLocked(tr.taskId, 0);
3644                } else {
3645                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3646                            resultData, "app-request", true);
3647                }
3648                return res;
3649            } finally {
3650                Binder.restoreCallingIdentity(origId);
3651            }
3652        }
3653    }
3654
3655    @Override
3656    public final void finishHeavyWeightApp() {
3657        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3658                != PackageManager.PERMISSION_GRANTED) {
3659            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3660                    + Binder.getCallingPid()
3661                    + ", uid=" + Binder.getCallingUid()
3662                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3663            Slog.w(TAG, msg);
3664            throw new SecurityException(msg);
3665        }
3666
3667        synchronized(this) {
3668            if (mHeavyWeightProcess == null) {
3669                return;
3670            }
3671
3672            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3673                    mHeavyWeightProcess.activities);
3674            for (int i=0; i<activities.size(); i++) {
3675                ActivityRecord r = activities.get(i);
3676                if (!r.finishing) {
3677                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3678                            null, "finish-heavy", true);
3679                }
3680            }
3681
3682            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3683                    mHeavyWeightProcess.userId, 0));
3684            mHeavyWeightProcess = null;
3685        }
3686    }
3687
3688    @Override
3689    public void crashApplication(int uid, int initialPid, String packageName,
3690            String message) {
3691        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3692                != PackageManager.PERMISSION_GRANTED) {
3693            String msg = "Permission Denial: crashApplication() from pid="
3694                    + Binder.getCallingPid()
3695                    + ", uid=" + Binder.getCallingUid()
3696                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3697            Slog.w(TAG, msg);
3698            throw new SecurityException(msg);
3699        }
3700
3701        synchronized(this) {
3702            ProcessRecord proc = null;
3703
3704            // Figure out which process to kill.  We don't trust that initialPid
3705            // still has any relation to current pids, so must scan through the
3706            // list.
3707            synchronized (mPidsSelfLocked) {
3708                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3709                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3710                    if (p.uid != uid) {
3711                        continue;
3712                    }
3713                    if (p.pid == initialPid) {
3714                        proc = p;
3715                        break;
3716                    }
3717                    if (p.pkgList.containsKey(packageName)) {
3718                        proc = p;
3719                    }
3720                }
3721            }
3722
3723            if (proc == null) {
3724                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3725                        + " initialPid=" + initialPid
3726                        + " packageName=" + packageName);
3727                return;
3728            }
3729
3730            if (proc.thread != null) {
3731                if (proc.pid == Process.myPid()) {
3732                    Log.w(TAG, "crashApplication: trying to crash self!");
3733                    return;
3734                }
3735                long ident = Binder.clearCallingIdentity();
3736                try {
3737                    proc.thread.scheduleCrash(message);
3738                } catch (RemoteException e) {
3739                }
3740                Binder.restoreCallingIdentity(ident);
3741            }
3742        }
3743    }
3744
3745    @Override
3746    public final void finishSubActivity(IBinder token, String resultWho,
3747            int requestCode) {
3748        synchronized(this) {
3749            final long origId = Binder.clearCallingIdentity();
3750            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3751            if (r != null) {
3752                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3753            }
3754            Binder.restoreCallingIdentity(origId);
3755        }
3756    }
3757
3758    @Override
3759    public boolean finishActivityAffinity(IBinder token) {
3760        synchronized(this) {
3761            final long origId = Binder.clearCallingIdentity();
3762            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3763            boolean res = false;
3764            if (r != null) {
3765                res = r.task.stack.finishActivityAffinityLocked(r);
3766            }
3767            Binder.restoreCallingIdentity(origId);
3768            return res;
3769        }
3770    }
3771
3772    @Override
3773    public boolean willActivityBeVisible(IBinder token) {
3774        synchronized(this) {
3775            ActivityStack stack = ActivityRecord.getStackLocked(token);
3776            if (stack != null) {
3777                return stack.willActivityBeVisibleLocked(token);
3778            }
3779            return false;
3780        }
3781    }
3782
3783    @Override
3784    public void overridePendingTransition(IBinder token, String packageName,
3785            int enterAnim, int exitAnim) {
3786        synchronized(this) {
3787            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3788            if (self == null) {
3789                return;
3790            }
3791
3792            final long origId = Binder.clearCallingIdentity();
3793
3794            if (self.state == ActivityState.RESUMED
3795                    || self.state == ActivityState.PAUSING) {
3796                mWindowManager.overridePendingAppTransition(packageName,
3797                        enterAnim, exitAnim, null);
3798            }
3799
3800            Binder.restoreCallingIdentity(origId);
3801        }
3802    }
3803
3804    /**
3805     * Main function for removing an existing process from the activity manager
3806     * as a result of that process going away.  Clears out all connections
3807     * to the process.
3808     */
3809    private final void handleAppDiedLocked(ProcessRecord app,
3810            boolean restarting, boolean allowRestart) {
3811        int pid = app.pid;
3812        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3813        if (!restarting) {
3814            removeLruProcessLocked(app);
3815            if (pid > 0) {
3816                ProcessList.remove(pid);
3817            }
3818        }
3819
3820        if (mProfileProc == app) {
3821            clearProfilerLocked();
3822        }
3823
3824        // Remove this application's activities from active lists.
3825        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3826
3827        app.activities.clear();
3828
3829        if (app.instrumentationClass != null) {
3830            Slog.w(TAG, "Crash of app " + app.processName
3831                  + " running instrumentation " + app.instrumentationClass);
3832            Bundle info = new Bundle();
3833            info.putString("shortMsg", "Process crashed.");
3834            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3835        }
3836
3837        if (!restarting) {
3838            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3839                // If there was nothing to resume, and we are not already
3840                // restarting this process, but there is a visible activity that
3841                // is hosted by the process...  then make sure all visible
3842                // activities are running, taking care of restarting this
3843                // process.
3844                if (hasVisibleActivities) {
3845                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3846                }
3847            }
3848        }
3849    }
3850
3851    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3852        IBinder threadBinder = thread.asBinder();
3853        // Find the application record.
3854        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3855            ProcessRecord rec = mLruProcesses.get(i);
3856            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3857                return i;
3858            }
3859        }
3860        return -1;
3861    }
3862
3863    final ProcessRecord getRecordForAppLocked(
3864            IApplicationThread thread) {
3865        if (thread == null) {
3866            return null;
3867        }
3868
3869        int appIndex = getLRURecordIndexForAppLocked(thread);
3870        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3871    }
3872
3873    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3874        // If there are no longer any background processes running,
3875        // and the app that died was not running instrumentation,
3876        // then tell everyone we are now low on memory.
3877        boolean haveBg = false;
3878        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3879            ProcessRecord rec = mLruProcesses.get(i);
3880            if (rec.thread != null
3881                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3882                haveBg = true;
3883                break;
3884            }
3885        }
3886
3887        if (!haveBg) {
3888            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3889            if (doReport) {
3890                long now = SystemClock.uptimeMillis();
3891                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3892                    doReport = false;
3893                } else {
3894                    mLastMemUsageReportTime = now;
3895                }
3896            }
3897            final ArrayList<ProcessMemInfo> memInfos
3898                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3899            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3900            long now = SystemClock.uptimeMillis();
3901            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3902                ProcessRecord rec = mLruProcesses.get(i);
3903                if (rec == dyingProc || rec.thread == null) {
3904                    continue;
3905                }
3906                if (doReport) {
3907                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3908                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3909                }
3910                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3911                    // The low memory report is overriding any current
3912                    // state for a GC request.  Make sure to do
3913                    // heavy/important/visible/foreground processes first.
3914                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3915                        rec.lastRequestedGc = 0;
3916                    } else {
3917                        rec.lastRequestedGc = rec.lastLowMemory;
3918                    }
3919                    rec.reportLowMemory = true;
3920                    rec.lastLowMemory = now;
3921                    mProcessesToGc.remove(rec);
3922                    addProcessToGcListLocked(rec);
3923                }
3924            }
3925            if (doReport) {
3926                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3927                mHandler.sendMessage(msg);
3928            }
3929            scheduleAppGcsLocked();
3930        }
3931    }
3932
3933    final void appDiedLocked(ProcessRecord app, int pid,
3934            IApplicationThread thread) {
3935
3936        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3937        synchronized (stats) {
3938            stats.noteProcessDiedLocked(app.info.uid, pid);
3939        }
3940
3941        // Clean up already done if the process has been re-started.
3942        if (app.pid == pid && app.thread != null &&
3943                app.thread.asBinder() == thread.asBinder()) {
3944            boolean doLowMem = app.instrumentationClass == null;
3945            boolean doOomAdj = doLowMem;
3946            if (!app.killedByAm) {
3947                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3948                        + ") has died.");
3949                mAllowLowerMemLevel = true;
3950            } else {
3951                // Note that we always want to do oom adj to update our state with the
3952                // new number of procs.
3953                mAllowLowerMemLevel = false;
3954                doLowMem = false;
3955            }
3956            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3957            if (DEBUG_CLEANUP) Slog.v(
3958                TAG, "Dying app: " + app + ", pid: " + pid
3959                + ", thread: " + thread.asBinder());
3960            handleAppDiedLocked(app, false, true);
3961
3962            if (doOomAdj) {
3963                updateOomAdjLocked();
3964            }
3965            if (doLowMem) {
3966                doLowMemReportIfNeededLocked(app);
3967            }
3968        } else if (app.pid != pid) {
3969            // A new process has already been started.
3970            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3971                    + ") has died and restarted (pid " + app.pid + ").");
3972            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3973        } else if (DEBUG_PROCESSES) {
3974            Slog.d(TAG, "Received spurious death notification for thread "
3975                    + thread.asBinder());
3976        }
3977    }
3978
3979    /**
3980     * If a stack trace dump file is configured, dump process stack traces.
3981     * @param clearTraces causes the dump file to be erased prior to the new
3982     *    traces being written, if true; when false, the new traces will be
3983     *    appended to any existing file content.
3984     * @param firstPids of dalvik VM processes to dump stack traces for first
3985     * @param lastPids of dalvik VM processes to dump stack traces for last
3986     * @param nativeProcs optional list of native process names to dump stack crawls
3987     * @return file containing stack traces, or null if no dump file is configured
3988     */
3989    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3990            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3991        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3992        if (tracesPath == null || tracesPath.length() == 0) {
3993            return null;
3994        }
3995
3996        File tracesFile = new File(tracesPath);
3997        try {
3998            File tracesDir = tracesFile.getParentFile();
3999            if (!tracesDir.exists()) {
4000                tracesFile.mkdirs();
4001                if (!SELinux.restorecon(tracesDir)) {
4002                    return null;
4003                }
4004            }
4005            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4006
4007            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4008            tracesFile.createNewFile();
4009            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4010        } catch (IOException e) {
4011            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4012            return null;
4013        }
4014
4015        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4016        return tracesFile;
4017    }
4018
4019    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4020            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4021        // Use a FileObserver to detect when traces finish writing.
4022        // The order of traces is considered important to maintain for legibility.
4023        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4024            @Override
4025            public synchronized void onEvent(int event, String path) { notify(); }
4026        };
4027
4028        try {
4029            observer.startWatching();
4030
4031            // First collect all of the stacks of the most important pids.
4032            if (firstPids != null) {
4033                try {
4034                    int num = firstPids.size();
4035                    for (int i = 0; i < num; i++) {
4036                        synchronized (observer) {
4037                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4038                            observer.wait(200);  // Wait for write-close, give up after 200msec
4039                        }
4040                    }
4041                } catch (InterruptedException e) {
4042                    Log.wtf(TAG, e);
4043                }
4044            }
4045
4046            // Next collect the stacks of the native pids
4047            if (nativeProcs != null) {
4048                int[] pids = Process.getPidsForCommands(nativeProcs);
4049                if (pids != null) {
4050                    for (int pid : pids) {
4051                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4052                    }
4053                }
4054            }
4055
4056            // Lastly, measure CPU usage.
4057            if (processCpuTracker != null) {
4058                processCpuTracker.init();
4059                System.gc();
4060                processCpuTracker.update();
4061                try {
4062                    synchronized (processCpuTracker) {
4063                        processCpuTracker.wait(500); // measure over 1/2 second.
4064                    }
4065                } catch (InterruptedException e) {
4066                }
4067                processCpuTracker.update();
4068
4069                // We'll take the stack crawls of just the top apps using CPU.
4070                final int N = processCpuTracker.countWorkingStats();
4071                int numProcs = 0;
4072                for (int i=0; i<N && numProcs<5; i++) {
4073                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4074                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4075                        numProcs++;
4076                        try {
4077                            synchronized (observer) {
4078                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4079                                observer.wait(200);  // Wait for write-close, give up after 200msec
4080                            }
4081                        } catch (InterruptedException e) {
4082                            Log.wtf(TAG, e);
4083                        }
4084
4085                    }
4086                }
4087            }
4088        } finally {
4089            observer.stopWatching();
4090        }
4091    }
4092
4093    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4094        if (true || IS_USER_BUILD) {
4095            return;
4096        }
4097        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4098        if (tracesPath == null || tracesPath.length() == 0) {
4099            return;
4100        }
4101
4102        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4103        StrictMode.allowThreadDiskWrites();
4104        try {
4105            final File tracesFile = new File(tracesPath);
4106            final File tracesDir = tracesFile.getParentFile();
4107            final File tracesTmp = new File(tracesDir, "__tmp__");
4108            try {
4109                if (!tracesDir.exists()) {
4110                    tracesFile.mkdirs();
4111                    if (!SELinux.restorecon(tracesDir.getPath())) {
4112                        return;
4113                    }
4114                }
4115                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4116
4117                if (tracesFile.exists()) {
4118                    tracesTmp.delete();
4119                    tracesFile.renameTo(tracesTmp);
4120                }
4121                StringBuilder sb = new StringBuilder();
4122                Time tobj = new Time();
4123                tobj.set(System.currentTimeMillis());
4124                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4125                sb.append(": ");
4126                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4127                sb.append(" since ");
4128                sb.append(msg);
4129                FileOutputStream fos = new FileOutputStream(tracesFile);
4130                fos.write(sb.toString().getBytes());
4131                if (app == null) {
4132                    fos.write("\n*** No application process!".getBytes());
4133                }
4134                fos.close();
4135                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4136            } catch (IOException e) {
4137                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4138                return;
4139            }
4140
4141            if (app != null) {
4142                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4143                firstPids.add(app.pid);
4144                dumpStackTraces(tracesPath, firstPids, null, null, null);
4145            }
4146
4147            File lastTracesFile = null;
4148            File curTracesFile = null;
4149            for (int i=9; i>=0; i--) {
4150                String name = String.format(Locale.US, "slow%02d.txt", i);
4151                curTracesFile = new File(tracesDir, name);
4152                if (curTracesFile.exists()) {
4153                    if (lastTracesFile != null) {
4154                        curTracesFile.renameTo(lastTracesFile);
4155                    } else {
4156                        curTracesFile.delete();
4157                    }
4158                }
4159                lastTracesFile = curTracesFile;
4160            }
4161            tracesFile.renameTo(curTracesFile);
4162            if (tracesTmp.exists()) {
4163                tracesTmp.renameTo(tracesFile);
4164            }
4165        } finally {
4166            StrictMode.setThreadPolicy(oldPolicy);
4167        }
4168    }
4169
4170    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4171            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4172        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4173        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4174
4175        if (mController != null) {
4176            try {
4177                // 0 == continue, -1 = kill process immediately
4178                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4179                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
4180            } catch (RemoteException e) {
4181                mController = null;
4182                Watchdog.getInstance().setActivityController(null);
4183            }
4184        }
4185
4186        long anrTime = SystemClock.uptimeMillis();
4187        if (MONITOR_CPU_USAGE) {
4188            updateCpuStatsNow();
4189        }
4190
4191        synchronized (this) {
4192            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4193            if (mShuttingDown) {
4194                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4195                return;
4196            } else if (app.notResponding) {
4197                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4198                return;
4199            } else if (app.crashing) {
4200                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4201                return;
4202            }
4203
4204            // In case we come through here for the same app before completing
4205            // this one, mark as anring now so we will bail out.
4206            app.notResponding = true;
4207
4208            // Log the ANR to the event log.
4209            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4210                    app.processName, app.info.flags, annotation);
4211
4212            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4213            firstPids.add(app.pid);
4214
4215            int parentPid = app.pid;
4216            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4217            if (parentPid != app.pid) firstPids.add(parentPid);
4218
4219            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4220
4221            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4222                ProcessRecord r = mLruProcesses.get(i);
4223                if (r != null && r.thread != null) {
4224                    int pid = r.pid;
4225                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4226                        if (r.persistent) {
4227                            firstPids.add(pid);
4228                        } else {
4229                            lastPids.put(pid, Boolean.TRUE);
4230                        }
4231                    }
4232                }
4233            }
4234        }
4235
4236        // Log the ANR to the main log.
4237        StringBuilder info = new StringBuilder();
4238        info.setLength(0);
4239        info.append("ANR in ").append(app.processName);
4240        if (activity != null && activity.shortComponentName != null) {
4241            info.append(" (").append(activity.shortComponentName).append(")");
4242        }
4243        info.append("\n");
4244        info.append("PID: ").append(app.pid).append("\n");
4245        if (annotation != null) {
4246            info.append("Reason: ").append(annotation).append("\n");
4247        }
4248        if (parent != null && parent != activity) {
4249            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4250        }
4251
4252        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4253
4254        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4255                NATIVE_STACKS_OF_INTEREST);
4256
4257        String cpuInfo = null;
4258        if (MONITOR_CPU_USAGE) {
4259            updateCpuStatsNow();
4260            synchronized (mProcessCpuThread) {
4261                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4262            }
4263            info.append(processCpuTracker.printCurrentLoad());
4264            info.append(cpuInfo);
4265        }
4266
4267        info.append(processCpuTracker.printCurrentState(anrTime));
4268
4269        Slog.e(TAG, info.toString());
4270        if (tracesFile == null) {
4271            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4272            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4273        }
4274
4275        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4276                cpuInfo, tracesFile, null);
4277
4278        if (mController != null) {
4279            try {
4280                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4281                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4282                if (res != 0) {
4283                    if (res < 0 && app.pid != MY_PID) {
4284                        Process.killProcess(app.pid);
4285                    } else {
4286                        synchronized (this) {
4287                            mServices.scheduleServiceTimeoutLocked(app);
4288                        }
4289                    }
4290                    return;
4291                }
4292            } catch (RemoteException e) {
4293                mController = null;
4294                Watchdog.getInstance().setActivityController(null);
4295            }
4296        }
4297
4298        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4299        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4300                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4301
4302        synchronized (this) {
4303            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4304                killUnneededProcessLocked(app, "background ANR");
4305                return;
4306            }
4307
4308            // Set the app's notResponding state, and look up the errorReportReceiver
4309            makeAppNotRespondingLocked(app,
4310                    activity != null ? activity.shortComponentName : null,
4311                    annotation != null ? "ANR " + annotation : "ANR",
4312                    info.toString());
4313
4314            // Bring up the infamous App Not Responding dialog
4315            Message msg = Message.obtain();
4316            HashMap<String, Object> map = new HashMap<String, Object>();
4317            msg.what = SHOW_NOT_RESPONDING_MSG;
4318            msg.obj = map;
4319            msg.arg1 = aboveSystem ? 1 : 0;
4320            map.put("app", app);
4321            if (activity != null) {
4322                map.put("activity", activity);
4323            }
4324
4325            mHandler.sendMessage(msg);
4326        }
4327    }
4328
4329    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4330        if (!mLaunchWarningShown) {
4331            mLaunchWarningShown = true;
4332            mHandler.post(new Runnable() {
4333                @Override
4334                public void run() {
4335                    synchronized (ActivityManagerService.this) {
4336                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4337                        d.show();
4338                        mHandler.postDelayed(new Runnable() {
4339                            @Override
4340                            public void run() {
4341                                synchronized (ActivityManagerService.this) {
4342                                    d.dismiss();
4343                                    mLaunchWarningShown = false;
4344                                }
4345                            }
4346                        }, 4000);
4347                    }
4348                }
4349            });
4350        }
4351    }
4352
4353    @Override
4354    public boolean clearApplicationUserData(final String packageName,
4355            final IPackageDataObserver observer, int userId) {
4356        enforceNotIsolatedCaller("clearApplicationUserData");
4357        int uid = Binder.getCallingUid();
4358        int pid = Binder.getCallingPid();
4359        userId = handleIncomingUser(pid, uid,
4360                userId, false, true, "clearApplicationUserData", null);
4361        long callingId = Binder.clearCallingIdentity();
4362        try {
4363            IPackageManager pm = AppGlobals.getPackageManager();
4364            int pkgUid = -1;
4365            synchronized(this) {
4366                try {
4367                    pkgUid = pm.getPackageUid(packageName, userId);
4368                } catch (RemoteException e) {
4369                }
4370                if (pkgUid == -1) {
4371                    Slog.w(TAG, "Invalid packageName: " + packageName);
4372                    if (observer != null) {
4373                        try {
4374                            observer.onRemoveCompleted(packageName, false);
4375                        } catch (RemoteException e) {
4376                            Slog.i(TAG, "Observer no longer exists.");
4377                        }
4378                    }
4379                    return false;
4380                }
4381                if (uid == pkgUid || checkComponentPermission(
4382                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4383                        pid, uid, -1, true)
4384                        == PackageManager.PERMISSION_GRANTED) {
4385                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4386                } else {
4387                    throw new SecurityException("PID " + pid + " does not have permission "
4388                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4389                                    + " of package " + packageName);
4390                }
4391            }
4392
4393            try {
4394                // Clear application user data
4395                pm.clearApplicationUserData(packageName, observer, userId);
4396
4397                // Remove all permissions granted from/to this package
4398                removeUriPermissionsForPackageLocked(packageName, userId, true);
4399
4400                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4401                        Uri.fromParts("package", packageName, null));
4402                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4403                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4404                        null, null, 0, null, null, null, false, false, userId);
4405            } catch (RemoteException e) {
4406            }
4407        } finally {
4408            Binder.restoreCallingIdentity(callingId);
4409        }
4410        return true;
4411    }
4412
4413    @Override
4414    public void killBackgroundProcesses(final String packageName, int userId) {
4415        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4416                != PackageManager.PERMISSION_GRANTED &&
4417                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4418                        != PackageManager.PERMISSION_GRANTED) {
4419            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4420                    + Binder.getCallingPid()
4421                    + ", uid=" + Binder.getCallingUid()
4422                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4423            Slog.w(TAG, msg);
4424            throw new SecurityException(msg);
4425        }
4426
4427        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4428                userId, true, true, "killBackgroundProcesses", null);
4429        long callingId = Binder.clearCallingIdentity();
4430        try {
4431            IPackageManager pm = AppGlobals.getPackageManager();
4432            synchronized(this) {
4433                int appId = -1;
4434                try {
4435                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4436                } catch (RemoteException e) {
4437                }
4438                if (appId == -1) {
4439                    Slog.w(TAG, "Invalid packageName: " + packageName);
4440                    return;
4441                }
4442                killPackageProcessesLocked(packageName, appId, userId,
4443                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4444            }
4445        } finally {
4446            Binder.restoreCallingIdentity(callingId);
4447        }
4448    }
4449
4450    @Override
4451    public void killAllBackgroundProcesses() {
4452        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4453                != PackageManager.PERMISSION_GRANTED) {
4454            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4455                    + Binder.getCallingPid()
4456                    + ", uid=" + Binder.getCallingUid()
4457                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4458            Slog.w(TAG, msg);
4459            throw new SecurityException(msg);
4460        }
4461
4462        long callingId = Binder.clearCallingIdentity();
4463        try {
4464            synchronized(this) {
4465                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4466                final int NP = mProcessNames.getMap().size();
4467                for (int ip=0; ip<NP; ip++) {
4468                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4469                    final int NA = apps.size();
4470                    for (int ia=0; ia<NA; ia++) {
4471                        ProcessRecord app = apps.valueAt(ia);
4472                        if (app.persistent) {
4473                            // we don't kill persistent processes
4474                            continue;
4475                        }
4476                        if (app.removed) {
4477                            procs.add(app);
4478                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4479                            app.removed = true;
4480                            procs.add(app);
4481                        }
4482                    }
4483                }
4484
4485                int N = procs.size();
4486                for (int i=0; i<N; i++) {
4487                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4488                }
4489                mAllowLowerMemLevel = true;
4490                updateOomAdjLocked();
4491                doLowMemReportIfNeededLocked(null);
4492            }
4493        } finally {
4494            Binder.restoreCallingIdentity(callingId);
4495        }
4496    }
4497
4498    @Override
4499    public void forceStopPackage(final String packageName, int userId) {
4500        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4501                != PackageManager.PERMISSION_GRANTED) {
4502            String msg = "Permission Denial: forceStopPackage() from pid="
4503                    + Binder.getCallingPid()
4504                    + ", uid=" + Binder.getCallingUid()
4505                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4506            Slog.w(TAG, msg);
4507            throw new SecurityException(msg);
4508        }
4509        final int callingPid = Binder.getCallingPid();
4510        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4511                userId, true, true, "forceStopPackage", null);
4512        long callingId = Binder.clearCallingIdentity();
4513        try {
4514            IPackageManager pm = AppGlobals.getPackageManager();
4515            synchronized(this) {
4516                int[] users = userId == UserHandle.USER_ALL
4517                        ? getUsersLocked() : new int[] { userId };
4518                for (int user : users) {
4519                    int pkgUid = -1;
4520                    try {
4521                        pkgUid = pm.getPackageUid(packageName, user);
4522                    } catch (RemoteException e) {
4523                    }
4524                    if (pkgUid == -1) {
4525                        Slog.w(TAG, "Invalid packageName: " + packageName);
4526                        continue;
4527                    }
4528                    try {
4529                        pm.setPackageStoppedState(packageName, true, user);
4530                    } catch (RemoteException e) {
4531                    } catch (IllegalArgumentException e) {
4532                        Slog.w(TAG, "Failed trying to unstop package "
4533                                + packageName + ": " + e);
4534                    }
4535                    if (isUserRunningLocked(user, false)) {
4536                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4537                    }
4538                }
4539            }
4540        } finally {
4541            Binder.restoreCallingIdentity(callingId);
4542        }
4543    }
4544
4545    /*
4546     * The pkg name and app id have to be specified.
4547     */
4548    @Override
4549    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4550        if (pkg == null) {
4551            return;
4552        }
4553        // Make sure the uid is valid.
4554        if (appid < 0) {
4555            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4556            return;
4557        }
4558        int callerUid = Binder.getCallingUid();
4559        // Only the system server can kill an application
4560        if (callerUid == Process.SYSTEM_UID) {
4561            // Post an aysnc message to kill the application
4562            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4563            msg.arg1 = appid;
4564            msg.arg2 = 0;
4565            Bundle bundle = new Bundle();
4566            bundle.putString("pkg", pkg);
4567            bundle.putString("reason", reason);
4568            msg.obj = bundle;
4569            mHandler.sendMessage(msg);
4570        } else {
4571            throw new SecurityException(callerUid + " cannot kill pkg: " +
4572                    pkg);
4573        }
4574    }
4575
4576    @Override
4577    public void closeSystemDialogs(String reason) {
4578        enforceNotIsolatedCaller("closeSystemDialogs");
4579
4580        final int pid = Binder.getCallingPid();
4581        final int uid = Binder.getCallingUid();
4582        final long origId = Binder.clearCallingIdentity();
4583        try {
4584            synchronized (this) {
4585                // Only allow this from foreground processes, so that background
4586                // applications can't abuse it to prevent system UI from being shown.
4587                if (uid >= Process.FIRST_APPLICATION_UID) {
4588                    ProcessRecord proc;
4589                    synchronized (mPidsSelfLocked) {
4590                        proc = mPidsSelfLocked.get(pid);
4591                    }
4592                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4593                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4594                                + " from background process " + proc);
4595                        return;
4596                    }
4597                }
4598                closeSystemDialogsLocked(reason);
4599            }
4600        } finally {
4601            Binder.restoreCallingIdentity(origId);
4602        }
4603    }
4604
4605    void closeSystemDialogsLocked(String reason) {
4606        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4607        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4608                | Intent.FLAG_RECEIVER_FOREGROUND);
4609        if (reason != null) {
4610            intent.putExtra("reason", reason);
4611        }
4612        mWindowManager.closeSystemDialogs(reason);
4613
4614        mStackSupervisor.closeSystemDialogsLocked();
4615
4616        broadcastIntentLocked(null, null, intent, null,
4617                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4618                Process.SYSTEM_UID, UserHandle.USER_ALL);
4619    }
4620
4621    @Override
4622    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4623        enforceNotIsolatedCaller("getProcessMemoryInfo");
4624        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4625        for (int i=pids.length-1; i>=0; i--) {
4626            ProcessRecord proc;
4627            int oomAdj;
4628            synchronized (this) {
4629                synchronized (mPidsSelfLocked) {
4630                    proc = mPidsSelfLocked.get(pids[i]);
4631                    oomAdj = proc != null ? proc.setAdj : 0;
4632                }
4633            }
4634            infos[i] = new Debug.MemoryInfo();
4635            Debug.getMemoryInfo(pids[i], infos[i]);
4636            if (proc != null) {
4637                synchronized (this) {
4638                    if (proc.thread != null && proc.setAdj == oomAdj) {
4639                        // Record this for posterity if the process has been stable.
4640                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4641                                infos[i].getTotalUss(), false, proc.pkgList);
4642                    }
4643                }
4644            }
4645        }
4646        return infos;
4647    }
4648
4649    @Override
4650    public long[] getProcessPss(int[] pids) {
4651        enforceNotIsolatedCaller("getProcessPss");
4652        long[] pss = new long[pids.length];
4653        for (int i=pids.length-1; i>=0; i--) {
4654            ProcessRecord proc;
4655            int oomAdj;
4656            synchronized (this) {
4657                synchronized (mPidsSelfLocked) {
4658                    proc = mPidsSelfLocked.get(pids[i]);
4659                    oomAdj = proc != null ? proc.setAdj : 0;
4660                }
4661            }
4662            long[] tmpUss = new long[1];
4663            pss[i] = Debug.getPss(pids[i], tmpUss);
4664            if (proc != null) {
4665                synchronized (this) {
4666                    if (proc.thread != null && proc.setAdj == oomAdj) {
4667                        // Record this for posterity if the process has been stable.
4668                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4669                    }
4670                }
4671            }
4672        }
4673        return pss;
4674    }
4675
4676    @Override
4677    public void killApplicationProcess(String processName, int uid) {
4678        if (processName == null) {
4679            return;
4680        }
4681
4682        int callerUid = Binder.getCallingUid();
4683        // Only the system server can kill an application
4684        if (callerUid == Process.SYSTEM_UID) {
4685            synchronized (this) {
4686                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4687                if (app != null && app.thread != null) {
4688                    try {
4689                        app.thread.scheduleSuicide();
4690                    } catch (RemoteException e) {
4691                        // If the other end already died, then our work here is done.
4692                    }
4693                } else {
4694                    Slog.w(TAG, "Process/uid not found attempting kill of "
4695                            + processName + " / " + uid);
4696                }
4697            }
4698        } else {
4699            throw new SecurityException(callerUid + " cannot kill app process: " +
4700                    processName);
4701        }
4702    }
4703
4704    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4705        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4706                false, true, false, false, UserHandle.getUserId(uid), reason);
4707        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4708                Uri.fromParts("package", packageName, null));
4709        if (!mProcessesReady) {
4710            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4711                    | Intent.FLAG_RECEIVER_FOREGROUND);
4712        }
4713        intent.putExtra(Intent.EXTRA_UID, uid);
4714        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4715        broadcastIntentLocked(null, null, intent,
4716                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4717                false, false,
4718                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4719    }
4720
4721    private void forceStopUserLocked(int userId, String reason) {
4722        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4723        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4724        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4725                | Intent.FLAG_RECEIVER_FOREGROUND);
4726        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4727        broadcastIntentLocked(null, null, intent,
4728                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4729                false, false,
4730                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4731    }
4732
4733    private final boolean killPackageProcessesLocked(String packageName, int appId,
4734            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4735            boolean doit, boolean evenPersistent, String reason) {
4736        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4737
4738        // Remove all processes this package may have touched: all with the
4739        // same UID (except for the system or root user), and all whose name
4740        // matches the package name.
4741        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4742        final int NP = mProcessNames.getMap().size();
4743        for (int ip=0; ip<NP; ip++) {
4744            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4745            final int NA = apps.size();
4746            for (int ia=0; ia<NA; ia++) {
4747                ProcessRecord app = apps.valueAt(ia);
4748                if (app.persistent && !evenPersistent) {
4749                    // we don't kill persistent processes
4750                    continue;
4751                }
4752                if (app.removed) {
4753                    if (doit) {
4754                        procs.add(app);
4755                    }
4756                    continue;
4757                }
4758
4759                // Skip process if it doesn't meet our oom adj requirement.
4760                if (app.setAdj < minOomAdj) {
4761                    continue;
4762                }
4763
4764                // If no package is specified, we call all processes under the
4765                // give user id.
4766                if (packageName == null) {
4767                    if (app.userId != userId) {
4768                        continue;
4769                    }
4770                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4771                        continue;
4772                    }
4773                // Package has been specified, we want to hit all processes
4774                // that match it.  We need to qualify this by the processes
4775                // that are running under the specified app and user ID.
4776                } else {
4777                    if (UserHandle.getAppId(app.uid) != appId) {
4778                        continue;
4779                    }
4780                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4781                        continue;
4782                    }
4783                    if (!app.pkgList.containsKey(packageName)) {
4784                        continue;
4785                    }
4786                }
4787
4788                // Process has passed all conditions, kill it!
4789                if (!doit) {
4790                    return true;
4791                }
4792                app.removed = true;
4793                procs.add(app);
4794            }
4795        }
4796
4797        int N = procs.size();
4798        for (int i=0; i<N; i++) {
4799            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4800        }
4801        updateOomAdjLocked();
4802        return N > 0;
4803    }
4804
4805    private final boolean forceStopPackageLocked(String name, int appId,
4806            boolean callerWillRestart, boolean purgeCache, boolean doit,
4807            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4808        int i;
4809        int N;
4810
4811        if (userId == UserHandle.USER_ALL && name == null) {
4812            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4813        }
4814
4815        if (appId < 0 && name != null) {
4816            try {
4817                appId = UserHandle.getAppId(
4818                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4819            } catch (RemoteException e) {
4820            }
4821        }
4822
4823        if (doit) {
4824            if (name != null) {
4825                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4826                        + " user=" + userId + ": " + reason);
4827            } else {
4828                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4829            }
4830
4831            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4832            for (int ip=pmap.size()-1; ip>=0; ip--) {
4833                SparseArray<Long> ba = pmap.valueAt(ip);
4834                for (i=ba.size()-1; i>=0; i--) {
4835                    boolean remove = false;
4836                    final int entUid = ba.keyAt(i);
4837                    if (name != null) {
4838                        if (userId == UserHandle.USER_ALL) {
4839                            if (UserHandle.getAppId(entUid) == appId) {
4840                                remove = true;
4841                            }
4842                        } else {
4843                            if (entUid == UserHandle.getUid(userId, appId)) {
4844                                remove = true;
4845                            }
4846                        }
4847                    } else if (UserHandle.getUserId(entUid) == userId) {
4848                        remove = true;
4849                    }
4850                    if (remove) {
4851                        ba.removeAt(i);
4852                    }
4853                }
4854                if (ba.size() == 0) {
4855                    pmap.removeAt(ip);
4856                }
4857            }
4858        }
4859
4860        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4861                -100, callerWillRestart, true, doit, evenPersistent,
4862                name == null ? ("stop user " + userId) : ("stop " + name));
4863
4864        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4865            if (!doit) {
4866                return true;
4867            }
4868            didSomething = true;
4869        }
4870
4871        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4872            if (!doit) {
4873                return true;
4874            }
4875            didSomething = true;
4876        }
4877
4878        if (name == null) {
4879            // Remove all sticky broadcasts from this user.
4880            mStickyBroadcasts.remove(userId);
4881        }
4882
4883        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4884        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4885                userId, providers)) {
4886            if (!doit) {
4887                return true;
4888            }
4889            didSomething = true;
4890        }
4891        N = providers.size();
4892        for (i=0; i<N; i++) {
4893            removeDyingProviderLocked(null, providers.get(i), true);
4894        }
4895
4896        // Remove transient permissions granted from/to this package/user
4897        removeUriPermissionsForPackageLocked(name, userId, false);
4898
4899        if (name == null || uninstalling) {
4900            // Remove pending intents.  For now we only do this when force
4901            // stopping users, because we have some problems when doing this
4902            // for packages -- app widgets are not currently cleaned up for
4903            // such packages, so they can be left with bad pending intents.
4904            if (mIntentSenderRecords.size() > 0) {
4905                Iterator<WeakReference<PendingIntentRecord>> it
4906                        = mIntentSenderRecords.values().iterator();
4907                while (it.hasNext()) {
4908                    WeakReference<PendingIntentRecord> wpir = it.next();
4909                    if (wpir == null) {
4910                        it.remove();
4911                        continue;
4912                    }
4913                    PendingIntentRecord pir = wpir.get();
4914                    if (pir == null) {
4915                        it.remove();
4916                        continue;
4917                    }
4918                    if (name == null) {
4919                        // Stopping user, remove all objects for the user.
4920                        if (pir.key.userId != userId) {
4921                            // Not the same user, skip it.
4922                            continue;
4923                        }
4924                    } else {
4925                        if (UserHandle.getAppId(pir.uid) != appId) {
4926                            // Different app id, skip it.
4927                            continue;
4928                        }
4929                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4930                            // Different user, skip it.
4931                            continue;
4932                        }
4933                        if (!pir.key.packageName.equals(name)) {
4934                            // Different package, skip it.
4935                            continue;
4936                        }
4937                    }
4938                    if (!doit) {
4939                        return true;
4940                    }
4941                    didSomething = true;
4942                    it.remove();
4943                    pir.canceled = true;
4944                    if (pir.key.activity != null) {
4945                        pir.key.activity.pendingResults.remove(pir.ref);
4946                    }
4947                }
4948            }
4949        }
4950
4951        if (doit) {
4952            if (purgeCache && name != null) {
4953                AttributeCache ac = AttributeCache.instance();
4954                if (ac != null) {
4955                    ac.removePackage(name);
4956                }
4957            }
4958            if (mBooted) {
4959                mStackSupervisor.resumeTopActivitiesLocked();
4960                mStackSupervisor.scheduleIdleLocked();
4961            }
4962        }
4963
4964        return didSomething;
4965    }
4966
4967    private final boolean removeProcessLocked(ProcessRecord app,
4968            boolean callerWillRestart, boolean allowRestart, String reason) {
4969        final String name = app.processName;
4970        final int uid = app.uid;
4971        if (DEBUG_PROCESSES) Slog.d(
4972            TAG, "Force removing proc " + app.toShortString() + " (" + name
4973            + "/" + uid + ")");
4974
4975        mProcessNames.remove(name, uid);
4976        mIsolatedProcesses.remove(app.uid);
4977        if (mHeavyWeightProcess == app) {
4978            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4979                    mHeavyWeightProcess.userId, 0));
4980            mHeavyWeightProcess = null;
4981        }
4982        boolean needRestart = false;
4983        if (app.pid > 0 && app.pid != MY_PID) {
4984            int pid = app.pid;
4985            synchronized (mPidsSelfLocked) {
4986                mPidsSelfLocked.remove(pid);
4987                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4988            }
4989            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
4990                    app.processName, app.info.uid);
4991            if (app.isolated) {
4992                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
4993            }
4994            killUnneededProcessLocked(app, reason);
4995            handleAppDiedLocked(app, true, allowRestart);
4996            removeLruProcessLocked(app);
4997
4998            if (app.persistent && !app.isolated) {
4999                if (!callerWillRestart) {
5000                    addAppLocked(app.info, false);
5001                } else {
5002                    needRestart = true;
5003                }
5004            }
5005        } else {
5006            mRemovedProcesses.add(app);
5007        }
5008
5009        return needRestart;
5010    }
5011
5012    private final void processStartTimedOutLocked(ProcessRecord app) {
5013        final int pid = app.pid;
5014        boolean gone = false;
5015        synchronized (mPidsSelfLocked) {
5016            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5017            if (knownApp != null && knownApp.thread == null) {
5018                mPidsSelfLocked.remove(pid);
5019                gone = true;
5020            }
5021        }
5022
5023        if (gone) {
5024            Slog.w(TAG, "Process " + app + " failed to attach");
5025            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5026                    pid, app.uid, app.processName);
5027            mProcessNames.remove(app.processName, app.uid);
5028            mIsolatedProcesses.remove(app.uid);
5029            if (mHeavyWeightProcess == app) {
5030                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5031                        mHeavyWeightProcess.userId, 0));
5032                mHeavyWeightProcess = null;
5033            }
5034            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5035                    app.processName, app.info.uid);
5036            if (app.isolated) {
5037                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5038            }
5039            // Take care of any launching providers waiting for this process.
5040            checkAppInLaunchingProvidersLocked(app, true);
5041            // Take care of any services that are waiting for the process.
5042            mServices.processStartTimedOutLocked(app);
5043            killUnneededProcessLocked(app, "start timeout");
5044            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5045                Slog.w(TAG, "Unattached app died before backup, skipping");
5046                try {
5047                    IBackupManager bm = IBackupManager.Stub.asInterface(
5048                            ServiceManager.getService(Context.BACKUP_SERVICE));
5049                    bm.agentDisconnected(app.info.packageName);
5050                } catch (RemoteException e) {
5051                    // Can't happen; the backup manager is local
5052                }
5053            }
5054            if (isPendingBroadcastProcessLocked(pid)) {
5055                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5056                skipPendingBroadcastLocked(pid);
5057            }
5058        } else {
5059            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5060        }
5061    }
5062
5063    private final boolean attachApplicationLocked(IApplicationThread thread,
5064            int pid) {
5065
5066        // Find the application record that is being attached...  either via
5067        // the pid if we are running in multiple processes, or just pull the
5068        // next app record if we are emulating process with anonymous threads.
5069        ProcessRecord app;
5070        if (pid != MY_PID && pid >= 0) {
5071            synchronized (mPidsSelfLocked) {
5072                app = mPidsSelfLocked.get(pid);
5073            }
5074        } else {
5075            app = null;
5076        }
5077
5078        if (app == null) {
5079            Slog.w(TAG, "No pending application record for pid " + pid
5080                    + " (IApplicationThread " + thread + "); dropping process");
5081            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5082            if (pid > 0 && pid != MY_PID) {
5083                Process.killProcessQuiet(pid);
5084            } else {
5085                try {
5086                    thread.scheduleExit();
5087                } catch (Exception e) {
5088                    // Ignore exceptions.
5089                }
5090            }
5091            return false;
5092        }
5093
5094        // If this application record is still attached to a previous
5095        // process, clean it up now.
5096        if (app.thread != null) {
5097            handleAppDiedLocked(app, true, true);
5098        }
5099
5100        // Tell the process all about itself.
5101
5102        if (localLOGV) Slog.v(
5103                TAG, "Binding process pid " + pid + " to record " + app);
5104
5105        final String processName = app.processName;
5106        try {
5107            AppDeathRecipient adr = new AppDeathRecipient(
5108                    app, pid, thread);
5109            thread.asBinder().linkToDeath(adr, 0);
5110            app.deathRecipient = adr;
5111        } catch (RemoteException e) {
5112            app.resetPackageList(mProcessStats);
5113            startProcessLocked(app, "link fail", processName);
5114            return false;
5115        }
5116
5117        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5118
5119        app.makeActive(thread, mProcessStats);
5120        app.curAdj = app.setAdj = -100;
5121        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5122        app.forcingToForeground = null;
5123        updateProcessForegroundLocked(app, false, false);
5124        app.hasShownUi = false;
5125        app.debugging = false;
5126        app.cached = false;
5127
5128        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5129
5130        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5131        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5132
5133        if (!normalMode) {
5134            Slog.i(TAG, "Launching preboot mode app: " + app);
5135        }
5136
5137        if (localLOGV) Slog.v(
5138            TAG, "New app record " + app
5139            + " thread=" + thread.asBinder() + " pid=" + pid);
5140        try {
5141            int testMode = IApplicationThread.DEBUG_OFF;
5142            if (mDebugApp != null && mDebugApp.equals(processName)) {
5143                testMode = mWaitForDebugger
5144                    ? IApplicationThread.DEBUG_WAIT
5145                    : IApplicationThread.DEBUG_ON;
5146                app.debugging = true;
5147                if (mDebugTransient) {
5148                    mDebugApp = mOrigDebugApp;
5149                    mWaitForDebugger = mOrigWaitForDebugger;
5150                }
5151            }
5152            String profileFile = app.instrumentationProfileFile;
5153            ParcelFileDescriptor profileFd = null;
5154            boolean profileAutoStop = false;
5155            if (mProfileApp != null && mProfileApp.equals(processName)) {
5156                mProfileProc = app;
5157                profileFile = mProfileFile;
5158                profileFd = mProfileFd;
5159                profileAutoStop = mAutoStopProfiler;
5160            }
5161            boolean enableOpenGlTrace = false;
5162            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5163                enableOpenGlTrace = true;
5164                mOpenGlTraceApp = null;
5165            }
5166
5167            // If the app is being launched for restore or full backup, set it up specially
5168            boolean isRestrictedBackupMode = false;
5169            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5170                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5171                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5172                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5173            }
5174
5175            ensurePackageDexOpt(app.instrumentationInfo != null
5176                    ? app.instrumentationInfo.packageName
5177                    : app.info.packageName);
5178            if (app.instrumentationClass != null) {
5179                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5180            }
5181            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5182                    + processName + " with config " + mConfiguration);
5183            ApplicationInfo appInfo = app.instrumentationInfo != null
5184                    ? app.instrumentationInfo : app.info;
5185            app.compat = compatibilityInfoForPackageLocked(appInfo);
5186            if (profileFd != null) {
5187                profileFd = profileFd.dup();
5188            }
5189            thread.bindApplication(processName, appInfo, providers,
5190                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5191                    app.instrumentationArguments, app.instrumentationWatcher,
5192                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5193                    isRestrictedBackupMode || !normalMode, app.persistent,
5194                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5195                    mCoreSettingsObserver.getCoreSettingsLocked());
5196            updateLruProcessLocked(app, false, null);
5197            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5198        } catch (Exception e) {
5199            // todo: Yikes!  What should we do?  For now we will try to
5200            // start another process, but that could easily get us in
5201            // an infinite loop of restarting processes...
5202            Slog.w(TAG, "Exception thrown during bind!", e);
5203
5204            app.resetPackageList(mProcessStats);
5205            app.unlinkDeathRecipient();
5206            startProcessLocked(app, "bind fail", processName);
5207            return false;
5208        }
5209
5210        // Remove this record from the list of starting applications.
5211        mPersistentStartingProcesses.remove(app);
5212        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5213                "Attach application locked removing on hold: " + app);
5214        mProcessesOnHold.remove(app);
5215
5216        boolean badApp = false;
5217        boolean didSomething = false;
5218
5219        // See if the top visible activity is waiting to run in this process...
5220        if (normalMode) {
5221            try {
5222                if (mStackSupervisor.attachApplicationLocked(app)) {
5223                    didSomething = true;
5224                }
5225            } catch (Exception e) {
5226                badApp = true;
5227            }
5228        }
5229
5230        // Find any services that should be running in this process...
5231        if (!badApp) {
5232            try {
5233                didSomething |= mServices.attachApplicationLocked(app, processName);
5234            } catch (Exception e) {
5235                badApp = true;
5236            }
5237        }
5238
5239        // Check if a next-broadcast receiver is in this process...
5240        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5241            try {
5242                didSomething |= sendPendingBroadcastsLocked(app);
5243            } catch (Exception e) {
5244                // If the app died trying to launch the receiver we declare it 'bad'
5245                badApp = true;
5246            }
5247        }
5248
5249        // Check whether the next backup agent is in this process...
5250        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5251            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5252            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5253            try {
5254                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5255                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5256                        mBackupTarget.backupMode);
5257            } catch (Exception e) {
5258                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5259                e.printStackTrace();
5260            }
5261        }
5262
5263        if (badApp) {
5264            // todo: Also need to kill application to deal with all
5265            // kinds of exceptions.
5266            handleAppDiedLocked(app, false, true);
5267            return false;
5268        }
5269
5270        if (!didSomething) {
5271            updateOomAdjLocked();
5272        }
5273
5274        return true;
5275    }
5276
5277    @Override
5278    public final void attachApplication(IApplicationThread thread) {
5279        synchronized (this) {
5280            int callingPid = Binder.getCallingPid();
5281            final long origId = Binder.clearCallingIdentity();
5282            attachApplicationLocked(thread, callingPid);
5283            Binder.restoreCallingIdentity(origId);
5284        }
5285    }
5286
5287    @Override
5288    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5289        final long origId = Binder.clearCallingIdentity();
5290        synchronized (this) {
5291            ActivityStack stack = ActivityRecord.getStackLocked(token);
5292            if (stack != null) {
5293                ActivityRecord r =
5294                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5295                if (stopProfiling) {
5296                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5297                        try {
5298                            mProfileFd.close();
5299                        } catch (IOException e) {
5300                        }
5301                        clearProfilerLocked();
5302                    }
5303                }
5304            }
5305        }
5306        Binder.restoreCallingIdentity(origId);
5307    }
5308
5309    void enableScreenAfterBoot() {
5310        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5311                SystemClock.uptimeMillis());
5312        mWindowManager.enableScreenAfterBoot();
5313
5314        synchronized (this) {
5315            updateEventDispatchingLocked();
5316        }
5317    }
5318
5319    @Override
5320    public void showBootMessage(final CharSequence msg, final boolean always) {
5321        enforceNotIsolatedCaller("showBootMessage");
5322        mWindowManager.showBootMessage(msg, always);
5323    }
5324
5325    @Override
5326    public void dismissKeyguardOnNextActivity() {
5327        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5328        final long token = Binder.clearCallingIdentity();
5329        try {
5330            synchronized (this) {
5331                if (DEBUG_LOCKSCREEN) logLockScreen("");
5332                if (mLockScreenShown) {
5333                    mLockScreenShown = false;
5334                    comeOutOfSleepIfNeededLocked();
5335                }
5336                mStackSupervisor.setDismissKeyguard(true);
5337            }
5338        } finally {
5339            Binder.restoreCallingIdentity(token);
5340        }
5341    }
5342
5343    final void finishBooting() {
5344        // Register receivers to handle package update events
5345        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5346
5347        synchronized (this) {
5348            // Ensure that any processes we had put on hold are now started
5349            // up.
5350            final int NP = mProcessesOnHold.size();
5351            if (NP > 0) {
5352                ArrayList<ProcessRecord> procs =
5353                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5354                for (int ip=0; ip<NP; ip++) {
5355                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5356                            + procs.get(ip));
5357                    startProcessLocked(procs.get(ip), "on-hold", null);
5358                }
5359            }
5360
5361            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5362                // Start looking for apps that are abusing wake locks.
5363                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5364                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5365                // Tell anyone interested that we are done booting!
5366                SystemProperties.set("sys.boot_completed", "1");
5367                SystemProperties.set("dev.bootcomplete", "1");
5368                for (int i=0; i<mStartedUsers.size(); i++) {
5369                    UserStartedState uss = mStartedUsers.valueAt(i);
5370                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5371                        uss.mState = UserStartedState.STATE_RUNNING;
5372                        final int userId = mStartedUsers.keyAt(i);
5373                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5374                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5375                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5376                        broadcastIntentLocked(null, null, intent, null,
5377                                new IIntentReceiver.Stub() {
5378                                    @Override
5379                                    public void performReceive(Intent intent, int resultCode,
5380                                            String data, Bundle extras, boolean ordered,
5381                                            boolean sticky, int sendingUser) {
5382                                        synchronized (ActivityManagerService.this) {
5383                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5384                                                    true, false);
5385                                        }
5386                                    }
5387                                },
5388                                0, null, null,
5389                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5390                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5391                                userId);
5392                    }
5393                }
5394                scheduleStartProfilesLocked();
5395            }
5396        }
5397    }
5398
5399    final void ensureBootCompleted() {
5400        boolean booting;
5401        boolean enableScreen;
5402        synchronized (this) {
5403            booting = mBooting;
5404            mBooting = false;
5405            enableScreen = !mBooted;
5406            mBooted = true;
5407        }
5408
5409        if (booting) {
5410            finishBooting();
5411        }
5412
5413        if (enableScreen) {
5414            enableScreenAfterBoot();
5415        }
5416    }
5417
5418    @Override
5419    public final void activityResumed(IBinder token) {
5420        final long origId = Binder.clearCallingIdentity();
5421        synchronized(this) {
5422            ActivityStack stack = ActivityRecord.getStackLocked(token);
5423            if (stack != null) {
5424                ActivityRecord.activityResumedLocked(token);
5425            }
5426        }
5427        Binder.restoreCallingIdentity(origId);
5428    }
5429
5430    @Override
5431    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5432        final long origId = Binder.clearCallingIdentity();
5433        synchronized(this) {
5434            ActivityStack stack = ActivityRecord.getStackLocked(token);
5435            if (stack != null) {
5436                stack.activityPausedLocked(token, false, persistentState);
5437            }
5438        }
5439        Binder.restoreCallingIdentity(origId);
5440    }
5441
5442    @Override
5443    public final void activityStopped(IBinder token, Bundle icicle,
5444            PersistableBundle persistentState, CharSequence description) {
5445        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5446
5447        // Refuse possible leaked file descriptors
5448        if (icicle != null && icicle.hasFileDescriptors()) {
5449            throw new IllegalArgumentException("File descriptors passed in Bundle");
5450        }
5451
5452        final long origId = Binder.clearCallingIdentity();
5453
5454        synchronized (this) {
5455            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5456            if (r != null) {
5457                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5458            }
5459        }
5460
5461        trimApplications();
5462
5463        Binder.restoreCallingIdentity(origId);
5464    }
5465
5466    @Override
5467    public final void activityDestroyed(IBinder token) {
5468        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5469        synchronized (this) {
5470            ActivityStack stack = ActivityRecord.getStackLocked(token);
5471            if (stack != null) {
5472                stack.activityDestroyedLocked(token);
5473            }
5474        }
5475    }
5476
5477    @Override
5478    public String getCallingPackage(IBinder token) {
5479        synchronized (this) {
5480            ActivityRecord r = getCallingRecordLocked(token);
5481            return r != null ? r.info.packageName : null;
5482        }
5483    }
5484
5485    @Override
5486    public ComponentName getCallingActivity(IBinder token) {
5487        synchronized (this) {
5488            ActivityRecord r = getCallingRecordLocked(token);
5489            return r != null ? r.intent.getComponent() : null;
5490        }
5491    }
5492
5493    private ActivityRecord getCallingRecordLocked(IBinder token) {
5494        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5495        if (r == null) {
5496            return null;
5497        }
5498        return r.resultTo;
5499    }
5500
5501    @Override
5502    public ComponentName getActivityClassForToken(IBinder token) {
5503        synchronized(this) {
5504            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5505            if (r == null) {
5506                return null;
5507            }
5508            return r.intent.getComponent();
5509        }
5510    }
5511
5512    @Override
5513    public String getPackageForToken(IBinder token) {
5514        synchronized(this) {
5515            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5516            if (r == null) {
5517                return null;
5518            }
5519            return r.packageName;
5520        }
5521    }
5522
5523    @Override
5524    public IIntentSender getIntentSender(int type,
5525            String packageName, IBinder token, String resultWho,
5526            int requestCode, Intent[] intents, String[] resolvedTypes,
5527            int flags, Bundle options, int userId) {
5528        enforceNotIsolatedCaller("getIntentSender");
5529        // Refuse possible leaked file descriptors
5530        if (intents != null) {
5531            if (intents.length < 1) {
5532                throw new IllegalArgumentException("Intents array length must be >= 1");
5533            }
5534            for (int i=0; i<intents.length; i++) {
5535                Intent intent = intents[i];
5536                if (intent != null) {
5537                    if (intent.hasFileDescriptors()) {
5538                        throw new IllegalArgumentException("File descriptors passed in Intent");
5539                    }
5540                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5541                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5542                        throw new IllegalArgumentException(
5543                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5544                    }
5545                    intents[i] = new Intent(intent);
5546                }
5547            }
5548            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5549                throw new IllegalArgumentException(
5550                        "Intent array length does not match resolvedTypes length");
5551            }
5552        }
5553        if (options != null) {
5554            if (options.hasFileDescriptors()) {
5555                throw new IllegalArgumentException("File descriptors passed in options");
5556            }
5557        }
5558
5559        synchronized(this) {
5560            int callingUid = Binder.getCallingUid();
5561            int origUserId = userId;
5562            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5563                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5564                    "getIntentSender", null);
5565            if (origUserId == UserHandle.USER_CURRENT) {
5566                // We don't want to evaluate this until the pending intent is
5567                // actually executed.  However, we do want to always do the
5568                // security checking for it above.
5569                userId = UserHandle.USER_CURRENT;
5570            }
5571            try {
5572                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5573                    int uid = AppGlobals.getPackageManager()
5574                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5575                    if (!UserHandle.isSameApp(callingUid, uid)) {
5576                        String msg = "Permission Denial: getIntentSender() from pid="
5577                            + Binder.getCallingPid()
5578                            + ", uid=" + Binder.getCallingUid()
5579                            + ", (need uid=" + uid + ")"
5580                            + " is not allowed to send as package " + packageName;
5581                        Slog.w(TAG, msg);
5582                        throw new SecurityException(msg);
5583                    }
5584                }
5585
5586                return getIntentSenderLocked(type, packageName, callingUid, userId,
5587                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5588
5589            } catch (RemoteException e) {
5590                throw new SecurityException(e);
5591            }
5592        }
5593    }
5594
5595    IIntentSender getIntentSenderLocked(int type, String packageName,
5596            int callingUid, int userId, IBinder token, String resultWho,
5597            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5598            Bundle options) {
5599        if (DEBUG_MU)
5600            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5601        ActivityRecord activity = null;
5602        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5603            activity = ActivityRecord.isInStackLocked(token);
5604            if (activity == null) {
5605                return null;
5606            }
5607            if (activity.finishing) {
5608                return null;
5609            }
5610        }
5611
5612        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5613        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5614        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5615        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5616                |PendingIntent.FLAG_UPDATE_CURRENT);
5617
5618        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5619                type, packageName, activity, resultWho,
5620                requestCode, intents, resolvedTypes, flags, options, userId);
5621        WeakReference<PendingIntentRecord> ref;
5622        ref = mIntentSenderRecords.get(key);
5623        PendingIntentRecord rec = ref != null ? ref.get() : null;
5624        if (rec != null) {
5625            if (!cancelCurrent) {
5626                if (updateCurrent) {
5627                    if (rec.key.requestIntent != null) {
5628                        rec.key.requestIntent.replaceExtras(intents != null ?
5629                                intents[intents.length - 1] : null);
5630                    }
5631                    if (intents != null) {
5632                        intents[intents.length-1] = rec.key.requestIntent;
5633                        rec.key.allIntents = intents;
5634                        rec.key.allResolvedTypes = resolvedTypes;
5635                    } else {
5636                        rec.key.allIntents = null;
5637                        rec.key.allResolvedTypes = null;
5638                    }
5639                }
5640                return rec;
5641            }
5642            rec.canceled = true;
5643            mIntentSenderRecords.remove(key);
5644        }
5645        if (noCreate) {
5646            return rec;
5647        }
5648        rec = new PendingIntentRecord(this, key, callingUid);
5649        mIntentSenderRecords.put(key, rec.ref);
5650        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5651            if (activity.pendingResults == null) {
5652                activity.pendingResults
5653                        = new HashSet<WeakReference<PendingIntentRecord>>();
5654            }
5655            activity.pendingResults.add(rec.ref);
5656        }
5657        return rec;
5658    }
5659
5660    @Override
5661    public void cancelIntentSender(IIntentSender sender) {
5662        if (!(sender instanceof PendingIntentRecord)) {
5663            return;
5664        }
5665        synchronized(this) {
5666            PendingIntentRecord rec = (PendingIntentRecord)sender;
5667            try {
5668                int uid = AppGlobals.getPackageManager()
5669                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5670                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5671                    String msg = "Permission Denial: cancelIntentSender() from pid="
5672                        + Binder.getCallingPid()
5673                        + ", uid=" + Binder.getCallingUid()
5674                        + " is not allowed to cancel packges "
5675                        + rec.key.packageName;
5676                    Slog.w(TAG, msg);
5677                    throw new SecurityException(msg);
5678                }
5679            } catch (RemoteException e) {
5680                throw new SecurityException(e);
5681            }
5682            cancelIntentSenderLocked(rec, true);
5683        }
5684    }
5685
5686    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5687        rec.canceled = true;
5688        mIntentSenderRecords.remove(rec.key);
5689        if (cleanActivity && rec.key.activity != null) {
5690            rec.key.activity.pendingResults.remove(rec.ref);
5691        }
5692    }
5693
5694    @Override
5695    public String getPackageForIntentSender(IIntentSender pendingResult) {
5696        if (!(pendingResult instanceof PendingIntentRecord)) {
5697            return null;
5698        }
5699        try {
5700            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5701            return res.key.packageName;
5702        } catch (ClassCastException e) {
5703        }
5704        return null;
5705    }
5706
5707    @Override
5708    public int getUidForIntentSender(IIntentSender sender) {
5709        if (sender instanceof PendingIntentRecord) {
5710            try {
5711                PendingIntentRecord res = (PendingIntentRecord)sender;
5712                return res.uid;
5713            } catch (ClassCastException e) {
5714            }
5715        }
5716        return -1;
5717    }
5718
5719    @Override
5720    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5721        if (!(pendingResult instanceof PendingIntentRecord)) {
5722            return false;
5723        }
5724        try {
5725            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5726            if (res.key.allIntents == null) {
5727                return false;
5728            }
5729            for (int i=0; i<res.key.allIntents.length; i++) {
5730                Intent intent = res.key.allIntents[i];
5731                if (intent.getPackage() != null && intent.getComponent() != null) {
5732                    return false;
5733                }
5734            }
5735            return true;
5736        } catch (ClassCastException e) {
5737        }
5738        return false;
5739    }
5740
5741    @Override
5742    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5743        if (!(pendingResult instanceof PendingIntentRecord)) {
5744            return false;
5745        }
5746        try {
5747            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5748            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5749                return true;
5750            }
5751            return false;
5752        } catch (ClassCastException e) {
5753        }
5754        return false;
5755    }
5756
5757    @Override
5758    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5759        if (!(pendingResult instanceof PendingIntentRecord)) {
5760            return null;
5761        }
5762        try {
5763            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5764            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5765        } catch (ClassCastException e) {
5766        }
5767        return null;
5768    }
5769
5770    @Override
5771    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5772        if (!(pendingResult instanceof PendingIntentRecord)) {
5773            return null;
5774        }
5775        try {
5776            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5777            Intent intent = res.key.requestIntent;
5778            if (intent != null) {
5779                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5780                        || res.lastTagPrefix.equals(prefix))) {
5781                    return res.lastTag;
5782                }
5783                res.lastTagPrefix = prefix;
5784                StringBuilder sb = new StringBuilder(128);
5785                if (prefix != null) {
5786                    sb.append(prefix);
5787                }
5788                if (intent.getAction() != null) {
5789                    sb.append(intent.getAction());
5790                } else if (intent.getComponent() != null) {
5791                    intent.getComponent().appendShortString(sb);
5792                } else {
5793                    sb.append("?");
5794                }
5795                return res.lastTag = sb.toString();
5796            }
5797        } catch (ClassCastException e) {
5798        }
5799        return null;
5800    }
5801
5802    @Override
5803    public void setProcessLimit(int max) {
5804        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5805                "setProcessLimit()");
5806        synchronized (this) {
5807            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5808            mProcessLimitOverride = max;
5809        }
5810        trimApplications();
5811    }
5812
5813    @Override
5814    public int getProcessLimit() {
5815        synchronized (this) {
5816            return mProcessLimitOverride;
5817        }
5818    }
5819
5820    void foregroundTokenDied(ForegroundToken token) {
5821        synchronized (ActivityManagerService.this) {
5822            synchronized (mPidsSelfLocked) {
5823                ForegroundToken cur
5824                    = mForegroundProcesses.get(token.pid);
5825                if (cur != token) {
5826                    return;
5827                }
5828                mForegroundProcesses.remove(token.pid);
5829                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5830                if (pr == null) {
5831                    return;
5832                }
5833                pr.forcingToForeground = null;
5834                updateProcessForegroundLocked(pr, false, false);
5835            }
5836            updateOomAdjLocked();
5837        }
5838    }
5839
5840    @Override
5841    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5842        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5843                "setProcessForeground()");
5844        synchronized(this) {
5845            boolean changed = false;
5846
5847            synchronized (mPidsSelfLocked) {
5848                ProcessRecord pr = mPidsSelfLocked.get(pid);
5849                if (pr == null && isForeground) {
5850                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5851                    return;
5852                }
5853                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5854                if (oldToken != null) {
5855                    oldToken.token.unlinkToDeath(oldToken, 0);
5856                    mForegroundProcesses.remove(pid);
5857                    if (pr != null) {
5858                        pr.forcingToForeground = null;
5859                    }
5860                    changed = true;
5861                }
5862                if (isForeground && token != null) {
5863                    ForegroundToken newToken = new ForegroundToken() {
5864                        @Override
5865                        public void binderDied() {
5866                            foregroundTokenDied(this);
5867                        }
5868                    };
5869                    newToken.pid = pid;
5870                    newToken.token = token;
5871                    try {
5872                        token.linkToDeath(newToken, 0);
5873                        mForegroundProcesses.put(pid, newToken);
5874                        pr.forcingToForeground = token;
5875                        changed = true;
5876                    } catch (RemoteException e) {
5877                        // If the process died while doing this, we will later
5878                        // do the cleanup with the process death link.
5879                    }
5880                }
5881            }
5882
5883            if (changed) {
5884                updateOomAdjLocked();
5885            }
5886        }
5887    }
5888
5889    // =========================================================
5890    // PERMISSIONS
5891    // =========================================================
5892
5893    static class PermissionController extends IPermissionController.Stub {
5894        ActivityManagerService mActivityManagerService;
5895        PermissionController(ActivityManagerService activityManagerService) {
5896            mActivityManagerService = activityManagerService;
5897        }
5898
5899        @Override
5900        public boolean checkPermission(String permission, int pid, int uid) {
5901            return mActivityManagerService.checkPermission(permission, pid,
5902                    uid) == PackageManager.PERMISSION_GRANTED;
5903        }
5904    }
5905
5906    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5907        @Override
5908        public int checkComponentPermission(String permission, int pid, int uid,
5909                int owningUid, boolean exported) {
5910            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5911                    owningUid, exported);
5912        }
5913
5914        @Override
5915        public Object getAMSLock() {
5916            return ActivityManagerService.this;
5917        }
5918    }
5919
5920    /**
5921     * This can be called with or without the global lock held.
5922     */
5923    int checkComponentPermission(String permission, int pid, int uid,
5924            int owningUid, boolean exported) {
5925        // We might be performing an operation on behalf of an indirect binder
5926        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5927        // client identity accordingly before proceeding.
5928        Identity tlsIdentity = sCallerIdentity.get();
5929        if (tlsIdentity != null) {
5930            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5931                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5932            uid = tlsIdentity.uid;
5933            pid = tlsIdentity.pid;
5934        }
5935
5936        if (pid == MY_PID) {
5937            return PackageManager.PERMISSION_GRANTED;
5938        }
5939
5940        return ActivityManager.checkComponentPermission(permission, uid,
5941                owningUid, exported);
5942    }
5943
5944    /**
5945     * As the only public entry point for permissions checking, this method
5946     * can enforce the semantic that requesting a check on a null global
5947     * permission is automatically denied.  (Internally a null permission
5948     * string is used when calling {@link #checkComponentPermission} in cases
5949     * when only uid-based security is needed.)
5950     *
5951     * This can be called with or without the global lock held.
5952     */
5953    @Override
5954    public int checkPermission(String permission, int pid, int uid) {
5955        if (permission == null) {
5956            return PackageManager.PERMISSION_DENIED;
5957        }
5958        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5959    }
5960
5961    /**
5962     * Binder IPC calls go through the public entry point.
5963     * This can be called with or without the global lock held.
5964     */
5965    int checkCallingPermission(String permission) {
5966        return checkPermission(permission,
5967                Binder.getCallingPid(),
5968                UserHandle.getAppId(Binder.getCallingUid()));
5969    }
5970
5971    /**
5972     * This can be called with or without the global lock held.
5973     */
5974    void enforceCallingPermission(String permission, String func) {
5975        if (checkCallingPermission(permission)
5976                == PackageManager.PERMISSION_GRANTED) {
5977            return;
5978        }
5979
5980        String msg = "Permission Denial: " + func + " from pid="
5981                + Binder.getCallingPid()
5982                + ", uid=" + Binder.getCallingUid()
5983                + " requires " + permission;
5984        Slog.w(TAG, msg);
5985        throw new SecurityException(msg);
5986    }
5987
5988    /**
5989     * Determine if UID is holding permissions required to access {@link Uri} in
5990     * the given {@link ProviderInfo}. Final permission checking is always done
5991     * in {@link ContentProvider}.
5992     */
5993    private final boolean checkHoldingPermissionsLocked(
5994            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, final int modeFlags) {
5995        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5996                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
5997
5998        if (pi.applicationInfo.uid == uid) {
5999            return true;
6000        } else if (!pi.exported) {
6001            return false;
6002        }
6003
6004        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6005        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6006        try {
6007            // check if target holds top-level <provider> permissions
6008            if (!readMet && pi.readPermission != null
6009                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6010                readMet = true;
6011            }
6012            if (!writeMet && pi.writePermission != null
6013                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6014                writeMet = true;
6015            }
6016
6017            // track if unprotected read/write is allowed; any denied
6018            // <path-permission> below removes this ability
6019            boolean allowDefaultRead = pi.readPermission == null;
6020            boolean allowDefaultWrite = pi.writePermission == null;
6021
6022            // check if target holds any <path-permission> that match uri
6023            final PathPermission[] pps = pi.pathPermissions;
6024            if (pps != null) {
6025                final String path = uri.getPath();
6026                int i = pps.length;
6027                while (i > 0 && (!readMet || !writeMet)) {
6028                    i--;
6029                    PathPermission pp = pps[i];
6030                    if (pp.match(path)) {
6031                        if (!readMet) {
6032                            final String pprperm = pp.getReadPermission();
6033                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6034                                    + pprperm + " for " + pp.getPath()
6035                                    + ": match=" + pp.match(path)
6036                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6037                            if (pprperm != null) {
6038                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
6039                                    readMet = true;
6040                                } else {
6041                                    allowDefaultRead = false;
6042                                }
6043                            }
6044                        }
6045                        if (!writeMet) {
6046                            final String ppwperm = pp.getWritePermission();
6047                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6048                                    + ppwperm + " for " + pp.getPath()
6049                                    + ": match=" + pp.match(path)
6050                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6051                            if (ppwperm != null) {
6052                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
6053                                    writeMet = true;
6054                                } else {
6055                                    allowDefaultWrite = false;
6056                                }
6057                            }
6058                        }
6059                    }
6060                }
6061            }
6062
6063            // grant unprotected <provider> read/write, if not blocked by
6064            // <path-permission> above
6065            if (allowDefaultRead) readMet = true;
6066            if (allowDefaultWrite) writeMet = true;
6067
6068        } catch (RemoteException e) {
6069            return false;
6070        }
6071
6072        return readMet && writeMet;
6073    }
6074
6075    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6076        ProviderInfo pi = null;
6077        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6078        if (cpr != null) {
6079            pi = cpr.info;
6080        } else {
6081            try {
6082                pi = AppGlobals.getPackageManager().resolveContentProvider(
6083                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6084            } catch (RemoteException ex) {
6085            }
6086        }
6087        return pi;
6088    }
6089
6090    private UriPermission findUriPermissionLocked(int targetUid, GrantUri uri) {
6091        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6092        if (targetUris != null) {
6093            return targetUris.get(uri);
6094        }
6095        return null;
6096    }
6097
6098    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6099            String targetPkg, int targetUid, GrantUri uri) {
6100        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6101        if (targetUris == null) {
6102            targetUris = Maps.newArrayMap();
6103            mGrantedUriPermissions.put(targetUid, targetUris);
6104        }
6105
6106        UriPermission perm = targetUris.get(uri);
6107        if (perm == null) {
6108            perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri);
6109            targetUris.put(uri, perm);
6110        }
6111
6112        return perm;
6113    }
6114
6115    private final boolean checkUriPermissionLocked(Uri uri, int uid, final int modeFlags) {
6116        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6117        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6118                : UriPermission.STRENGTH_OWNED;
6119
6120        // Root gets to do everything.
6121        if (uid == 0) {
6122            return true;
6123        }
6124
6125        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6126        if (perms == null) return false;
6127
6128        // First look for exact match
6129        final UriPermission exactPerm = perms.get(new GrantUri(uri, false));
6130        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6131            return true;
6132        }
6133
6134        // No exact match, look for prefixes
6135        final int N = perms.size();
6136        for (int i = 0; i < N; i++) {
6137            final UriPermission perm = perms.valueAt(i);
6138            if (perm.uri.prefix && uri.isPathPrefixMatch(perm.uri.uri)
6139                    && perm.getStrength(modeFlags) >= minStrength) {
6140                return true;
6141            }
6142        }
6143
6144        return false;
6145    }
6146
6147    @Override
6148    public int checkUriPermission(Uri uri, int pid, int uid, final int modeFlags) {
6149        enforceNotIsolatedCaller("checkUriPermission");
6150
6151        // Another redirected-binder-call permissions check as in
6152        // {@link checkComponentPermission}.
6153        Identity tlsIdentity = sCallerIdentity.get();
6154        if (tlsIdentity != null) {
6155            uid = tlsIdentity.uid;
6156            pid = tlsIdentity.pid;
6157        }
6158
6159        // Our own process gets to do everything.
6160        if (pid == MY_PID) {
6161            return PackageManager.PERMISSION_GRANTED;
6162        }
6163        synchronized (this) {
6164            return checkUriPermissionLocked(uri, uid, modeFlags)
6165                    ? PackageManager.PERMISSION_GRANTED
6166                    : PackageManager.PERMISSION_DENIED;
6167        }
6168    }
6169
6170    /**
6171     * Check if the targetPkg can be granted permission to access uri by
6172     * the callingUid using the given modeFlags.  Throws a security exception
6173     * if callingUid is not allowed to do this.  Returns the uid of the target
6174     * if the URI permission grant should be performed; returns -1 if it is not
6175     * needed (for example targetPkg already has permission to access the URI).
6176     * If you already know the uid of the target, you can supply it in
6177     * lastTargetUid else set that to -1.
6178     */
6179    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
6180            Uri uri, final int modeFlags, int lastTargetUid) {
6181        if (!Intent.isAccessUriMode(modeFlags)) {
6182            return -1;
6183        }
6184
6185        if (targetPkg != null) {
6186            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6187                    "Checking grant " + targetPkg + " permission to " + uri);
6188        }
6189
6190        final IPackageManager pm = AppGlobals.getPackageManager();
6191
6192        // If this is not a content: uri, we can't do anything with it.
6193        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
6194            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6195                    "Can't grant URI permission for non-content URI: " + uri);
6196            return -1;
6197        }
6198
6199        final String authority = uri.getAuthority();
6200        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6201        if (pi == null) {
6202            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
6203            return -1;
6204        }
6205
6206        int targetUid = lastTargetUid;
6207        if (targetUid < 0 && targetPkg != null) {
6208            try {
6209                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6210                if (targetUid < 0) {
6211                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6212                            "Can't grant URI permission no uid for: " + targetPkg);
6213                    return -1;
6214                }
6215            } catch (RemoteException ex) {
6216                return -1;
6217            }
6218        }
6219
6220        if (targetUid >= 0) {
6221            // First...  does the target actually need this permission?
6222            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
6223                // No need to grant the target this permission.
6224                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6225                        "Target " + targetPkg + " already has full permission to " + uri);
6226                return -1;
6227            }
6228        } else {
6229            // First...  there is no target package, so can anyone access it?
6230            boolean allowed = pi.exported;
6231            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6232                if (pi.readPermission != null) {
6233                    allowed = false;
6234                }
6235            }
6236            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6237                if (pi.writePermission != null) {
6238                    allowed = false;
6239                }
6240            }
6241            if (allowed) {
6242                return -1;
6243            }
6244        }
6245
6246        // Second...  is the provider allowing granting of URI permissions?
6247        if (!pi.grantUriPermissions) {
6248            throw new SecurityException("Provider " + pi.packageName
6249                    + "/" + pi.name
6250                    + " does not allow granting of Uri permissions (uri "
6251                    + uri + ")");
6252        }
6253        if (pi.uriPermissionPatterns != null) {
6254            final int N = pi.uriPermissionPatterns.length;
6255            boolean allowed = false;
6256            for (int i=0; i<N; i++) {
6257                if (pi.uriPermissionPatterns[i] != null
6258                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
6259                    allowed = true;
6260                    break;
6261                }
6262            }
6263            if (!allowed) {
6264                throw new SecurityException("Provider " + pi.packageName
6265                        + "/" + pi.name
6266                        + " does not allow granting of permission to path of Uri "
6267                        + uri);
6268            }
6269        }
6270
6271        // Third...  does the caller itself have permission to access
6272        // this uri?
6273        if (callingUid != Process.myUid()) {
6274            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6275                // Require they hold a strong enough Uri permission
6276                if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6277                    throw new SecurityException("Uid " + callingUid
6278                            + " does not have permission to uri " + uri);
6279                }
6280            }
6281        }
6282
6283        return targetUid;
6284    }
6285
6286    @Override
6287    public int checkGrantUriPermission(int callingUid, String targetPkg,
6288            Uri uri, final int modeFlags) {
6289        enforceNotIsolatedCaller("checkGrantUriPermission");
6290        synchronized(this) {
6291            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6292        }
6293    }
6294
6295    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, Uri uri,
6296            final int modeFlags, UriPermissionOwner owner) {
6297        if (!Intent.isAccessUriMode(modeFlags)) {
6298            return;
6299        }
6300
6301        // So here we are: the caller has the assumed permission
6302        // to the uri, and the target doesn't.  Let's now give this to
6303        // the target.
6304
6305        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6306                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
6307
6308        final String authority = uri.getAuthority();
6309        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid));
6310        if (pi == null) {
6311            Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString());
6312            return;
6313        }
6314
6315        final boolean prefix = (modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
6316        final UriPermission perm = findOrCreateUriPermissionLocked(
6317                pi.packageName, targetPkg, targetUid, new GrantUri(uri, prefix));
6318        perm.grantModes(modeFlags, owner);
6319    }
6320
6321    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
6322            final int modeFlags, UriPermissionOwner owner) {
6323        if (targetPkg == null) {
6324            throw new NullPointerException("targetPkg");
6325        }
6326
6327        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6328        if (targetUid < 0) {
6329            return;
6330        }
6331
6332        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
6333    }
6334
6335    static class NeededUriGrants extends ArrayList<Uri> {
6336        final String targetPkg;
6337        final int targetUid;
6338        final int flags;
6339
6340        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6341            this.targetPkg = targetPkg;
6342            this.targetUid = targetUid;
6343            this.flags = flags;
6344        }
6345    }
6346
6347    /**
6348     * Like checkGrantUriPermissionLocked, but takes an Intent.
6349     */
6350    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6351            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6352        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6353                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6354                + " clip=" + (intent != null ? intent.getClipData() : null)
6355                + " from " + intent + "; flags=0x"
6356                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6357
6358        if (targetPkg == null) {
6359            throw new NullPointerException("targetPkg");
6360        }
6361
6362        if (intent == null) {
6363            return null;
6364        }
6365        Uri data = intent.getData();
6366        ClipData clip = intent.getClipData();
6367        if (data == null && clip == null) {
6368            return null;
6369        }
6370
6371        if (data != null) {
6372            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
6373                mode, needed != null ? needed.targetUid : -1);
6374            if (targetUid > 0) {
6375                if (needed == null) {
6376                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6377                }
6378                needed.add(data);
6379            }
6380        }
6381        if (clip != null) {
6382            for (int i=0; i<clip.getItemCount(); i++) {
6383                Uri uri = clip.getItemAt(i).getUri();
6384                if (uri != null) {
6385                    int targetUid = -1;
6386                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
6387                            mode, needed != null ? needed.targetUid : -1);
6388                    if (targetUid > 0) {
6389                        if (needed == null) {
6390                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6391                        }
6392                        needed.add(uri);
6393                    }
6394                } else {
6395                    Intent clipIntent = clip.getItemAt(i).getIntent();
6396                    if (clipIntent != null) {
6397                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6398                                callingUid, targetPkg, clipIntent, mode, needed);
6399                        if (newNeeded != null) {
6400                            needed = newNeeded;
6401                        }
6402                    }
6403                }
6404            }
6405        }
6406
6407        return needed;
6408    }
6409
6410    /**
6411     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6412     */
6413    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6414            UriPermissionOwner owner) {
6415        if (needed != null) {
6416            for (int i=0; i<needed.size(); i++) {
6417                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6418                        needed.get(i), needed.flags, owner);
6419            }
6420        }
6421    }
6422
6423    void grantUriPermissionFromIntentLocked(int callingUid,
6424            String targetPkg, Intent intent, UriPermissionOwner owner) {
6425        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6426                intent, intent != null ? intent.getFlags() : 0, null);
6427        if (needed == null) {
6428            return;
6429        }
6430
6431        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6432    }
6433
6434    @Override
6435    public void grantUriPermission(IApplicationThread caller, String targetPkg,
6436            Uri uri, final int modeFlags) {
6437        enforceNotIsolatedCaller("grantUriPermission");
6438        synchronized(this) {
6439            final ProcessRecord r = getRecordForAppLocked(caller);
6440            if (r == null) {
6441                throw new SecurityException("Unable to find app for caller "
6442                        + caller
6443                        + " when granting permission to uri " + uri);
6444            }
6445            if (targetPkg == null) {
6446                throw new IllegalArgumentException("null target");
6447            }
6448            if (uri == null) {
6449                throw new IllegalArgumentException("null uri");
6450            }
6451
6452            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6453                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6454                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6455                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6456
6457            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, null);
6458        }
6459    }
6460
6461    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6462        if (perm.modeFlags == 0) {
6463            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6464                    perm.targetUid);
6465            if (perms != null) {
6466                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6467                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6468
6469                perms.remove(perm.uri);
6470                if (perms.isEmpty()) {
6471                    mGrantedUriPermissions.remove(perm.targetUid);
6472                }
6473            }
6474        }
6475    }
6476
6477    private void revokeUriPermissionLocked(int callingUid, Uri uri, final int modeFlags) {
6478        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri);
6479
6480        final IPackageManager pm = AppGlobals.getPackageManager();
6481        final String authority = uri.getAuthority();
6482        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6483        if (pi == null) {
6484            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
6485            return;
6486        }
6487
6488        // Does the caller have this permission on the URI?
6489        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6490            // Right now, if you are not the original owner of the permission,
6491            // you are not allowed to revoke it.
6492            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6493                throw new SecurityException("Uid " + callingUid
6494                        + " does not have permission to uri " + uri);
6495            //}
6496        }
6497
6498        boolean persistChanged = false;
6499
6500        // Go through all of the permissions and remove any that match.
6501        int N = mGrantedUriPermissions.size();
6502        for (int i = 0; i < N; i++) {
6503            final int targetUid = mGrantedUriPermissions.keyAt(i);
6504            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6505
6506            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6507                final UriPermission perm = it.next();
6508                if (perm.uri.uri.isPathPrefixMatch(uri)) {
6509                    if (DEBUG_URI_PERMISSION)
6510                        Slog.v(TAG,
6511                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6512                    persistChanged |= perm.revokeModes(
6513                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6514                    if (perm.modeFlags == 0) {
6515                        it.remove();
6516                    }
6517                }
6518            }
6519
6520            if (perms.isEmpty()) {
6521                mGrantedUriPermissions.remove(targetUid);
6522                N--;
6523                i--;
6524            }
6525        }
6526
6527        if (persistChanged) {
6528            schedulePersistUriGrants();
6529        }
6530    }
6531
6532    @Override
6533    public void revokeUriPermission(IApplicationThread caller, Uri uri,
6534            final int modeFlags) {
6535        enforceNotIsolatedCaller("revokeUriPermission");
6536        synchronized(this) {
6537            final ProcessRecord r = getRecordForAppLocked(caller);
6538            if (r == null) {
6539                throw new SecurityException("Unable to find app for caller "
6540                        + caller
6541                        + " when revoking permission to uri " + uri);
6542            }
6543            if (uri == null) {
6544                Slog.w(TAG, "revokeUriPermission: null uri");
6545                return;
6546            }
6547
6548            if (!Intent.isAccessUriMode(modeFlags)) {
6549                return;
6550            }
6551
6552            final IPackageManager pm = AppGlobals.getPackageManager();
6553            final String authority = uri.getAuthority();
6554            final ProviderInfo pi = getProviderInfoLocked(authority, r.userId);
6555            if (pi == null) {
6556                Slog.w(TAG, "No content provider found for permission revoke: "
6557                        + uri.toSafeString());
6558                return;
6559            }
6560
6561            revokeUriPermissionLocked(r.uid, uri, modeFlags);
6562        }
6563    }
6564
6565    /**
6566     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6567     * given package.
6568     *
6569     * @param packageName Package name to match, or {@code null} to apply to all
6570     *            packages.
6571     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6572     *            to all users.
6573     * @param persistable If persistable grants should be removed.
6574     */
6575    private void removeUriPermissionsForPackageLocked(
6576            String packageName, int userHandle, boolean persistable) {
6577        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6578            throw new IllegalArgumentException("Must narrow by either package or user");
6579        }
6580
6581        boolean persistChanged = false;
6582
6583        int N = mGrantedUriPermissions.size();
6584        for (int i = 0; i < N; i++) {
6585            final int targetUid = mGrantedUriPermissions.keyAt(i);
6586            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6587
6588            // Only inspect grants matching user
6589            if (userHandle == UserHandle.USER_ALL
6590                    || userHandle == UserHandle.getUserId(targetUid)) {
6591                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6592                    final UriPermission perm = it.next();
6593
6594                    // Only inspect grants matching package
6595                    if (packageName == null || perm.sourcePkg.equals(packageName)
6596                            || perm.targetPkg.equals(packageName)) {
6597                        persistChanged |= perm.revokeModes(
6598                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6599
6600                        // Only remove when no modes remain; any persisted grants
6601                        // will keep this alive.
6602                        if (perm.modeFlags == 0) {
6603                            it.remove();
6604                        }
6605                    }
6606                }
6607
6608                if (perms.isEmpty()) {
6609                    mGrantedUriPermissions.remove(targetUid);
6610                    N--;
6611                    i--;
6612                }
6613            }
6614        }
6615
6616        if (persistChanged) {
6617            schedulePersistUriGrants();
6618        }
6619    }
6620
6621    @Override
6622    public IBinder newUriPermissionOwner(String name) {
6623        enforceNotIsolatedCaller("newUriPermissionOwner");
6624        synchronized(this) {
6625            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6626            return owner.getExternalTokenLocked();
6627        }
6628    }
6629
6630    @Override
6631    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
6632            Uri uri, final int modeFlags) {
6633        synchronized(this) {
6634            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6635            if (owner == null) {
6636                throw new IllegalArgumentException("Unknown owner: " + token);
6637            }
6638            if (fromUid != Binder.getCallingUid()) {
6639                if (Binder.getCallingUid() != Process.myUid()) {
6640                    // Only system code can grant URI permissions on behalf
6641                    // of other users.
6642                    throw new SecurityException("nice try");
6643                }
6644            }
6645            if (targetPkg == null) {
6646                throw new IllegalArgumentException("null target");
6647            }
6648            if (uri == null) {
6649                throw new IllegalArgumentException("null uri");
6650            }
6651
6652            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
6653        }
6654    }
6655
6656    @Override
6657    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
6658        synchronized(this) {
6659            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6660            if (owner == null) {
6661                throw new IllegalArgumentException("Unknown owner: " + token);
6662            }
6663
6664            if (uri == null) {
6665                owner.removeUriPermissionsLocked(mode);
6666            } else {
6667                owner.removeUriPermissionLocked(uri, mode);
6668            }
6669        }
6670    }
6671
6672    private void schedulePersistUriGrants() {
6673        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6674            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6675                    10 * DateUtils.SECOND_IN_MILLIS);
6676        }
6677    }
6678
6679    private void writeGrantedUriPermissions() {
6680        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6681
6682        // Snapshot permissions so we can persist without lock
6683        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6684        synchronized (this) {
6685            final int size = mGrantedUriPermissions.size();
6686            for (int i = 0; i < size; i++) {
6687                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6688                for (UriPermission perm : perms.values()) {
6689                    if (perm.persistedModeFlags != 0) {
6690                        persist.add(perm.snapshot());
6691                    }
6692                }
6693            }
6694        }
6695
6696        FileOutputStream fos = null;
6697        try {
6698            fos = mGrantFile.startWrite();
6699
6700            XmlSerializer out = new FastXmlSerializer();
6701            out.setOutput(fos, "utf-8");
6702            out.startDocument(null, true);
6703            out.startTag(null, TAG_URI_GRANTS);
6704            for (UriPermission.Snapshot perm : persist) {
6705                out.startTag(null, TAG_URI_GRANT);
6706                writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle);
6707                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6708                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6709                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6710                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6711                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6712                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6713                out.endTag(null, TAG_URI_GRANT);
6714            }
6715            out.endTag(null, TAG_URI_GRANTS);
6716            out.endDocument();
6717
6718            mGrantFile.finishWrite(fos);
6719        } catch (IOException e) {
6720            if (fos != null) {
6721                mGrantFile.failWrite(fos);
6722            }
6723        }
6724    }
6725
6726    private void readGrantedUriPermissionsLocked() {
6727        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6728
6729        final long now = System.currentTimeMillis();
6730
6731        FileInputStream fis = null;
6732        try {
6733            fis = mGrantFile.openRead();
6734            final XmlPullParser in = Xml.newPullParser();
6735            in.setInput(fis, null);
6736
6737            int type;
6738            while ((type = in.next()) != END_DOCUMENT) {
6739                final String tag = in.getName();
6740                if (type == START_TAG) {
6741                    if (TAG_URI_GRANT.equals(tag)) {
6742                        final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE);
6743                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6744                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6745                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6746                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
6747                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6748                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6749
6750                        // Sanity check that provider still belongs to source package
6751                        final ProviderInfo pi = getProviderInfoLocked(
6752                                uri.getAuthority(), userHandle);
6753                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6754                            int targetUid = -1;
6755                            try {
6756                                targetUid = AppGlobals.getPackageManager()
6757                                        .getPackageUid(targetPkg, userHandle);
6758                            } catch (RemoteException e) {
6759                            }
6760                            if (targetUid != -1) {
6761                                final UriPermission perm = findOrCreateUriPermissionLocked(
6762                                        sourcePkg, targetPkg, targetUid, new GrantUri(uri, prefix));
6763                                perm.initPersistedModes(modeFlags, createdTime);
6764                            }
6765                        } else {
6766                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6767                                    + " but instead found " + pi);
6768                        }
6769                    }
6770                }
6771            }
6772        } catch (FileNotFoundException e) {
6773            // Missing grants is okay
6774        } catch (IOException e) {
6775            Log.wtf(TAG, "Failed reading Uri grants", e);
6776        } catch (XmlPullParserException e) {
6777            Log.wtf(TAG, "Failed reading Uri grants", e);
6778        } finally {
6779            IoUtils.closeQuietly(fis);
6780        }
6781    }
6782
6783    @Override
6784    public void takePersistableUriPermission(Uri uri, final int modeFlags) {
6785        enforceNotIsolatedCaller("takePersistableUriPermission");
6786
6787        Preconditions.checkFlagsArgument(modeFlags,
6788                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6789
6790        synchronized (this) {
6791            final int callingUid = Binder.getCallingUid();
6792            boolean persistChanged = false;
6793
6794            UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false));
6795            UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true));
6796
6797            final boolean exactValid = (exactPerm != null)
6798                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
6799            final boolean prefixValid = (prefixPerm != null)
6800                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
6801
6802            if (!(exactValid || prefixValid)) {
6803                throw new SecurityException("No persistable permission grants found for UID "
6804                        + callingUid + " and Uri " + uri.toSafeString());
6805            }
6806
6807            if (exactValid) {
6808                persistChanged |= exactPerm.takePersistableModes(modeFlags);
6809            }
6810            if (prefixValid) {
6811                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
6812            }
6813
6814            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6815
6816            if (persistChanged) {
6817                schedulePersistUriGrants();
6818            }
6819        }
6820    }
6821
6822    @Override
6823    public void releasePersistableUriPermission(Uri uri, final int modeFlags) {
6824        enforceNotIsolatedCaller("releasePersistableUriPermission");
6825
6826        Preconditions.checkFlagsArgument(modeFlags,
6827                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6828
6829        synchronized (this) {
6830            final int callingUid = Binder.getCallingUid();
6831            boolean persistChanged = false;
6832
6833            UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false));
6834            UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true));
6835            if (exactPerm == null && prefixPerm == null) {
6836                throw new SecurityException("No permission grants found for UID " + callingUid
6837                        + " and Uri " + uri.toSafeString());
6838            }
6839
6840            if (exactPerm != null) {
6841                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
6842                removeUriPermissionIfNeededLocked(exactPerm);
6843            }
6844            if (prefixPerm != null) {
6845                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
6846                removeUriPermissionIfNeededLocked(prefixPerm);
6847            }
6848
6849            if (persistChanged) {
6850                schedulePersistUriGrants();
6851            }
6852        }
6853    }
6854
6855    /**
6856     * Prune any older {@link UriPermission} for the given UID until outstanding
6857     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6858     *
6859     * @return if any mutations occured that require persisting.
6860     */
6861    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6862        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6863        if (perms == null) return false;
6864        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6865
6866        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6867        for (UriPermission perm : perms.values()) {
6868            if (perm.persistedModeFlags != 0) {
6869                persisted.add(perm);
6870            }
6871        }
6872
6873        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6874        if (trimCount <= 0) return false;
6875
6876        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6877        for (int i = 0; i < trimCount; i++) {
6878            final UriPermission perm = persisted.get(i);
6879
6880            if (DEBUG_URI_PERMISSION) {
6881                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6882            }
6883
6884            perm.releasePersistableModes(~0);
6885            removeUriPermissionIfNeededLocked(perm);
6886        }
6887
6888        return true;
6889    }
6890
6891    @Override
6892    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6893            String packageName, boolean incoming) {
6894        enforceNotIsolatedCaller("getPersistedUriPermissions");
6895        Preconditions.checkNotNull(packageName, "packageName");
6896
6897        final int callingUid = Binder.getCallingUid();
6898        final IPackageManager pm = AppGlobals.getPackageManager();
6899        try {
6900            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6901            if (packageUid != callingUid) {
6902                throw new SecurityException(
6903                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6904            }
6905        } catch (RemoteException e) {
6906            throw new SecurityException("Failed to verify package name ownership");
6907        }
6908
6909        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6910        synchronized (this) {
6911            if (incoming) {
6912                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6913                        callingUid);
6914                if (perms == null) {
6915                    Slog.w(TAG, "No permission grants found for " + packageName);
6916                } else {
6917                    for (UriPermission perm : perms.values()) {
6918                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6919                            result.add(perm.buildPersistedPublicApiObject());
6920                        }
6921                    }
6922                }
6923            } else {
6924                final int size = mGrantedUriPermissions.size();
6925                for (int i = 0; i < size; i++) {
6926                    final ArrayMap<GrantUri, UriPermission> perms =
6927                            mGrantedUriPermissions.valueAt(i);
6928                    for (UriPermission perm : perms.values()) {
6929                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6930                            result.add(perm.buildPersistedPublicApiObject());
6931                        }
6932                    }
6933                }
6934            }
6935        }
6936        return new ParceledListSlice<android.content.UriPermission>(result);
6937    }
6938
6939    @Override
6940    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6941        synchronized (this) {
6942            ProcessRecord app =
6943                who != null ? getRecordForAppLocked(who) : null;
6944            if (app == null) return;
6945
6946            Message msg = Message.obtain();
6947            msg.what = WAIT_FOR_DEBUGGER_MSG;
6948            msg.obj = app;
6949            msg.arg1 = waiting ? 1 : 0;
6950            mHandler.sendMessage(msg);
6951        }
6952    }
6953
6954    @Override
6955    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
6956        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
6957        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
6958        outInfo.availMem = Process.getFreeMemory();
6959        outInfo.totalMem = Process.getTotalMemory();
6960        outInfo.threshold = homeAppMem;
6961        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
6962        outInfo.hiddenAppThreshold = cachedAppMem;
6963        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
6964                ProcessList.SERVICE_ADJ);
6965        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
6966                ProcessList.VISIBLE_APP_ADJ);
6967        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
6968                ProcessList.FOREGROUND_APP_ADJ);
6969    }
6970
6971    // =========================================================
6972    // TASK MANAGEMENT
6973    // =========================================================
6974
6975    @Override
6976    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
6977        final int callingUid = Binder.getCallingUid();
6978        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
6979
6980        synchronized(this) {
6981            if (localLOGV) Slog.v(
6982                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
6983
6984            final boolean allowed = checkCallingPermission(
6985                    android.Manifest.permission.GET_TASKS)
6986                    == PackageManager.PERMISSION_GRANTED;
6987            if (!allowed) {
6988                Slog.w(TAG, "getTasks: caller " + callingUid
6989                        + " does not hold GET_TASKS; limiting output");
6990            }
6991
6992            // TODO: Improve with MRU list from all ActivityStacks.
6993            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
6994        }
6995
6996        return list;
6997    }
6998
6999    TaskRecord getMostRecentTask() {
7000        return mRecentTasks.get(0);
7001    }
7002
7003    @Override
7004    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
7005            int flags, int userId) {
7006        final int callingUid = Binder.getCallingUid();
7007        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7008                false, true, "getRecentTasks", null);
7009
7010        synchronized (this) {
7011            final boolean allowed = checkCallingPermission(
7012                    android.Manifest.permission.GET_TASKS)
7013                    == PackageManager.PERMISSION_GRANTED;
7014            if (!allowed) {
7015                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7016                        + " does not hold GET_TASKS; limiting output");
7017            }
7018            final boolean detailed = checkCallingPermission(
7019                    android.Manifest.permission.GET_DETAILED_TASKS)
7020                    == PackageManager.PERMISSION_GRANTED;
7021
7022            IPackageManager pm = AppGlobals.getPackageManager();
7023
7024            final int N = mRecentTasks.size();
7025            ArrayList<ActivityManager.RecentTaskInfo> res
7026                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7027                            maxNum < N ? maxNum : N);
7028
7029            final Set<Integer> includedUsers;
7030            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
7031                includedUsers = getProfileIdsLocked(userId);
7032            } else {
7033                includedUsers = new HashSet<Integer>();
7034            }
7035            includedUsers.add(Integer.valueOf(userId));
7036            for (int i=0; i<N && maxNum > 0; i++) {
7037                TaskRecord tr = mRecentTasks.get(i);
7038                // Only add calling user or related users recent tasks
7039                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7040
7041                // Return the entry if desired by the caller.  We always return
7042                // the first entry, because callers always expect this to be the
7043                // foreground app.  We may filter others if the caller has
7044                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7045                // we should exclude the entry.
7046
7047                if (i == 0
7048                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
7049                        || (tr.intent == null)
7050                        || ((tr.intent.getFlags()
7051                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
7052                    if (!allowed) {
7053                        // If the caller doesn't have the GET_TASKS permission, then only
7054                        // allow them to see a small subset of tasks -- their own and home.
7055                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7056                            continue;
7057                        }
7058                    }
7059                    ActivityManager.RecentTaskInfo rti
7060                            = new ActivityManager.RecentTaskInfo();
7061                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
7062                    rti.persistentId = tr.taskId;
7063                    rti.baseIntent = new Intent(
7064                            tr.intent != null ? tr.intent : tr.affinityIntent);
7065                    if (!detailed) {
7066                        rti.baseIntent.replaceExtras((Bundle)null);
7067                    }
7068                    rti.origActivity = tr.origActivity;
7069                    rti.description = tr.lastDescription;
7070                    rti.stackId = tr.stack.mStackId;
7071                    rti.userId = tr.userId;
7072
7073                    // Traverse upwards looking for any break between main task activities and
7074                    // utility activities.
7075                    final ArrayList<ActivityRecord> activities = tr.mActivities;
7076                    int activityNdx;
7077                    final int numActivities = activities.size();
7078                    for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities;
7079                            ++activityNdx) {
7080                        final ActivityRecord r = activities.get(activityNdx);
7081                        if (r.intent != null &&
7082                                (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET)
7083                                        != 0) {
7084                            break;
7085                        }
7086                    }
7087                    if (activityNdx > 0) {
7088                        // Traverse downwards starting below break looking for set label, icon.
7089                        // Note that if there are activities in the task but none of them set the
7090                        // recent activity values, then we do not fall back to the last set
7091                        // values in the TaskRecord.
7092                        rti.activityValues = new ActivityManager.RecentsActivityValues();
7093                        for (--activityNdx; activityNdx >= 0; --activityNdx) {
7094                            final ActivityRecord r = activities.get(activityNdx);
7095                            if (r.activityValues != null) {
7096                                if (rti.activityValues.label == null) {
7097                                    rti.activityValues.label = r.activityValues.label;
7098                                    tr.lastActivityValues.label = r.activityValues.label;
7099                                }
7100                                if (rti.activityValues.icon == null) {
7101                                    rti.activityValues.icon = r.activityValues.icon;
7102                                    tr.lastActivityValues.icon = r.activityValues.icon;
7103                                }
7104                                if (rti.activityValues.colorPrimary == 0) {
7105                                    rti.activityValues.colorPrimary = r.activityValues.colorPrimary;
7106                                    tr.lastActivityValues.colorPrimary = r.activityValues.colorPrimary;
7107                                }
7108                            }
7109                        }
7110                    } else {
7111                        // If there are no activity records in this task, then we use the last
7112                        // resolved values
7113                        rti.activityValues =
7114                                new ActivityManager.RecentsActivityValues(tr.lastActivityValues);
7115                    }
7116
7117                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7118                        // Check whether this activity is currently available.
7119                        try {
7120                            if (rti.origActivity != null) {
7121                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7122                                        == null) {
7123                                    continue;
7124                                }
7125                            } else if (rti.baseIntent != null) {
7126                                if (pm.queryIntentActivities(rti.baseIntent,
7127                                        null, 0, userId) == null) {
7128                                    continue;
7129                                }
7130                            }
7131                        } catch (RemoteException e) {
7132                            // Will never happen.
7133                        }
7134                    }
7135
7136                    res.add(rti);
7137                    maxNum--;
7138                }
7139            }
7140            return res;
7141        }
7142    }
7143
7144    private TaskRecord recentTaskForIdLocked(int id) {
7145        final int N = mRecentTasks.size();
7146            for (int i=0; i<N; i++) {
7147                TaskRecord tr = mRecentTasks.get(i);
7148                if (tr.taskId == id) {
7149                    return tr;
7150                }
7151            }
7152            return null;
7153    }
7154
7155    @Override
7156    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
7157        synchronized (this) {
7158            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7159                    "getTaskThumbnails()");
7160            TaskRecord tr = recentTaskForIdLocked(id);
7161            if (tr != null) {
7162                return tr.getTaskThumbnailsLocked();
7163            }
7164        }
7165        return null;
7166    }
7167
7168    @Override
7169    public Bitmap getTaskTopThumbnail(int id) {
7170        synchronized (this) {
7171            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7172                    "getTaskTopThumbnail()");
7173            TaskRecord tr = recentTaskForIdLocked(id);
7174            if (tr != null) {
7175                return tr.getTaskTopThumbnailLocked();
7176            }
7177        }
7178        return null;
7179    }
7180
7181    @Override
7182    public void setRecentsActivityValues(IBinder token, ActivityManager.RecentsActivityValues rav) {
7183        synchronized (this) {
7184            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7185            if (r != null) {
7186                r.activityValues = rav;
7187            }
7188        }
7189    }
7190
7191    @Override
7192    public boolean removeSubTask(int taskId, int subTaskIndex) {
7193        synchronized (this) {
7194            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7195                    "removeSubTask()");
7196            long ident = Binder.clearCallingIdentity();
7197            try {
7198                TaskRecord tr = recentTaskForIdLocked(taskId);
7199                if (tr != null) {
7200                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
7201                }
7202                return false;
7203            } finally {
7204                Binder.restoreCallingIdentity(ident);
7205            }
7206        }
7207    }
7208
7209    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7210        if (!pr.killedByAm) {
7211            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7212            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7213                    pr.processName, pr.setAdj, reason);
7214            pr.killedByAm = true;
7215            Process.killProcessQuiet(pr.pid);
7216        }
7217    }
7218
7219    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7220        tr.disposeThumbnail();
7221        mRecentTasks.remove(tr);
7222        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7223        Intent baseIntent = new Intent(
7224                tr.intent != null ? tr.intent : tr.affinityIntent);
7225        ComponentName component = baseIntent.getComponent();
7226        if (component == null) {
7227            Slog.w(TAG, "Now component for base intent of task: " + tr);
7228            return;
7229        }
7230
7231        // Find any running services associated with this app.
7232        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7233
7234        if (killProcesses) {
7235            // Find any running processes associated with this app.
7236            final String pkg = component.getPackageName();
7237            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7238            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7239            for (int i=0; i<pmap.size(); i++) {
7240                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7241                for (int j=0; j<uids.size(); j++) {
7242                    ProcessRecord proc = uids.valueAt(j);
7243                    if (proc.userId != tr.userId) {
7244                        continue;
7245                    }
7246                    if (!proc.pkgList.containsKey(pkg)) {
7247                        continue;
7248                    }
7249                    procs.add(proc);
7250                }
7251            }
7252
7253            // Kill the running processes.
7254            for (int i=0; i<procs.size(); i++) {
7255                ProcessRecord pr = procs.get(i);
7256                if (pr == mHomeProcess) {
7257                    // Don't kill the home process along with tasks from the same package.
7258                    continue;
7259                }
7260                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7261                    killUnneededProcessLocked(pr, "remove task");
7262                } else {
7263                    pr.waitingToKill = "remove task";
7264                }
7265            }
7266        }
7267    }
7268
7269    /**
7270     * Removes the task with the specified task id.
7271     *
7272     * @param taskId Identifier of the task to be removed.
7273     * @param flags Additional operational flags.  May be 0 or
7274     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7275     * @return Returns true if the given task was found and removed.
7276     */
7277    private boolean removeTaskByIdLocked(int taskId, int flags) {
7278        TaskRecord tr = recentTaskForIdLocked(taskId);
7279        if (tr != null) {
7280            tr.removeTaskActivitiesLocked(-1, false);
7281            cleanUpRemovedTaskLocked(tr, flags);
7282            return true;
7283        }
7284        return false;
7285    }
7286
7287    @Override
7288    public boolean removeTask(int taskId, int flags) {
7289        synchronized (this) {
7290            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7291                    "removeTask()");
7292            long ident = Binder.clearCallingIdentity();
7293            try {
7294                return removeTaskByIdLocked(taskId, flags);
7295            } finally {
7296                Binder.restoreCallingIdentity(ident);
7297            }
7298        }
7299    }
7300
7301    /**
7302     * TODO: Add mController hook
7303     */
7304    @Override
7305    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7306        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7307                "moveTaskToFront()");
7308
7309        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7310        synchronized(this) {
7311            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7312                    Binder.getCallingUid(), "Task to front")) {
7313                ActivityOptions.abort(options);
7314                return;
7315            }
7316            final long origId = Binder.clearCallingIdentity();
7317            try {
7318                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7319                if (task == null) {
7320                    return;
7321                }
7322                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7323                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7324                    return;
7325                }
7326                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7327            } finally {
7328                Binder.restoreCallingIdentity(origId);
7329            }
7330            ActivityOptions.abort(options);
7331        }
7332    }
7333
7334    @Override
7335    public void moveTaskToBack(int taskId) {
7336        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7337                "moveTaskToBack()");
7338
7339        synchronized(this) {
7340            TaskRecord tr = recentTaskForIdLocked(taskId);
7341            if (tr != null) {
7342                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7343                ActivityStack stack = tr.stack;
7344                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7345                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7346                            Binder.getCallingUid(), "Task to back")) {
7347                        return;
7348                    }
7349                }
7350                final long origId = Binder.clearCallingIdentity();
7351                try {
7352                    stack.moveTaskToBackLocked(taskId, null);
7353                } finally {
7354                    Binder.restoreCallingIdentity(origId);
7355                }
7356            }
7357        }
7358    }
7359
7360    /**
7361     * Moves an activity, and all of the other activities within the same task, to the bottom
7362     * of the history stack.  The activity's order within the task is unchanged.
7363     *
7364     * @param token A reference to the activity we wish to move
7365     * @param nonRoot If false then this only works if the activity is the root
7366     *                of a task; if true it will work for any activity in a task.
7367     * @return Returns true if the move completed, false if not.
7368     */
7369    @Override
7370    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7371        enforceNotIsolatedCaller("moveActivityTaskToBack");
7372        synchronized(this) {
7373            final long origId = Binder.clearCallingIdentity();
7374            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7375            if (taskId >= 0) {
7376                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7377            }
7378            Binder.restoreCallingIdentity(origId);
7379        }
7380        return false;
7381    }
7382
7383    @Override
7384    public void moveTaskBackwards(int task) {
7385        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7386                "moveTaskBackwards()");
7387
7388        synchronized(this) {
7389            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7390                    Binder.getCallingUid(), "Task backwards")) {
7391                return;
7392            }
7393            final long origId = Binder.clearCallingIdentity();
7394            moveTaskBackwardsLocked(task);
7395            Binder.restoreCallingIdentity(origId);
7396        }
7397    }
7398
7399    private final void moveTaskBackwardsLocked(int task) {
7400        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7401    }
7402
7403    @Override
7404    public IBinder getHomeActivityToken() throws RemoteException {
7405        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7406                "getHomeActivityToken()");
7407        synchronized (this) {
7408            return mStackSupervisor.getHomeActivityToken();
7409        }
7410    }
7411
7412    @Override
7413    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7414            IActivityContainerCallback callback) throws RemoteException {
7415        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7416                "createActivityContainer()");
7417        synchronized (this) {
7418            if (parentActivityToken == null) {
7419                throw new IllegalArgumentException("parent token must not be null");
7420            }
7421            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7422            if (r == null) {
7423                return null;
7424            }
7425            if (callback == null) {
7426                throw new IllegalArgumentException("callback must not be null");
7427            }
7428            return mStackSupervisor.createActivityContainer(r, callback);
7429        }
7430    }
7431
7432    @Override
7433    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7434        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7435                "deleteActivityContainer()");
7436        synchronized (this) {
7437            mStackSupervisor.deleteActivityContainer(container);
7438        }
7439    }
7440
7441    @Override
7442    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7443            throws RemoteException {
7444        synchronized (this) {
7445            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7446            if (stack != null) {
7447                return stack.mActivityContainer;
7448            }
7449            return null;
7450        }
7451    }
7452
7453    @Override
7454    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7455        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7456                "moveTaskToStack()");
7457        if (stackId == HOME_STACK_ID) {
7458            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7459                    new RuntimeException("here").fillInStackTrace());
7460        }
7461        synchronized (this) {
7462            long ident = Binder.clearCallingIdentity();
7463            try {
7464                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7465                        + stackId + " toTop=" + toTop);
7466                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7467            } finally {
7468                Binder.restoreCallingIdentity(ident);
7469            }
7470        }
7471    }
7472
7473    @Override
7474    public void resizeStack(int stackBoxId, Rect bounds) {
7475        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7476                "resizeStackBox()");
7477        long ident = Binder.clearCallingIdentity();
7478        try {
7479            mWindowManager.resizeStack(stackBoxId, bounds);
7480        } finally {
7481            Binder.restoreCallingIdentity(ident);
7482        }
7483    }
7484
7485    @Override
7486    public List<StackInfo> getAllStackInfos() {
7487        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7488                "getAllStackInfos()");
7489        long ident = Binder.clearCallingIdentity();
7490        try {
7491            synchronized (this) {
7492                return mStackSupervisor.getAllStackInfosLocked();
7493            }
7494        } finally {
7495            Binder.restoreCallingIdentity(ident);
7496        }
7497    }
7498
7499    @Override
7500    public StackInfo getStackInfo(int stackId) {
7501        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7502                "getStackInfo()");
7503        long ident = Binder.clearCallingIdentity();
7504        try {
7505            synchronized (this) {
7506                return mStackSupervisor.getStackInfoLocked(stackId);
7507            }
7508        } finally {
7509            Binder.restoreCallingIdentity(ident);
7510        }
7511    }
7512
7513    @Override
7514    public boolean isInHomeStack(int taskId) {
7515        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7516                "getStackInfo()");
7517        long ident = Binder.clearCallingIdentity();
7518        try {
7519            synchronized (this) {
7520                TaskRecord tr = recentTaskForIdLocked(taskId);
7521                if (tr != null) {
7522                    return tr.stack.isHomeStack();
7523                }
7524            }
7525        } finally {
7526            Binder.restoreCallingIdentity(ident);
7527        }
7528        return false;
7529    }
7530
7531    @Override
7532    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7533        synchronized(this) {
7534            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7535        }
7536    }
7537
7538    private boolean isLockTaskAuthorized(ComponentName name) {
7539//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7540//                "startLockTaskMode()");
7541//        DevicePolicyManager dpm = (DevicePolicyManager)
7542//                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7543//        return dpm != null && dpm.isLockTaskPermitted(name);
7544        return true;
7545    }
7546
7547    private void startLockTaskMode(TaskRecord task) {
7548        if (!isLockTaskAuthorized(task.intent.getComponent())) {
7549            return;
7550        }
7551        long ident = Binder.clearCallingIdentity();
7552        try {
7553            synchronized (this) {
7554                // Since we lost lock on task, make sure it is still there.
7555                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7556                if (task != null) {
7557                    mStackSupervisor.setLockTaskModeLocked(task);
7558                }
7559            }
7560        } finally {
7561            Binder.restoreCallingIdentity(ident);
7562        }
7563    }
7564
7565    @Override
7566    public void startLockTaskMode(int taskId) {
7567        long ident = Binder.clearCallingIdentity();
7568        try {
7569            final TaskRecord task;
7570            synchronized (this) {
7571                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7572            }
7573            if (task != null) {
7574                startLockTaskMode(task);
7575            }
7576        } finally {
7577            Binder.restoreCallingIdentity(ident);
7578        }
7579    }
7580
7581    @Override
7582    public void startLockTaskMode(IBinder token) {
7583        long ident = Binder.clearCallingIdentity();
7584        try {
7585            final TaskRecord task;
7586            synchronized (this) {
7587                final ActivityRecord r = ActivityRecord.forToken(token);
7588                if (r == null) {
7589                    return;
7590                }
7591                task = r.task;
7592            }
7593            if (task != null) {
7594                startLockTaskMode(task);
7595            }
7596        } finally {
7597            Binder.restoreCallingIdentity(ident);
7598        }
7599    }
7600
7601    @Override
7602    public void stopLockTaskMode() {
7603//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7604//                "stopLockTaskMode()");
7605        synchronized (this) {
7606            mStackSupervisor.setLockTaskModeLocked(null);
7607        }
7608    }
7609
7610    @Override
7611    public boolean isInLockTaskMode() {
7612        synchronized (this) {
7613            return mStackSupervisor.isInLockTaskMode();
7614        }
7615    }
7616
7617    // =========================================================
7618    // CONTENT PROVIDERS
7619    // =========================================================
7620
7621    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7622        List<ProviderInfo> providers = null;
7623        try {
7624            providers = AppGlobals.getPackageManager().
7625                queryContentProviders(app.processName, app.uid,
7626                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7627        } catch (RemoteException ex) {
7628        }
7629        if (DEBUG_MU)
7630            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7631        int userId = app.userId;
7632        if (providers != null) {
7633            int N = providers.size();
7634            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7635            for (int i=0; i<N; i++) {
7636                ProviderInfo cpi =
7637                    (ProviderInfo)providers.get(i);
7638                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7639                        cpi.name, cpi.flags);
7640                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7641                    // This is a singleton provider, but a user besides the
7642                    // default user is asking to initialize a process it runs
7643                    // in...  well, no, it doesn't actually run in this process,
7644                    // it runs in the process of the default user.  Get rid of it.
7645                    providers.remove(i);
7646                    N--;
7647                    i--;
7648                    continue;
7649                }
7650
7651                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7652                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7653                if (cpr == null) {
7654                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7655                    mProviderMap.putProviderByClass(comp, cpr);
7656                }
7657                if (DEBUG_MU)
7658                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7659                app.pubProviders.put(cpi.name, cpr);
7660                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7661                    // Don't add this if it is a platform component that is marked
7662                    // to run in multiple processes, because this is actually
7663                    // part of the framework so doesn't make sense to track as a
7664                    // separate apk in the process.
7665                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7666                }
7667                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7668            }
7669        }
7670        return providers;
7671    }
7672
7673    /**
7674     * Check if {@link ProcessRecord} has a possible chance at accessing the
7675     * given {@link ProviderInfo}. Final permission checking is always done
7676     * in {@link ContentProvider}.
7677     */
7678    private final String checkContentProviderPermissionLocked(
7679            ProviderInfo cpi, ProcessRecord r) {
7680        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7681        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7682        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7683                cpi.applicationInfo.uid, cpi.exported)
7684                == PackageManager.PERMISSION_GRANTED) {
7685            return null;
7686        }
7687        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7688                cpi.applicationInfo.uid, cpi.exported)
7689                == PackageManager.PERMISSION_GRANTED) {
7690            return null;
7691        }
7692
7693        PathPermission[] pps = cpi.pathPermissions;
7694        if (pps != null) {
7695            int i = pps.length;
7696            while (i > 0) {
7697                i--;
7698                PathPermission pp = pps[i];
7699                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7700                        cpi.applicationInfo.uid, cpi.exported)
7701                        == PackageManager.PERMISSION_GRANTED) {
7702                    return null;
7703                }
7704                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7705                        cpi.applicationInfo.uid, cpi.exported)
7706                        == PackageManager.PERMISSION_GRANTED) {
7707                    return null;
7708                }
7709            }
7710        }
7711
7712        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7713        if (perms != null) {
7714            for (GrantUri uri : perms.keySet()) {
7715                if (uri.uri.getAuthority().equals(cpi.authority)) {
7716                    return null;
7717                }
7718            }
7719        }
7720
7721        String msg;
7722        if (!cpi.exported) {
7723            msg = "Permission Denial: opening provider " + cpi.name
7724                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7725                    + ", uid=" + callingUid + ") that is not exported from uid "
7726                    + cpi.applicationInfo.uid;
7727        } else {
7728            msg = "Permission Denial: opening provider " + cpi.name
7729                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7730                    + ", uid=" + callingUid + ") requires "
7731                    + cpi.readPermission + " or " + cpi.writePermission;
7732        }
7733        Slog.w(TAG, msg);
7734        return msg;
7735    }
7736
7737    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7738            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7739        if (r != null) {
7740            for (int i=0; i<r.conProviders.size(); i++) {
7741                ContentProviderConnection conn = r.conProviders.get(i);
7742                if (conn.provider == cpr) {
7743                    if (DEBUG_PROVIDER) Slog.v(TAG,
7744                            "Adding provider requested by "
7745                            + r.processName + " from process "
7746                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7747                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7748                    if (stable) {
7749                        conn.stableCount++;
7750                        conn.numStableIncs++;
7751                    } else {
7752                        conn.unstableCount++;
7753                        conn.numUnstableIncs++;
7754                    }
7755                    return conn;
7756                }
7757            }
7758            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7759            if (stable) {
7760                conn.stableCount = 1;
7761                conn.numStableIncs = 1;
7762            } else {
7763                conn.unstableCount = 1;
7764                conn.numUnstableIncs = 1;
7765            }
7766            cpr.connections.add(conn);
7767            r.conProviders.add(conn);
7768            return conn;
7769        }
7770        cpr.addExternalProcessHandleLocked(externalProcessToken);
7771        return null;
7772    }
7773
7774    boolean decProviderCountLocked(ContentProviderConnection conn,
7775            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7776        if (conn != null) {
7777            cpr = conn.provider;
7778            if (DEBUG_PROVIDER) Slog.v(TAG,
7779                    "Removing provider requested by "
7780                    + conn.client.processName + " from process "
7781                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7782                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7783            if (stable) {
7784                conn.stableCount--;
7785            } else {
7786                conn.unstableCount--;
7787            }
7788            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7789                cpr.connections.remove(conn);
7790                conn.client.conProviders.remove(conn);
7791                return true;
7792            }
7793            return false;
7794        }
7795        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7796        return false;
7797    }
7798
7799    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7800            String name, IBinder token, boolean stable, int userId) {
7801        ContentProviderRecord cpr;
7802        ContentProviderConnection conn = null;
7803        ProviderInfo cpi = null;
7804
7805        synchronized(this) {
7806            ProcessRecord r = null;
7807            if (caller != null) {
7808                r = getRecordForAppLocked(caller);
7809                if (r == null) {
7810                    throw new SecurityException(
7811                            "Unable to find app for caller " + caller
7812                          + " (pid=" + Binder.getCallingPid()
7813                          + ") when getting content provider " + name);
7814                }
7815            }
7816
7817            // First check if this content provider has been published...
7818            cpr = mProviderMap.getProviderByName(name, userId);
7819            boolean providerRunning = cpr != null;
7820            if (providerRunning) {
7821                cpi = cpr.info;
7822                String msg;
7823                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7824                    throw new SecurityException(msg);
7825                }
7826
7827                if (r != null && cpr.canRunHere(r)) {
7828                    // This provider has been published or is in the process
7829                    // of being published...  but it is also allowed to run
7830                    // in the caller's process, so don't make a connection
7831                    // and just let the caller instantiate its own instance.
7832                    ContentProviderHolder holder = cpr.newHolder(null);
7833                    // don't give caller the provider object, it needs
7834                    // to make its own.
7835                    holder.provider = null;
7836                    return holder;
7837                }
7838
7839                final long origId = Binder.clearCallingIdentity();
7840
7841                // In this case the provider instance already exists, so we can
7842                // return it right away.
7843                conn = incProviderCountLocked(r, cpr, token, stable);
7844                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7845                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7846                        // If this is a perceptible app accessing the provider,
7847                        // make sure to count it as being accessed and thus
7848                        // back up on the LRU list.  This is good because
7849                        // content providers are often expensive to start.
7850                        updateLruProcessLocked(cpr.proc, false, null);
7851                    }
7852                }
7853
7854                if (cpr.proc != null) {
7855                    if (false) {
7856                        if (cpr.name.flattenToShortString().equals(
7857                                "com.android.providers.calendar/.CalendarProvider2")) {
7858                            Slog.v(TAG, "****************** KILLING "
7859                                + cpr.name.flattenToShortString());
7860                            Process.killProcess(cpr.proc.pid);
7861                        }
7862                    }
7863                    boolean success = updateOomAdjLocked(cpr.proc);
7864                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7865                    // NOTE: there is still a race here where a signal could be
7866                    // pending on the process even though we managed to update its
7867                    // adj level.  Not sure what to do about this, but at least
7868                    // the race is now smaller.
7869                    if (!success) {
7870                        // Uh oh...  it looks like the provider's process
7871                        // has been killed on us.  We need to wait for a new
7872                        // process to be started, and make sure its death
7873                        // doesn't kill our process.
7874                        Slog.i(TAG,
7875                                "Existing provider " + cpr.name.flattenToShortString()
7876                                + " is crashing; detaching " + r);
7877                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7878                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7879                        if (!lastRef) {
7880                            // This wasn't the last ref our process had on
7881                            // the provider...  we have now been killed, bail.
7882                            return null;
7883                        }
7884                        providerRunning = false;
7885                        conn = null;
7886                    }
7887                }
7888
7889                Binder.restoreCallingIdentity(origId);
7890            }
7891
7892            boolean singleton;
7893            if (!providerRunning) {
7894                try {
7895                    cpi = AppGlobals.getPackageManager().
7896                        resolveContentProvider(name,
7897                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7898                } catch (RemoteException ex) {
7899                }
7900                if (cpi == null) {
7901                    return null;
7902                }
7903                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7904                        cpi.name, cpi.flags);
7905                if (singleton) {
7906                    userId = 0;
7907                }
7908                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7909
7910                String msg;
7911                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7912                    throw new SecurityException(msg);
7913                }
7914
7915                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
7916                        && !cpi.processName.equals("system")) {
7917                    // If this content provider does not run in the system
7918                    // process, and the system is not yet ready to run other
7919                    // processes, then fail fast instead of hanging.
7920                    throw new IllegalArgumentException(
7921                            "Attempt to launch content provider before system ready");
7922                }
7923
7924                // Make sure that the user who owns this provider is started.  If not,
7925                // we don't want to allow it to run.
7926                if (mStartedUsers.get(userId) == null) {
7927                    Slog.w(TAG, "Unable to launch app "
7928                            + cpi.applicationInfo.packageName + "/"
7929                            + cpi.applicationInfo.uid + " for provider "
7930                            + name + ": user " + userId + " is stopped");
7931                    return null;
7932                }
7933
7934                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7935                cpr = mProviderMap.getProviderByClass(comp, userId);
7936                final boolean firstClass = cpr == null;
7937                if (firstClass) {
7938                    try {
7939                        ApplicationInfo ai =
7940                            AppGlobals.getPackageManager().
7941                                getApplicationInfo(
7942                                        cpi.applicationInfo.packageName,
7943                                        STOCK_PM_FLAGS, userId);
7944                        if (ai == null) {
7945                            Slog.w(TAG, "No package info for content provider "
7946                                    + cpi.name);
7947                            return null;
7948                        }
7949                        ai = getAppInfoForUser(ai, userId);
7950                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
7951                    } catch (RemoteException ex) {
7952                        // pm is in same process, this will never happen.
7953                    }
7954                }
7955
7956                if (r != null && cpr.canRunHere(r)) {
7957                    // If this is a multiprocess provider, then just return its
7958                    // info and allow the caller to instantiate it.  Only do
7959                    // this if the provider is the same user as the caller's
7960                    // process, or can run as root (so can be in any process).
7961                    return cpr.newHolder(null);
7962                }
7963
7964                if (DEBUG_PROVIDER) {
7965                    RuntimeException e = new RuntimeException("here");
7966                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
7967                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
7968                }
7969
7970                // This is single process, and our app is now connecting to it.
7971                // See if we are already in the process of launching this
7972                // provider.
7973                final int N = mLaunchingProviders.size();
7974                int i;
7975                for (i=0; i<N; i++) {
7976                    if (mLaunchingProviders.get(i) == cpr) {
7977                        break;
7978                    }
7979                }
7980
7981                // If the provider is not already being launched, then get it
7982                // started.
7983                if (i >= N) {
7984                    final long origId = Binder.clearCallingIdentity();
7985
7986                    try {
7987                        // Content provider is now in use, its package can't be stopped.
7988                        try {
7989                            AppGlobals.getPackageManager().setPackageStoppedState(
7990                                    cpr.appInfo.packageName, false, userId);
7991                        } catch (RemoteException e) {
7992                        } catch (IllegalArgumentException e) {
7993                            Slog.w(TAG, "Failed trying to unstop package "
7994                                    + cpr.appInfo.packageName + ": " + e);
7995                        }
7996
7997                        // Use existing process if already started
7998                        ProcessRecord proc = getProcessRecordLocked(
7999                                cpi.processName, cpr.appInfo.uid, false);
8000                        if (proc != null && proc.thread != null) {
8001                            if (DEBUG_PROVIDER) {
8002                                Slog.d(TAG, "Installing in existing process " + proc);
8003                            }
8004                            proc.pubProviders.put(cpi.name, cpr);
8005                            try {
8006                                proc.thread.scheduleInstallProvider(cpi);
8007                            } catch (RemoteException e) {
8008                            }
8009                        } else {
8010                            proc = startProcessLocked(cpi.processName,
8011                                    cpr.appInfo, false, 0, "content provider",
8012                                    new ComponentName(cpi.applicationInfo.packageName,
8013                                            cpi.name), false, false, false);
8014                            if (proc == null) {
8015                                Slog.w(TAG, "Unable to launch app "
8016                                        + cpi.applicationInfo.packageName + "/"
8017                                        + cpi.applicationInfo.uid + " for provider "
8018                                        + name + ": process is bad");
8019                                return null;
8020                            }
8021                        }
8022                        cpr.launchingApp = proc;
8023                        mLaunchingProviders.add(cpr);
8024                    } finally {
8025                        Binder.restoreCallingIdentity(origId);
8026                    }
8027                }
8028
8029                // Make sure the provider is published (the same provider class
8030                // may be published under multiple names).
8031                if (firstClass) {
8032                    mProviderMap.putProviderByClass(comp, cpr);
8033                }
8034
8035                mProviderMap.putProviderByName(name, cpr);
8036                conn = incProviderCountLocked(r, cpr, token, stable);
8037                if (conn != null) {
8038                    conn.waiting = true;
8039                }
8040            }
8041        }
8042
8043        // Wait for the provider to be published...
8044        synchronized (cpr) {
8045            while (cpr.provider == null) {
8046                if (cpr.launchingApp == null) {
8047                    Slog.w(TAG, "Unable to launch app "
8048                            + cpi.applicationInfo.packageName + "/"
8049                            + cpi.applicationInfo.uid + " for provider "
8050                            + name + ": launching app became null");
8051                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8052                            UserHandle.getUserId(cpi.applicationInfo.uid),
8053                            cpi.applicationInfo.packageName,
8054                            cpi.applicationInfo.uid, name);
8055                    return null;
8056                }
8057                try {
8058                    if (DEBUG_MU) {
8059                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8060                                + cpr.launchingApp);
8061                    }
8062                    if (conn != null) {
8063                        conn.waiting = true;
8064                    }
8065                    cpr.wait();
8066                } catch (InterruptedException ex) {
8067                } finally {
8068                    if (conn != null) {
8069                        conn.waiting = false;
8070                    }
8071                }
8072            }
8073        }
8074        return cpr != null ? cpr.newHolder(conn) : null;
8075    }
8076
8077    public final ContentProviderHolder getContentProvider(
8078            IApplicationThread caller, String name, int userId, boolean stable) {
8079        enforceNotIsolatedCaller("getContentProvider");
8080        if (caller == null) {
8081            String msg = "null IApplicationThread when getting content provider "
8082                    + name;
8083            Slog.w(TAG, msg);
8084            throw new SecurityException(msg);
8085        }
8086
8087        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8088                false, true, "getContentProvider", null);
8089        return getContentProviderImpl(caller, name, null, stable, userId);
8090    }
8091
8092    public ContentProviderHolder getContentProviderExternal(
8093            String name, int userId, IBinder token) {
8094        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8095            "Do not have permission in call getContentProviderExternal()");
8096        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8097                false, true, "getContentProvider", null);
8098        return getContentProviderExternalUnchecked(name, token, userId);
8099    }
8100
8101    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8102            IBinder token, int userId) {
8103        return getContentProviderImpl(null, name, token, true, userId);
8104    }
8105
8106    /**
8107     * Drop a content provider from a ProcessRecord's bookkeeping
8108     */
8109    public void removeContentProvider(IBinder connection, boolean stable) {
8110        enforceNotIsolatedCaller("removeContentProvider");
8111        long ident = Binder.clearCallingIdentity();
8112        try {
8113            synchronized (this) {
8114                ContentProviderConnection conn;
8115                try {
8116                    conn = (ContentProviderConnection)connection;
8117                } catch (ClassCastException e) {
8118                    String msg ="removeContentProvider: " + connection
8119                            + " not a ContentProviderConnection";
8120                    Slog.w(TAG, msg);
8121                    throw new IllegalArgumentException(msg);
8122                }
8123                if (conn == null) {
8124                    throw new NullPointerException("connection is null");
8125                }
8126                if (decProviderCountLocked(conn, null, null, stable)) {
8127                    updateOomAdjLocked();
8128                }
8129            }
8130        } finally {
8131            Binder.restoreCallingIdentity(ident);
8132        }
8133    }
8134
8135    public void removeContentProviderExternal(String name, IBinder token) {
8136        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8137            "Do not have permission in call removeContentProviderExternal()");
8138        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8139    }
8140
8141    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8142        synchronized (this) {
8143            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8144            if(cpr == null) {
8145                //remove from mProvidersByClass
8146                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8147                return;
8148            }
8149
8150            //update content provider record entry info
8151            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8152            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8153            if (localCpr.hasExternalProcessHandles()) {
8154                if (localCpr.removeExternalProcessHandleLocked(token)) {
8155                    updateOomAdjLocked();
8156                } else {
8157                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8158                            + " with no external reference for token: "
8159                            + token + ".");
8160                }
8161            } else {
8162                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8163                        + " with no external references.");
8164            }
8165        }
8166    }
8167
8168    public final void publishContentProviders(IApplicationThread caller,
8169            List<ContentProviderHolder> providers) {
8170        if (providers == null) {
8171            return;
8172        }
8173
8174        enforceNotIsolatedCaller("publishContentProviders");
8175        synchronized (this) {
8176            final ProcessRecord r = getRecordForAppLocked(caller);
8177            if (DEBUG_MU)
8178                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8179            if (r == null) {
8180                throw new SecurityException(
8181                        "Unable to find app for caller " + caller
8182                      + " (pid=" + Binder.getCallingPid()
8183                      + ") when publishing content providers");
8184            }
8185
8186            final long origId = Binder.clearCallingIdentity();
8187
8188            final int N = providers.size();
8189            for (int i=0; i<N; i++) {
8190                ContentProviderHolder src = providers.get(i);
8191                if (src == null || src.info == null || src.provider == null) {
8192                    continue;
8193                }
8194                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8195                if (DEBUG_MU)
8196                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8197                if (dst != null) {
8198                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8199                    mProviderMap.putProviderByClass(comp, dst);
8200                    String names[] = dst.info.authority.split(";");
8201                    for (int j = 0; j < names.length; j++) {
8202                        mProviderMap.putProviderByName(names[j], dst);
8203                    }
8204
8205                    int NL = mLaunchingProviders.size();
8206                    int j;
8207                    for (j=0; j<NL; j++) {
8208                        if (mLaunchingProviders.get(j) == dst) {
8209                            mLaunchingProviders.remove(j);
8210                            j--;
8211                            NL--;
8212                        }
8213                    }
8214                    synchronized (dst) {
8215                        dst.provider = src.provider;
8216                        dst.proc = r;
8217                        dst.notifyAll();
8218                    }
8219                    updateOomAdjLocked(r);
8220                }
8221            }
8222
8223            Binder.restoreCallingIdentity(origId);
8224        }
8225    }
8226
8227    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8228        ContentProviderConnection conn;
8229        try {
8230            conn = (ContentProviderConnection)connection;
8231        } catch (ClassCastException e) {
8232            String msg ="refContentProvider: " + connection
8233                    + " not a ContentProviderConnection";
8234            Slog.w(TAG, msg);
8235            throw new IllegalArgumentException(msg);
8236        }
8237        if (conn == null) {
8238            throw new NullPointerException("connection is null");
8239        }
8240
8241        synchronized (this) {
8242            if (stable > 0) {
8243                conn.numStableIncs += stable;
8244            }
8245            stable = conn.stableCount + stable;
8246            if (stable < 0) {
8247                throw new IllegalStateException("stableCount < 0: " + stable);
8248            }
8249
8250            if (unstable > 0) {
8251                conn.numUnstableIncs += unstable;
8252            }
8253            unstable = conn.unstableCount + unstable;
8254            if (unstable < 0) {
8255                throw new IllegalStateException("unstableCount < 0: " + unstable);
8256            }
8257
8258            if ((stable+unstable) <= 0) {
8259                throw new IllegalStateException("ref counts can't go to zero here: stable="
8260                        + stable + " unstable=" + unstable);
8261            }
8262            conn.stableCount = stable;
8263            conn.unstableCount = unstable;
8264            return !conn.dead;
8265        }
8266    }
8267
8268    public void unstableProviderDied(IBinder connection) {
8269        ContentProviderConnection conn;
8270        try {
8271            conn = (ContentProviderConnection)connection;
8272        } catch (ClassCastException e) {
8273            String msg ="refContentProvider: " + connection
8274                    + " not a ContentProviderConnection";
8275            Slog.w(TAG, msg);
8276            throw new IllegalArgumentException(msg);
8277        }
8278        if (conn == null) {
8279            throw new NullPointerException("connection is null");
8280        }
8281
8282        // Safely retrieve the content provider associated with the connection.
8283        IContentProvider provider;
8284        synchronized (this) {
8285            provider = conn.provider.provider;
8286        }
8287
8288        if (provider == null) {
8289            // Um, yeah, we're way ahead of you.
8290            return;
8291        }
8292
8293        // Make sure the caller is being honest with us.
8294        if (provider.asBinder().pingBinder()) {
8295            // Er, no, still looks good to us.
8296            synchronized (this) {
8297                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8298                        + " says " + conn + " died, but we don't agree");
8299                return;
8300            }
8301        }
8302
8303        // Well look at that!  It's dead!
8304        synchronized (this) {
8305            if (conn.provider.provider != provider) {
8306                // But something changed...  good enough.
8307                return;
8308            }
8309
8310            ProcessRecord proc = conn.provider.proc;
8311            if (proc == null || proc.thread == null) {
8312                // Seems like the process is already cleaned up.
8313                return;
8314            }
8315
8316            // As far as we're concerned, this is just like receiving a
8317            // death notification...  just a bit prematurely.
8318            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8319                    + ") early provider death");
8320            final long ident = Binder.clearCallingIdentity();
8321            try {
8322                appDiedLocked(proc, proc.pid, proc.thread);
8323            } finally {
8324                Binder.restoreCallingIdentity(ident);
8325            }
8326        }
8327    }
8328
8329    @Override
8330    public void appNotRespondingViaProvider(IBinder connection) {
8331        enforceCallingPermission(
8332                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8333
8334        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8335        if (conn == null) {
8336            Slog.w(TAG, "ContentProviderConnection is null");
8337            return;
8338        }
8339
8340        final ProcessRecord host = conn.provider.proc;
8341        if (host == null) {
8342            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8343            return;
8344        }
8345
8346        final long token = Binder.clearCallingIdentity();
8347        try {
8348            appNotResponding(host, null, null, false, "ContentProvider not responding");
8349        } finally {
8350            Binder.restoreCallingIdentity(token);
8351        }
8352    }
8353
8354    public final void installSystemProviders() {
8355        List<ProviderInfo> providers;
8356        synchronized (this) {
8357            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8358            providers = generateApplicationProvidersLocked(app);
8359            if (providers != null) {
8360                for (int i=providers.size()-1; i>=0; i--) {
8361                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8362                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8363                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8364                                + ": not system .apk");
8365                        providers.remove(i);
8366                    }
8367                }
8368            }
8369        }
8370        if (providers != null) {
8371            mSystemThread.installSystemProviders(providers);
8372        }
8373
8374        mCoreSettingsObserver = new CoreSettingsObserver(this);
8375
8376        mUsageStatsService.monitorPackages();
8377    }
8378
8379    /**
8380     * Allows app to retrieve the MIME type of a URI without having permission
8381     * to access its content provider.
8382     *
8383     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8384     *
8385     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8386     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8387     */
8388    public String getProviderMimeType(Uri uri, int userId) {
8389        enforceNotIsolatedCaller("getProviderMimeType");
8390        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8391                userId, false, true, "getProviderMimeType", null);
8392        final String name = uri.getAuthority();
8393        final long ident = Binder.clearCallingIdentity();
8394        ContentProviderHolder holder = null;
8395
8396        try {
8397            holder = getContentProviderExternalUnchecked(name, null, userId);
8398            if (holder != null) {
8399                return holder.provider.getType(uri);
8400            }
8401        } catch (RemoteException e) {
8402            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8403            return null;
8404        } finally {
8405            if (holder != null) {
8406                removeContentProviderExternalUnchecked(name, null, userId);
8407            }
8408            Binder.restoreCallingIdentity(ident);
8409        }
8410
8411        return null;
8412    }
8413
8414    // =========================================================
8415    // GLOBAL MANAGEMENT
8416    // =========================================================
8417
8418    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8419            boolean isolated) {
8420        String proc = customProcess != null ? customProcess : info.processName;
8421        BatteryStatsImpl.Uid.Proc ps = null;
8422        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8423        int uid = info.uid;
8424        if (isolated) {
8425            int userId = UserHandle.getUserId(uid);
8426            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8427            while (true) {
8428                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8429                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8430                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8431                }
8432                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8433                mNextIsolatedProcessUid++;
8434                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8435                    // No process for this uid, use it.
8436                    break;
8437                }
8438                stepsLeft--;
8439                if (stepsLeft <= 0) {
8440                    return null;
8441                }
8442            }
8443        }
8444        return new ProcessRecord(stats, info, proc, uid);
8445    }
8446
8447    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8448        ProcessRecord app;
8449        if (!isolated) {
8450            app = getProcessRecordLocked(info.processName, info.uid, true);
8451        } else {
8452            app = null;
8453        }
8454
8455        if (app == null) {
8456            app = newProcessRecordLocked(info, null, isolated);
8457            mProcessNames.put(info.processName, app.uid, app);
8458            if (isolated) {
8459                mIsolatedProcesses.put(app.uid, app);
8460            }
8461            updateLruProcessLocked(app, false, null);
8462            updateOomAdjLocked();
8463        }
8464
8465        // This package really, really can not be stopped.
8466        try {
8467            AppGlobals.getPackageManager().setPackageStoppedState(
8468                    info.packageName, false, UserHandle.getUserId(app.uid));
8469        } catch (RemoteException e) {
8470        } catch (IllegalArgumentException e) {
8471            Slog.w(TAG, "Failed trying to unstop package "
8472                    + info.packageName + ": " + e);
8473        }
8474
8475        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8476                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8477            app.persistent = true;
8478            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8479        }
8480        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8481            mPersistentStartingProcesses.add(app);
8482            startProcessLocked(app, "added application", app.processName);
8483        }
8484
8485        return app;
8486    }
8487
8488    public void unhandledBack() {
8489        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8490                "unhandledBack()");
8491
8492        synchronized(this) {
8493            final long origId = Binder.clearCallingIdentity();
8494            try {
8495                getFocusedStack().unhandledBackLocked();
8496            } finally {
8497                Binder.restoreCallingIdentity(origId);
8498            }
8499        }
8500    }
8501
8502    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8503        enforceNotIsolatedCaller("openContentUri");
8504        final int userId = UserHandle.getCallingUserId();
8505        String name = uri.getAuthority();
8506        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8507        ParcelFileDescriptor pfd = null;
8508        if (cph != null) {
8509            // We record the binder invoker's uid in thread-local storage before
8510            // going to the content provider to open the file.  Later, in the code
8511            // that handles all permissions checks, we look for this uid and use
8512            // that rather than the Activity Manager's own uid.  The effect is that
8513            // we do the check against the caller's permissions even though it looks
8514            // to the content provider like the Activity Manager itself is making
8515            // the request.
8516            sCallerIdentity.set(new Identity(
8517                    Binder.getCallingPid(), Binder.getCallingUid()));
8518            try {
8519                pfd = cph.provider.openFile(null, uri, "r", null);
8520            } catch (FileNotFoundException e) {
8521                // do nothing; pfd will be returned null
8522            } finally {
8523                // Ensure that whatever happens, we clean up the identity state
8524                sCallerIdentity.remove();
8525            }
8526
8527            // We've got the fd now, so we're done with the provider.
8528            removeContentProviderExternalUnchecked(name, null, userId);
8529        } else {
8530            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8531        }
8532        return pfd;
8533    }
8534
8535    // Actually is sleeping or shutting down or whatever else in the future
8536    // is an inactive state.
8537    public boolean isSleepingOrShuttingDown() {
8538        return mSleeping || mShuttingDown;
8539    }
8540
8541    public boolean isSleeping() {
8542        return mSleeping;
8543    }
8544
8545    void goingToSleep() {
8546        synchronized(this) {
8547            mWentToSleep = true;
8548            updateEventDispatchingLocked();
8549            goToSleepIfNeededLocked();
8550        }
8551    }
8552
8553    void finishRunningVoiceLocked() {
8554        if (mRunningVoice) {
8555            mRunningVoice = false;
8556            goToSleepIfNeededLocked();
8557        }
8558    }
8559
8560    void goToSleepIfNeededLocked() {
8561        if (mWentToSleep && !mRunningVoice) {
8562            if (!mSleeping) {
8563                mSleeping = true;
8564                mStackSupervisor.goingToSleepLocked();
8565
8566                // Initialize the wake times of all processes.
8567                checkExcessivePowerUsageLocked(false);
8568                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8569                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8570                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8571            }
8572        }
8573    }
8574
8575    @Override
8576    public boolean shutdown(int timeout) {
8577        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8578                != PackageManager.PERMISSION_GRANTED) {
8579            throw new SecurityException("Requires permission "
8580                    + android.Manifest.permission.SHUTDOWN);
8581        }
8582
8583        boolean timedout = false;
8584
8585        synchronized(this) {
8586            mShuttingDown = true;
8587            updateEventDispatchingLocked();
8588            timedout = mStackSupervisor.shutdownLocked(timeout);
8589        }
8590
8591        mAppOpsService.shutdown();
8592        mUsageStatsService.shutdown();
8593        mBatteryStatsService.shutdown();
8594        synchronized (this) {
8595            mProcessStats.shutdownLocked();
8596        }
8597
8598        return timedout;
8599    }
8600
8601    public final void activitySlept(IBinder token) {
8602        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8603
8604        final long origId = Binder.clearCallingIdentity();
8605
8606        synchronized (this) {
8607            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8608            if (r != null) {
8609                mStackSupervisor.activitySleptLocked(r);
8610            }
8611        }
8612
8613        Binder.restoreCallingIdentity(origId);
8614    }
8615
8616    void logLockScreen(String msg) {
8617        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8618                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8619                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8620                mStackSupervisor.mDismissKeyguardOnNextActivity);
8621    }
8622
8623    private void comeOutOfSleepIfNeededLocked() {
8624        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
8625            if (mSleeping) {
8626                mSleeping = false;
8627                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8628            }
8629        }
8630    }
8631
8632    void wakingUp() {
8633        synchronized(this) {
8634            mWentToSleep = false;
8635            updateEventDispatchingLocked();
8636            comeOutOfSleepIfNeededLocked();
8637        }
8638    }
8639
8640    void startRunningVoiceLocked() {
8641        if (!mRunningVoice) {
8642            mRunningVoice = true;
8643            comeOutOfSleepIfNeededLocked();
8644        }
8645    }
8646
8647    private void updateEventDispatchingLocked() {
8648        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8649    }
8650
8651    public void setLockScreenShown(boolean shown) {
8652        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8653                != PackageManager.PERMISSION_GRANTED) {
8654            throw new SecurityException("Requires permission "
8655                    + android.Manifest.permission.DEVICE_POWER);
8656        }
8657
8658        synchronized(this) {
8659            long ident = Binder.clearCallingIdentity();
8660            try {
8661                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8662                mLockScreenShown = shown;
8663                comeOutOfSleepIfNeededLocked();
8664            } finally {
8665                Binder.restoreCallingIdentity(ident);
8666            }
8667        }
8668    }
8669
8670    public void stopAppSwitches() {
8671        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8672                != PackageManager.PERMISSION_GRANTED) {
8673            throw new SecurityException("Requires permission "
8674                    + android.Manifest.permission.STOP_APP_SWITCHES);
8675        }
8676
8677        synchronized(this) {
8678            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8679                    + APP_SWITCH_DELAY_TIME;
8680            mDidAppSwitch = false;
8681            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8682            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8683            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8684        }
8685    }
8686
8687    public void resumeAppSwitches() {
8688        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8689                != PackageManager.PERMISSION_GRANTED) {
8690            throw new SecurityException("Requires permission "
8691                    + android.Manifest.permission.STOP_APP_SWITCHES);
8692        }
8693
8694        synchronized(this) {
8695            // Note that we don't execute any pending app switches... we will
8696            // let those wait until either the timeout, or the next start
8697            // activity request.
8698            mAppSwitchesAllowedTime = 0;
8699        }
8700    }
8701
8702    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8703            String name) {
8704        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8705            return true;
8706        }
8707
8708        final int perm = checkComponentPermission(
8709                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8710                callingUid, -1, true);
8711        if (perm == PackageManager.PERMISSION_GRANTED) {
8712            return true;
8713        }
8714
8715        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8716        return false;
8717    }
8718
8719    public void setDebugApp(String packageName, boolean waitForDebugger,
8720            boolean persistent) {
8721        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8722                "setDebugApp()");
8723
8724        long ident = Binder.clearCallingIdentity();
8725        try {
8726            // Note that this is not really thread safe if there are multiple
8727            // callers into it at the same time, but that's not a situation we
8728            // care about.
8729            if (persistent) {
8730                final ContentResolver resolver = mContext.getContentResolver();
8731                Settings.Global.putString(
8732                    resolver, Settings.Global.DEBUG_APP,
8733                    packageName);
8734                Settings.Global.putInt(
8735                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8736                    waitForDebugger ? 1 : 0);
8737            }
8738
8739            synchronized (this) {
8740                if (!persistent) {
8741                    mOrigDebugApp = mDebugApp;
8742                    mOrigWaitForDebugger = mWaitForDebugger;
8743                }
8744                mDebugApp = packageName;
8745                mWaitForDebugger = waitForDebugger;
8746                mDebugTransient = !persistent;
8747                if (packageName != null) {
8748                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8749                            false, UserHandle.USER_ALL, "set debug app");
8750                }
8751            }
8752        } finally {
8753            Binder.restoreCallingIdentity(ident);
8754        }
8755    }
8756
8757    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8758        synchronized (this) {
8759            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8760            if (!isDebuggable) {
8761                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8762                    throw new SecurityException("Process not debuggable: " + app.packageName);
8763                }
8764            }
8765
8766            mOpenGlTraceApp = processName;
8767        }
8768    }
8769
8770    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8771            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8772        synchronized (this) {
8773            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8774            if (!isDebuggable) {
8775                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8776                    throw new SecurityException("Process not debuggable: " + app.packageName);
8777                }
8778            }
8779            mProfileApp = processName;
8780            mProfileFile = profileFile;
8781            if (mProfileFd != null) {
8782                try {
8783                    mProfileFd.close();
8784                } catch (IOException e) {
8785                }
8786                mProfileFd = null;
8787            }
8788            mProfileFd = profileFd;
8789            mProfileType = 0;
8790            mAutoStopProfiler = autoStopProfiler;
8791        }
8792    }
8793
8794    @Override
8795    public void setAlwaysFinish(boolean enabled) {
8796        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8797                "setAlwaysFinish()");
8798
8799        Settings.Global.putInt(
8800                mContext.getContentResolver(),
8801                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8802
8803        synchronized (this) {
8804            mAlwaysFinishActivities = enabled;
8805        }
8806    }
8807
8808    @Override
8809    public void setActivityController(IActivityController controller) {
8810        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8811                "setActivityController()");
8812        synchronized (this) {
8813            mController = controller;
8814            Watchdog.getInstance().setActivityController(controller);
8815        }
8816    }
8817
8818    @Override
8819    public void setUserIsMonkey(boolean userIsMonkey) {
8820        synchronized (this) {
8821            synchronized (mPidsSelfLocked) {
8822                final int callingPid = Binder.getCallingPid();
8823                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8824                if (precessRecord == null) {
8825                    throw new SecurityException("Unknown process: " + callingPid);
8826                }
8827                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8828                    throw new SecurityException("Only an instrumentation process "
8829                            + "with a UiAutomation can call setUserIsMonkey");
8830                }
8831            }
8832            mUserIsMonkey = userIsMonkey;
8833        }
8834    }
8835
8836    @Override
8837    public boolean isUserAMonkey() {
8838        synchronized (this) {
8839            // If there is a controller also implies the user is a monkey.
8840            return (mUserIsMonkey || mController != null);
8841        }
8842    }
8843
8844    public void requestBugReport() {
8845        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8846        SystemProperties.set("ctl.start", "bugreport");
8847    }
8848
8849    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8850        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8851    }
8852
8853    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8854        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8855            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8856        }
8857        return KEY_DISPATCHING_TIMEOUT;
8858    }
8859
8860    @Override
8861    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8862        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8863                != PackageManager.PERMISSION_GRANTED) {
8864            throw new SecurityException("Requires permission "
8865                    + android.Manifest.permission.FILTER_EVENTS);
8866        }
8867        ProcessRecord proc;
8868        long timeout;
8869        synchronized (this) {
8870            synchronized (mPidsSelfLocked) {
8871                proc = mPidsSelfLocked.get(pid);
8872            }
8873            timeout = getInputDispatchingTimeoutLocked(proc);
8874        }
8875
8876        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8877            return -1;
8878        }
8879
8880        return timeout;
8881    }
8882
8883    /**
8884     * Handle input dispatching timeouts.
8885     * Returns whether input dispatching should be aborted or not.
8886     */
8887    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8888            final ActivityRecord activity, final ActivityRecord parent,
8889            final boolean aboveSystem, String reason) {
8890        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8891                != PackageManager.PERMISSION_GRANTED) {
8892            throw new SecurityException("Requires permission "
8893                    + android.Manifest.permission.FILTER_EVENTS);
8894        }
8895
8896        final String annotation;
8897        if (reason == null) {
8898            annotation = "Input dispatching timed out";
8899        } else {
8900            annotation = "Input dispatching timed out (" + reason + ")";
8901        }
8902
8903        if (proc != null) {
8904            synchronized (this) {
8905                if (proc.debugging) {
8906                    return false;
8907                }
8908
8909                if (mDidDexOpt) {
8910                    // Give more time since we were dexopting.
8911                    mDidDexOpt = false;
8912                    return false;
8913                }
8914
8915                if (proc.instrumentationClass != null) {
8916                    Bundle info = new Bundle();
8917                    info.putString("shortMsg", "keyDispatchingTimedOut");
8918                    info.putString("longMsg", annotation);
8919                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8920                    return true;
8921                }
8922            }
8923            mHandler.post(new Runnable() {
8924                @Override
8925                public void run() {
8926                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
8927                }
8928            });
8929        }
8930
8931        return true;
8932    }
8933
8934    public Bundle getAssistContextExtras(int requestType) {
8935        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
8936                "getAssistContextExtras()");
8937        PendingAssistExtras pae;
8938        Bundle extras = new Bundle();
8939        synchronized (this) {
8940            ActivityRecord activity = getFocusedStack().mResumedActivity;
8941            if (activity == null) {
8942                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
8943                return null;
8944            }
8945            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
8946            if (activity.app == null || activity.app.thread == null) {
8947                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
8948                return extras;
8949            }
8950            if (activity.app.pid == Binder.getCallingPid()) {
8951                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
8952                return extras;
8953            }
8954            pae = new PendingAssistExtras(activity);
8955            try {
8956                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
8957                        requestType);
8958                mPendingAssistExtras.add(pae);
8959                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
8960            } catch (RemoteException e) {
8961                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
8962                return extras;
8963            }
8964        }
8965        synchronized (pae) {
8966            while (!pae.haveResult) {
8967                try {
8968                    pae.wait();
8969                } catch (InterruptedException e) {
8970                }
8971            }
8972            if (pae.result != null) {
8973                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
8974            }
8975        }
8976        synchronized (this) {
8977            mPendingAssistExtras.remove(pae);
8978            mHandler.removeCallbacks(pae);
8979        }
8980        return extras;
8981    }
8982
8983    public void reportAssistContextExtras(IBinder token, Bundle extras) {
8984        PendingAssistExtras pae = (PendingAssistExtras)token;
8985        synchronized (pae) {
8986            pae.result = extras;
8987            pae.haveResult = true;
8988            pae.notifyAll();
8989        }
8990    }
8991
8992    public void registerProcessObserver(IProcessObserver observer) {
8993        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8994                "registerProcessObserver()");
8995        synchronized (this) {
8996            mProcessObservers.register(observer);
8997        }
8998    }
8999
9000    @Override
9001    public void unregisterProcessObserver(IProcessObserver observer) {
9002        synchronized (this) {
9003            mProcessObservers.unregister(observer);
9004        }
9005    }
9006
9007    @Override
9008    public boolean convertFromTranslucent(IBinder token) {
9009        final long origId = Binder.clearCallingIdentity();
9010        try {
9011            synchronized (this) {
9012                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9013                if (r == null) {
9014                    return false;
9015                }
9016                if (r.changeWindowTranslucency(true)) {
9017                    mWindowManager.setAppFullscreen(token, true);
9018                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9019                    return true;
9020                }
9021                return false;
9022            }
9023        } finally {
9024            Binder.restoreCallingIdentity(origId);
9025        }
9026    }
9027
9028    @Override
9029    public boolean convertToTranslucent(IBinder token) {
9030        final long origId = Binder.clearCallingIdentity();
9031        try {
9032            synchronized (this) {
9033                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9034                if (r == null) {
9035                    return false;
9036                }
9037                if (r.changeWindowTranslucency(false)) {
9038                    r.task.stack.convertToTranslucent(r);
9039                    mWindowManager.setAppFullscreen(token, false);
9040                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9041                    return true;
9042                }
9043                return false;
9044            }
9045        } finally {
9046            Binder.restoreCallingIdentity(origId);
9047        }
9048    }
9049
9050    @Override
9051    public void setImmersive(IBinder token, boolean immersive) {
9052        synchronized(this) {
9053            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9054            if (r == null) {
9055                throw new IllegalArgumentException();
9056            }
9057            r.immersive = immersive;
9058
9059            // update associated state if we're frontmost
9060            if (r == mFocusedActivity) {
9061                if (DEBUG_IMMERSIVE) {
9062                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9063                }
9064                applyUpdateLockStateLocked(r);
9065            }
9066        }
9067    }
9068
9069    @Override
9070    public boolean isImmersive(IBinder token) {
9071        synchronized (this) {
9072            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9073            if (r == null) {
9074                throw new IllegalArgumentException();
9075            }
9076            return r.immersive;
9077        }
9078    }
9079
9080    public boolean isTopActivityImmersive() {
9081        enforceNotIsolatedCaller("startActivity");
9082        synchronized (this) {
9083            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9084            return (r != null) ? r.immersive : false;
9085        }
9086    }
9087
9088    public final void enterSafeMode() {
9089        synchronized(this) {
9090            // It only makes sense to do this before the system is ready
9091            // and started launching other packages.
9092            if (!mSystemReady) {
9093                try {
9094                    AppGlobals.getPackageManager().enterSafeMode();
9095                } catch (RemoteException e) {
9096                }
9097            }
9098
9099            mSafeMode = true;
9100        }
9101    }
9102
9103    public final void showSafeModeOverlay() {
9104        View v = LayoutInflater.from(mContext).inflate(
9105                com.android.internal.R.layout.safe_mode, null);
9106        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9107        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9108        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9109        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9110        lp.gravity = Gravity.BOTTOM | Gravity.START;
9111        lp.format = v.getBackground().getOpacity();
9112        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9113                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9114        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9115        ((WindowManager)mContext.getSystemService(
9116                Context.WINDOW_SERVICE)).addView(v, lp);
9117    }
9118
9119    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9120        if (!(sender instanceof PendingIntentRecord)) {
9121            return;
9122        }
9123        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9124        synchronized (stats) {
9125            if (mBatteryStatsService.isOnBattery()) {
9126                mBatteryStatsService.enforceCallingPermission();
9127                PendingIntentRecord rec = (PendingIntentRecord)sender;
9128                int MY_UID = Binder.getCallingUid();
9129                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9130                BatteryStatsImpl.Uid.Pkg pkg =
9131                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9132                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9133                pkg.incWakeupsLocked();
9134            }
9135        }
9136    }
9137
9138    public boolean killPids(int[] pids, String pReason, boolean secure) {
9139        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9140            throw new SecurityException("killPids only available to the system");
9141        }
9142        String reason = (pReason == null) ? "Unknown" : pReason;
9143        // XXX Note: don't acquire main activity lock here, because the window
9144        // manager calls in with its locks held.
9145
9146        boolean killed = false;
9147        synchronized (mPidsSelfLocked) {
9148            int[] types = new int[pids.length];
9149            int worstType = 0;
9150            for (int i=0; i<pids.length; i++) {
9151                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9152                if (proc != null) {
9153                    int type = proc.setAdj;
9154                    types[i] = type;
9155                    if (type > worstType) {
9156                        worstType = type;
9157                    }
9158                }
9159            }
9160
9161            // If the worst oom_adj is somewhere in the cached proc LRU range,
9162            // then constrain it so we will kill all cached procs.
9163            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9164                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9165                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9166            }
9167
9168            // If this is not a secure call, don't let it kill processes that
9169            // are important.
9170            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9171                worstType = ProcessList.SERVICE_ADJ;
9172            }
9173
9174            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9175            for (int i=0; i<pids.length; i++) {
9176                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9177                if (proc == null) {
9178                    continue;
9179                }
9180                int adj = proc.setAdj;
9181                if (adj >= worstType && !proc.killedByAm) {
9182                    killUnneededProcessLocked(proc, reason);
9183                    killed = true;
9184                }
9185            }
9186        }
9187        return killed;
9188    }
9189
9190    @Override
9191    public void killUid(int uid, String reason) {
9192        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9193            throw new SecurityException("killUid only available to the system");
9194        }
9195        synchronized (this) {
9196            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9197                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9198                    reason != null ? reason : "kill uid");
9199        }
9200    }
9201
9202    @Override
9203    public boolean killProcessesBelowForeground(String reason) {
9204        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9205            throw new SecurityException("killProcessesBelowForeground() only available to system");
9206        }
9207
9208        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9209    }
9210
9211    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9212        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9213            throw new SecurityException("killProcessesBelowAdj() only available to system");
9214        }
9215
9216        boolean killed = false;
9217        synchronized (mPidsSelfLocked) {
9218            final int size = mPidsSelfLocked.size();
9219            for (int i = 0; i < size; i++) {
9220                final int pid = mPidsSelfLocked.keyAt(i);
9221                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9222                if (proc == null) continue;
9223
9224                final int adj = proc.setAdj;
9225                if (adj > belowAdj && !proc.killedByAm) {
9226                    killUnneededProcessLocked(proc, reason);
9227                    killed = true;
9228                }
9229            }
9230        }
9231        return killed;
9232    }
9233
9234    @Override
9235    public void hang(final IBinder who, boolean allowRestart) {
9236        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9237                != PackageManager.PERMISSION_GRANTED) {
9238            throw new SecurityException("Requires permission "
9239                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9240        }
9241
9242        final IBinder.DeathRecipient death = new DeathRecipient() {
9243            @Override
9244            public void binderDied() {
9245                synchronized (this) {
9246                    notifyAll();
9247                }
9248            }
9249        };
9250
9251        try {
9252            who.linkToDeath(death, 0);
9253        } catch (RemoteException e) {
9254            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9255            return;
9256        }
9257
9258        synchronized (this) {
9259            Watchdog.getInstance().setAllowRestart(allowRestart);
9260            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9261            synchronized (death) {
9262                while (who.isBinderAlive()) {
9263                    try {
9264                        death.wait();
9265                    } catch (InterruptedException e) {
9266                    }
9267                }
9268            }
9269            Watchdog.getInstance().setAllowRestart(true);
9270        }
9271    }
9272
9273    @Override
9274    public void restart() {
9275        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9276                != PackageManager.PERMISSION_GRANTED) {
9277            throw new SecurityException("Requires permission "
9278                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9279        }
9280
9281        Log.i(TAG, "Sending shutdown broadcast...");
9282
9283        BroadcastReceiver br = new BroadcastReceiver() {
9284            @Override public void onReceive(Context context, Intent intent) {
9285                // Now the broadcast is done, finish up the low-level shutdown.
9286                Log.i(TAG, "Shutting down activity manager...");
9287                shutdown(10000);
9288                Log.i(TAG, "Shutdown complete, restarting!");
9289                Process.killProcess(Process.myPid());
9290                System.exit(10);
9291            }
9292        };
9293
9294        // First send the high-level shut down broadcast.
9295        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9296        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9297        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9298        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9299        mContext.sendOrderedBroadcastAsUser(intent,
9300                UserHandle.ALL, null, br, mHandler, 0, null, null);
9301        */
9302        br.onReceive(mContext, intent);
9303    }
9304
9305    private long getLowRamTimeSinceIdle(long now) {
9306        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9307    }
9308
9309    @Override
9310    public void performIdleMaintenance() {
9311        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9312                != PackageManager.PERMISSION_GRANTED) {
9313            throw new SecurityException("Requires permission "
9314                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9315        }
9316
9317        synchronized (this) {
9318            final long now = SystemClock.uptimeMillis();
9319            final long timeSinceLastIdle = now - mLastIdleTime;
9320            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9321            mLastIdleTime = now;
9322            mLowRamTimeSinceLastIdle = 0;
9323            if (mLowRamStartTime != 0) {
9324                mLowRamStartTime = now;
9325            }
9326
9327            StringBuilder sb = new StringBuilder(128);
9328            sb.append("Idle maintenance over ");
9329            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9330            sb.append(" low RAM for ");
9331            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9332            Slog.i(TAG, sb.toString());
9333
9334            // If at least 1/3 of our time since the last idle period has been spent
9335            // with RAM low, then we want to kill processes.
9336            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9337
9338            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9339                ProcessRecord proc = mLruProcesses.get(i);
9340                if (proc.notCachedSinceIdle) {
9341                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9342                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9343                        if (doKilling && proc.initialIdlePss != 0
9344                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9345                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9346                                    + " from " + proc.initialIdlePss + ")");
9347                        }
9348                    }
9349                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9350                    proc.notCachedSinceIdle = true;
9351                    proc.initialIdlePss = 0;
9352                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9353                            isSleeping(), now);
9354                }
9355            }
9356
9357            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9358            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9359        }
9360    }
9361
9362    private void retrieveSettings() {
9363        final ContentResolver resolver = mContext.getContentResolver();
9364        String debugApp = Settings.Global.getString(
9365            resolver, Settings.Global.DEBUG_APP);
9366        boolean waitForDebugger = Settings.Global.getInt(
9367            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9368        boolean alwaysFinishActivities = Settings.Global.getInt(
9369            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9370        boolean forceRtl = Settings.Global.getInt(
9371                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9372        // Transfer any global setting for forcing RTL layout, into a System Property
9373        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9374
9375        Configuration configuration = new Configuration();
9376        Settings.System.getConfiguration(resolver, configuration);
9377        if (forceRtl) {
9378            // This will take care of setting the correct layout direction flags
9379            configuration.setLayoutDirection(configuration.locale);
9380        }
9381
9382        synchronized (this) {
9383            mDebugApp = mOrigDebugApp = debugApp;
9384            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9385            mAlwaysFinishActivities = alwaysFinishActivities;
9386            // This happens before any activities are started, so we can
9387            // change mConfiguration in-place.
9388            updateConfigurationLocked(configuration, null, false, true);
9389            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9390        }
9391    }
9392
9393    public boolean testIsSystemReady() {
9394        // no need to synchronize(this) just to read & return the value
9395        return mSystemReady;
9396    }
9397
9398    private static File getCalledPreBootReceiversFile() {
9399        File dataDir = Environment.getDataDirectory();
9400        File systemDir = new File(dataDir, "system");
9401        File fname = new File(systemDir, "called_pre_boots.dat");
9402        return fname;
9403    }
9404
9405    static final int LAST_DONE_VERSION = 10000;
9406
9407    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9408        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9409        File file = getCalledPreBootReceiversFile();
9410        FileInputStream fis = null;
9411        try {
9412            fis = new FileInputStream(file);
9413            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9414            int fvers = dis.readInt();
9415            if (fvers == LAST_DONE_VERSION) {
9416                String vers = dis.readUTF();
9417                String codename = dis.readUTF();
9418                String build = dis.readUTF();
9419                if (android.os.Build.VERSION.RELEASE.equals(vers)
9420                        && android.os.Build.VERSION.CODENAME.equals(codename)
9421                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9422                    int num = dis.readInt();
9423                    while (num > 0) {
9424                        num--;
9425                        String pkg = dis.readUTF();
9426                        String cls = dis.readUTF();
9427                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9428                    }
9429                }
9430            }
9431        } catch (FileNotFoundException e) {
9432        } catch (IOException e) {
9433            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9434        } finally {
9435            if (fis != null) {
9436                try {
9437                    fis.close();
9438                } catch (IOException e) {
9439                }
9440            }
9441        }
9442        return lastDoneReceivers;
9443    }
9444
9445    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9446        File file = getCalledPreBootReceiversFile();
9447        FileOutputStream fos = null;
9448        DataOutputStream dos = null;
9449        try {
9450            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9451            fos = new FileOutputStream(file);
9452            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9453            dos.writeInt(LAST_DONE_VERSION);
9454            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9455            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9456            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9457            dos.writeInt(list.size());
9458            for (int i=0; i<list.size(); i++) {
9459                dos.writeUTF(list.get(i).getPackageName());
9460                dos.writeUTF(list.get(i).getClassName());
9461            }
9462        } catch (IOException e) {
9463            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9464            file.delete();
9465        } finally {
9466            FileUtils.sync(fos);
9467            if (dos != null) {
9468                try {
9469                    dos.close();
9470                } catch (IOException e) {
9471                    // TODO Auto-generated catch block
9472                    e.printStackTrace();
9473                }
9474            }
9475        }
9476    }
9477
9478    public void systemReady(final Runnable goingCallback) {
9479        synchronized(this) {
9480            if (mSystemReady) {
9481                if (goingCallback != null) goingCallback.run();
9482                return;
9483            }
9484
9485            // Check to see if there are any update receivers to run.
9486            if (!mDidUpdate) {
9487                if (mWaitingUpdate) {
9488                    return;
9489                }
9490                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9491                List<ResolveInfo> ris = null;
9492                try {
9493                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9494                            intent, null, 0, 0);
9495                } catch (RemoteException e) {
9496                }
9497                if (ris != null) {
9498                    for (int i=ris.size()-1; i>=0; i--) {
9499                        if ((ris.get(i).activityInfo.applicationInfo.flags
9500                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9501                            ris.remove(i);
9502                        }
9503                    }
9504                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9505
9506                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9507
9508                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9509                    for (int i=0; i<ris.size(); i++) {
9510                        ActivityInfo ai = ris.get(i).activityInfo;
9511                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9512                        if (lastDoneReceivers.contains(comp)) {
9513                            // We already did the pre boot receiver for this app with the current
9514                            // platform version, so don't do it again...
9515                            ris.remove(i);
9516                            i--;
9517                            // ...however, do keep it as one that has been done, so we don't
9518                            // forget about it when rewriting the file of last done receivers.
9519                            doneReceivers.add(comp);
9520                        }
9521                    }
9522
9523                    final int[] users = getUsersLocked();
9524                    for (int i=0; i<ris.size(); i++) {
9525                        ActivityInfo ai = ris.get(i).activityInfo;
9526                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9527                        doneReceivers.add(comp);
9528                        intent.setComponent(comp);
9529                        for (int j=0; j<users.length; j++) {
9530                            IIntentReceiver finisher = null;
9531                            if (i == ris.size()-1 && j == users.length-1) {
9532                                finisher = new IIntentReceiver.Stub() {
9533                                    public void performReceive(Intent intent, int resultCode,
9534                                            String data, Bundle extras, boolean ordered,
9535                                            boolean sticky, int sendingUser) {
9536                                        // The raw IIntentReceiver interface is called
9537                                        // with the AM lock held, so redispatch to
9538                                        // execute our code without the lock.
9539                                        mHandler.post(new Runnable() {
9540                                            public void run() {
9541                                                synchronized (ActivityManagerService.this) {
9542                                                    mDidUpdate = true;
9543                                                }
9544                                                writeLastDonePreBootReceivers(doneReceivers);
9545                                                showBootMessage(mContext.getText(
9546                                                        R.string.android_upgrading_complete),
9547                                                        false);
9548                                                systemReady(goingCallback);
9549                                            }
9550                                        });
9551                                    }
9552                                };
9553                            }
9554                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9555                                    + " for user " + users[j]);
9556                            broadcastIntentLocked(null, null, intent, null, finisher,
9557                                    0, null, null, null, AppOpsManager.OP_NONE,
9558                                    true, false, MY_PID, Process.SYSTEM_UID,
9559                                    users[j]);
9560                            if (finisher != null) {
9561                                mWaitingUpdate = true;
9562                            }
9563                        }
9564                    }
9565                }
9566                if (mWaitingUpdate) {
9567                    return;
9568                }
9569                mDidUpdate = true;
9570            }
9571
9572            mAppOpsService.systemReady();
9573            mUsageStatsService.systemReady();
9574            mSystemReady = true;
9575        }
9576
9577        ArrayList<ProcessRecord> procsToKill = null;
9578        synchronized(mPidsSelfLocked) {
9579            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9580                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9581                if (!isAllowedWhileBooting(proc.info)){
9582                    if (procsToKill == null) {
9583                        procsToKill = new ArrayList<ProcessRecord>();
9584                    }
9585                    procsToKill.add(proc);
9586                }
9587            }
9588        }
9589
9590        synchronized(this) {
9591            if (procsToKill != null) {
9592                for (int i=procsToKill.size()-1; i>=0; i--) {
9593                    ProcessRecord proc = procsToKill.get(i);
9594                    Slog.i(TAG, "Removing system update proc: " + proc);
9595                    removeProcessLocked(proc, true, false, "system update done");
9596                }
9597            }
9598
9599            // Now that we have cleaned up any update processes, we
9600            // are ready to start launching real processes and know that
9601            // we won't trample on them any more.
9602            mProcessesReady = true;
9603        }
9604
9605        Slog.i(TAG, "System now ready");
9606        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9607            SystemClock.uptimeMillis());
9608
9609        synchronized(this) {
9610            // Make sure we have no pre-ready processes sitting around.
9611
9612            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9613                ResolveInfo ri = mContext.getPackageManager()
9614                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9615                                STOCK_PM_FLAGS);
9616                CharSequence errorMsg = null;
9617                if (ri != null) {
9618                    ActivityInfo ai = ri.activityInfo;
9619                    ApplicationInfo app = ai.applicationInfo;
9620                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9621                        mTopAction = Intent.ACTION_FACTORY_TEST;
9622                        mTopData = null;
9623                        mTopComponent = new ComponentName(app.packageName,
9624                                ai.name);
9625                    } else {
9626                        errorMsg = mContext.getResources().getText(
9627                                com.android.internal.R.string.factorytest_not_system);
9628                    }
9629                } else {
9630                    errorMsg = mContext.getResources().getText(
9631                            com.android.internal.R.string.factorytest_no_action);
9632                }
9633                if (errorMsg != null) {
9634                    mTopAction = null;
9635                    mTopData = null;
9636                    mTopComponent = null;
9637                    Message msg = Message.obtain();
9638                    msg.what = SHOW_FACTORY_ERROR_MSG;
9639                    msg.getData().putCharSequence("msg", errorMsg);
9640                    mHandler.sendMessage(msg);
9641                }
9642            }
9643        }
9644
9645        retrieveSettings();
9646
9647        synchronized (this) {
9648            readGrantedUriPermissionsLocked();
9649        }
9650
9651        if (goingCallback != null) goingCallback.run();
9652
9653        mSystemServiceManager.startUser(mCurrentUserId);
9654
9655        synchronized (this) {
9656            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9657                try {
9658                    List apps = AppGlobals.getPackageManager().
9659                        getPersistentApplications(STOCK_PM_FLAGS);
9660                    if (apps != null) {
9661                        int N = apps.size();
9662                        int i;
9663                        for (i=0; i<N; i++) {
9664                            ApplicationInfo info
9665                                = (ApplicationInfo)apps.get(i);
9666                            if (info != null &&
9667                                    !info.packageName.equals("android")) {
9668                                addAppLocked(info, false);
9669                            }
9670                        }
9671                    }
9672                } catch (RemoteException ex) {
9673                    // pm is in same process, this will never happen.
9674                }
9675            }
9676
9677            // Start up initial activity.
9678            mBooting = true;
9679
9680            try {
9681                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9682                    Message msg = Message.obtain();
9683                    msg.what = SHOW_UID_ERROR_MSG;
9684                    mHandler.sendMessage(msg);
9685                }
9686            } catch (RemoteException e) {
9687            }
9688
9689            long ident = Binder.clearCallingIdentity();
9690            try {
9691                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9692                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9693                        | Intent.FLAG_RECEIVER_FOREGROUND);
9694                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9695                broadcastIntentLocked(null, null, intent,
9696                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9697                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9698                intent = new Intent(Intent.ACTION_USER_STARTING);
9699                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9700                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9701                broadcastIntentLocked(null, null, intent,
9702                        null, new IIntentReceiver.Stub() {
9703                            @Override
9704                            public void performReceive(Intent intent, int resultCode, String data,
9705                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9706                                    throws RemoteException {
9707                            }
9708                        }, 0, null, null,
9709                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9710                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9711            } catch (Throwable t) {
9712                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
9713            } finally {
9714                Binder.restoreCallingIdentity(ident);
9715            }
9716            mStackSupervisor.resumeTopActivitiesLocked();
9717            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9718        }
9719    }
9720
9721    private boolean makeAppCrashingLocked(ProcessRecord app,
9722            String shortMsg, String longMsg, String stackTrace) {
9723        app.crashing = true;
9724        app.crashingReport = generateProcessError(app,
9725                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9726        startAppProblemLocked(app);
9727        app.stopFreezingAllLocked();
9728        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9729    }
9730
9731    private void makeAppNotRespondingLocked(ProcessRecord app,
9732            String activity, String shortMsg, String longMsg) {
9733        app.notResponding = true;
9734        app.notRespondingReport = generateProcessError(app,
9735                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9736                activity, shortMsg, longMsg, null);
9737        startAppProblemLocked(app);
9738        app.stopFreezingAllLocked();
9739    }
9740
9741    /**
9742     * Generate a process error record, suitable for attachment to a ProcessRecord.
9743     *
9744     * @param app The ProcessRecord in which the error occurred.
9745     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9746     *                      ActivityManager.AppErrorStateInfo
9747     * @param activity The activity associated with the crash, if known.
9748     * @param shortMsg Short message describing the crash.
9749     * @param longMsg Long message describing the crash.
9750     * @param stackTrace Full crash stack trace, may be null.
9751     *
9752     * @return Returns a fully-formed AppErrorStateInfo record.
9753     */
9754    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9755            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9756        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9757
9758        report.condition = condition;
9759        report.processName = app.processName;
9760        report.pid = app.pid;
9761        report.uid = app.info.uid;
9762        report.tag = activity;
9763        report.shortMsg = shortMsg;
9764        report.longMsg = longMsg;
9765        report.stackTrace = stackTrace;
9766
9767        return report;
9768    }
9769
9770    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9771        synchronized (this) {
9772            app.crashing = false;
9773            app.crashingReport = null;
9774            app.notResponding = false;
9775            app.notRespondingReport = null;
9776            if (app.anrDialog == fromDialog) {
9777                app.anrDialog = null;
9778            }
9779            if (app.waitDialog == fromDialog) {
9780                app.waitDialog = null;
9781            }
9782            if (app.pid > 0 && app.pid != MY_PID) {
9783                handleAppCrashLocked(app, null, null, null);
9784                killUnneededProcessLocked(app, "user request after error");
9785            }
9786        }
9787    }
9788
9789    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9790            String stackTrace) {
9791        long now = SystemClock.uptimeMillis();
9792
9793        Long crashTime;
9794        if (!app.isolated) {
9795            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9796        } else {
9797            crashTime = null;
9798        }
9799        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9800            // This process loses!
9801            Slog.w(TAG, "Process " + app.info.processName
9802                    + " has crashed too many times: killing!");
9803            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9804                    app.userId, app.info.processName, app.uid);
9805            mStackSupervisor.handleAppCrashLocked(app);
9806            if (!app.persistent) {
9807                // We don't want to start this process again until the user
9808                // explicitly does so...  but for persistent process, we really
9809                // need to keep it running.  If a persistent process is actually
9810                // repeatedly crashing, then badness for everyone.
9811                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9812                        app.info.processName);
9813                if (!app.isolated) {
9814                    // XXX We don't have a way to mark isolated processes
9815                    // as bad, since they don't have a peristent identity.
9816                    mBadProcesses.put(app.info.processName, app.uid,
9817                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9818                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9819                }
9820                app.bad = true;
9821                app.removed = true;
9822                // Don't let services in this process be restarted and potentially
9823                // annoy the user repeatedly.  Unless it is persistent, since those
9824                // processes run critical code.
9825                removeProcessLocked(app, false, false, "crash");
9826                mStackSupervisor.resumeTopActivitiesLocked();
9827                return false;
9828            }
9829            mStackSupervisor.resumeTopActivitiesLocked();
9830        } else {
9831            mStackSupervisor.finishTopRunningActivityLocked(app);
9832        }
9833
9834        // Bump up the crash count of any services currently running in the proc.
9835        for (int i=app.services.size()-1; i>=0; i--) {
9836            // Any services running in the application need to be placed
9837            // back in the pending list.
9838            ServiceRecord sr = app.services.valueAt(i);
9839            sr.crashCount++;
9840        }
9841
9842        // If the crashing process is what we consider to be the "home process" and it has been
9843        // replaced by a third-party app, clear the package preferred activities from packages
9844        // with a home activity running in the process to prevent a repeatedly crashing app
9845        // from blocking the user to manually clear the list.
9846        final ArrayList<ActivityRecord> activities = app.activities;
9847        if (app == mHomeProcess && activities.size() > 0
9848                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9849            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9850                final ActivityRecord r = activities.get(activityNdx);
9851                if (r.isHomeActivity()) {
9852                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9853                    try {
9854                        ActivityThread.getPackageManager()
9855                                .clearPackagePreferredActivities(r.packageName);
9856                    } catch (RemoteException c) {
9857                        // pm is in same process, this will never happen.
9858                    }
9859                }
9860            }
9861        }
9862
9863        if (!app.isolated) {
9864            // XXX Can't keep track of crash times for isolated processes,
9865            // because they don't have a perisistent identity.
9866            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9867        }
9868
9869        return true;
9870    }
9871
9872    void startAppProblemLocked(ProcessRecord app) {
9873        if (app.userId == mCurrentUserId) {
9874            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9875                    mContext, app.info.packageName, app.info.flags);
9876        } else {
9877            // If this app is not running under the current user, then we
9878            // can't give it a report button because that would require
9879            // launching the report UI under a different user.
9880            app.errorReportReceiver = null;
9881        }
9882        skipCurrentReceiverLocked(app);
9883    }
9884
9885    void skipCurrentReceiverLocked(ProcessRecord app) {
9886        for (BroadcastQueue queue : mBroadcastQueues) {
9887            queue.skipCurrentReceiverLocked(app);
9888        }
9889    }
9890
9891    /**
9892     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9893     * The application process will exit immediately after this call returns.
9894     * @param app object of the crashing app, null for the system server
9895     * @param crashInfo describing the exception
9896     */
9897    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9898        ProcessRecord r = findAppProcess(app, "Crash");
9899        final String processName = app == null ? "system_server"
9900                : (r == null ? "unknown" : r.processName);
9901
9902        handleApplicationCrashInner("crash", r, processName, crashInfo);
9903    }
9904
9905    /* Native crash reporting uses this inner version because it needs to be somewhat
9906     * decoupled from the AM-managed cleanup lifecycle
9907     */
9908    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
9909            ApplicationErrorReport.CrashInfo crashInfo) {
9910        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
9911                UserHandle.getUserId(Binder.getCallingUid()), processName,
9912                r == null ? -1 : r.info.flags,
9913                crashInfo.exceptionClassName,
9914                crashInfo.exceptionMessage,
9915                crashInfo.throwFileName,
9916                crashInfo.throwLineNumber);
9917
9918        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
9919
9920        crashApplication(r, crashInfo);
9921    }
9922
9923    public void handleApplicationStrictModeViolation(
9924            IBinder app,
9925            int violationMask,
9926            StrictMode.ViolationInfo info) {
9927        ProcessRecord r = findAppProcess(app, "StrictMode");
9928        if (r == null) {
9929            return;
9930        }
9931
9932        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
9933            Integer stackFingerprint = info.hashCode();
9934            boolean logIt = true;
9935            synchronized (mAlreadyLoggedViolatedStacks) {
9936                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
9937                    logIt = false;
9938                    // TODO: sub-sample into EventLog for these, with
9939                    // the info.durationMillis?  Then we'd get
9940                    // the relative pain numbers, without logging all
9941                    // the stack traces repeatedly.  We'd want to do
9942                    // likewise in the client code, which also does
9943                    // dup suppression, before the Binder call.
9944                } else {
9945                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
9946                        mAlreadyLoggedViolatedStacks.clear();
9947                    }
9948                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
9949                }
9950            }
9951            if (logIt) {
9952                logStrictModeViolationToDropBox(r, info);
9953            }
9954        }
9955
9956        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
9957            AppErrorResult result = new AppErrorResult();
9958            synchronized (this) {
9959                final long origId = Binder.clearCallingIdentity();
9960
9961                Message msg = Message.obtain();
9962                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
9963                HashMap<String, Object> data = new HashMap<String, Object>();
9964                data.put("result", result);
9965                data.put("app", r);
9966                data.put("violationMask", violationMask);
9967                data.put("info", info);
9968                msg.obj = data;
9969                mHandler.sendMessage(msg);
9970
9971                Binder.restoreCallingIdentity(origId);
9972            }
9973            int res = result.get();
9974            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
9975        }
9976    }
9977
9978    // Depending on the policy in effect, there could be a bunch of
9979    // these in quick succession so we try to batch these together to
9980    // minimize disk writes, number of dropbox entries, and maximize
9981    // compression, by having more fewer, larger records.
9982    private void logStrictModeViolationToDropBox(
9983            ProcessRecord process,
9984            StrictMode.ViolationInfo info) {
9985        if (info == null) {
9986            return;
9987        }
9988        final boolean isSystemApp = process == null ||
9989                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
9990                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
9991        final String processName = process == null ? "unknown" : process.processName;
9992        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
9993        final DropBoxManager dbox = (DropBoxManager)
9994                mContext.getSystemService(Context.DROPBOX_SERVICE);
9995
9996        // Exit early if the dropbox isn't configured to accept this report type.
9997        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9998
9999        boolean bufferWasEmpty;
10000        boolean needsFlush;
10001        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10002        synchronized (sb) {
10003            bufferWasEmpty = sb.length() == 0;
10004            appendDropBoxProcessHeaders(process, processName, sb);
10005            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10006            sb.append("System-App: ").append(isSystemApp).append("\n");
10007            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10008            if (info.violationNumThisLoop != 0) {
10009                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10010            }
10011            if (info.numAnimationsRunning != 0) {
10012                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10013            }
10014            if (info.broadcastIntentAction != null) {
10015                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10016            }
10017            if (info.durationMillis != -1) {
10018                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10019            }
10020            if (info.numInstances != -1) {
10021                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10022            }
10023            if (info.tags != null) {
10024                for (String tag : info.tags) {
10025                    sb.append("Span-Tag: ").append(tag).append("\n");
10026                }
10027            }
10028            sb.append("\n");
10029            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10030                sb.append(info.crashInfo.stackTrace);
10031            }
10032            sb.append("\n");
10033
10034            // Only buffer up to ~64k.  Various logging bits truncate
10035            // things at 128k.
10036            needsFlush = (sb.length() > 64 * 1024);
10037        }
10038
10039        // Flush immediately if the buffer's grown too large, or this
10040        // is a non-system app.  Non-system apps are isolated with a
10041        // different tag & policy and not batched.
10042        //
10043        // Batching is useful during internal testing with
10044        // StrictMode settings turned up high.  Without batching,
10045        // thousands of separate files could be created on boot.
10046        if (!isSystemApp || needsFlush) {
10047            new Thread("Error dump: " + dropboxTag) {
10048                @Override
10049                public void run() {
10050                    String report;
10051                    synchronized (sb) {
10052                        report = sb.toString();
10053                        sb.delete(0, sb.length());
10054                        sb.trimToSize();
10055                    }
10056                    if (report.length() != 0) {
10057                        dbox.addText(dropboxTag, report);
10058                    }
10059                }
10060            }.start();
10061            return;
10062        }
10063
10064        // System app batching:
10065        if (!bufferWasEmpty) {
10066            // An existing dropbox-writing thread is outstanding, so
10067            // we don't need to start it up.  The existing thread will
10068            // catch the buffer appends we just did.
10069            return;
10070        }
10071
10072        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10073        // (After this point, we shouldn't access AMS internal data structures.)
10074        new Thread("Error dump: " + dropboxTag) {
10075            @Override
10076            public void run() {
10077                // 5 second sleep to let stacks arrive and be batched together
10078                try {
10079                    Thread.sleep(5000);  // 5 seconds
10080                } catch (InterruptedException e) {}
10081
10082                String errorReport;
10083                synchronized (mStrictModeBuffer) {
10084                    errorReport = mStrictModeBuffer.toString();
10085                    if (errorReport.length() == 0) {
10086                        return;
10087                    }
10088                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10089                    mStrictModeBuffer.trimToSize();
10090                }
10091                dbox.addText(dropboxTag, errorReport);
10092            }
10093        }.start();
10094    }
10095
10096    /**
10097     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10098     * @param app object of the crashing app, null for the system server
10099     * @param tag reported by the caller
10100     * @param crashInfo describing the context of the error
10101     * @return true if the process should exit immediately (WTF is fatal)
10102     */
10103    public boolean handleApplicationWtf(IBinder app, String tag,
10104            ApplicationErrorReport.CrashInfo crashInfo) {
10105        ProcessRecord r = findAppProcess(app, "WTF");
10106        final String processName = app == null ? "system_server"
10107                : (r == null ? "unknown" : r.processName);
10108
10109        EventLog.writeEvent(EventLogTags.AM_WTF,
10110                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10111                processName,
10112                r == null ? -1 : r.info.flags,
10113                tag, crashInfo.exceptionMessage);
10114
10115        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10116
10117        if (r != null && r.pid != Process.myPid() &&
10118                Settings.Global.getInt(mContext.getContentResolver(),
10119                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10120            crashApplication(r, crashInfo);
10121            return true;
10122        } else {
10123            return false;
10124        }
10125    }
10126
10127    /**
10128     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10129     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10130     */
10131    private ProcessRecord findAppProcess(IBinder app, String reason) {
10132        if (app == null) {
10133            return null;
10134        }
10135
10136        synchronized (this) {
10137            final int NP = mProcessNames.getMap().size();
10138            for (int ip=0; ip<NP; ip++) {
10139                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10140                final int NA = apps.size();
10141                for (int ia=0; ia<NA; ia++) {
10142                    ProcessRecord p = apps.valueAt(ia);
10143                    if (p.thread != null && p.thread.asBinder() == app) {
10144                        return p;
10145                    }
10146                }
10147            }
10148
10149            Slog.w(TAG, "Can't find mystery application for " + reason
10150                    + " from pid=" + Binder.getCallingPid()
10151                    + " uid=" + Binder.getCallingUid() + ": " + app);
10152            return null;
10153        }
10154    }
10155
10156    /**
10157     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10158     * to append various headers to the dropbox log text.
10159     */
10160    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10161            StringBuilder sb) {
10162        // Watchdog thread ends up invoking this function (with
10163        // a null ProcessRecord) to add the stack file to dropbox.
10164        // Do not acquire a lock on this (am) in such cases, as it
10165        // could cause a potential deadlock, if and when watchdog
10166        // is invoked due to unavailability of lock on am and it
10167        // would prevent watchdog from killing system_server.
10168        if (process == null) {
10169            sb.append("Process: ").append(processName).append("\n");
10170            return;
10171        }
10172        // Note: ProcessRecord 'process' is guarded by the service
10173        // instance.  (notably process.pkgList, which could otherwise change
10174        // concurrently during execution of this method)
10175        synchronized (this) {
10176            sb.append("Process: ").append(processName).append("\n");
10177            int flags = process.info.flags;
10178            IPackageManager pm = AppGlobals.getPackageManager();
10179            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10180            for (int ip=0; ip<process.pkgList.size(); ip++) {
10181                String pkg = process.pkgList.keyAt(ip);
10182                sb.append("Package: ").append(pkg);
10183                try {
10184                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10185                    if (pi != null) {
10186                        sb.append(" v").append(pi.versionCode);
10187                        if (pi.versionName != null) {
10188                            sb.append(" (").append(pi.versionName).append(")");
10189                        }
10190                    }
10191                } catch (RemoteException e) {
10192                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10193                }
10194                sb.append("\n");
10195            }
10196        }
10197    }
10198
10199    private static String processClass(ProcessRecord process) {
10200        if (process == null || process.pid == MY_PID) {
10201            return "system_server";
10202        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10203            return "system_app";
10204        } else {
10205            return "data_app";
10206        }
10207    }
10208
10209    /**
10210     * Write a description of an error (crash, WTF, ANR) to the drop box.
10211     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10212     * @param process which caused the error, null means the system server
10213     * @param activity which triggered the error, null if unknown
10214     * @param parent activity related to the error, null if unknown
10215     * @param subject line related to the error, null if absent
10216     * @param report in long form describing the error, null if absent
10217     * @param logFile to include in the report, null if none
10218     * @param crashInfo giving an application stack trace, null if absent
10219     */
10220    public void addErrorToDropBox(String eventType,
10221            ProcessRecord process, String processName, ActivityRecord activity,
10222            ActivityRecord parent, String subject,
10223            final String report, final File logFile,
10224            final ApplicationErrorReport.CrashInfo crashInfo) {
10225        // NOTE -- this must never acquire the ActivityManagerService lock,
10226        // otherwise the watchdog may be prevented from resetting the system.
10227
10228        final String dropboxTag = processClass(process) + "_" + eventType;
10229        final DropBoxManager dbox = (DropBoxManager)
10230                mContext.getSystemService(Context.DROPBOX_SERVICE);
10231
10232        // Exit early if the dropbox isn't configured to accept this report type.
10233        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10234
10235        final StringBuilder sb = new StringBuilder(1024);
10236        appendDropBoxProcessHeaders(process, processName, sb);
10237        if (activity != null) {
10238            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10239        }
10240        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10241            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10242        }
10243        if (parent != null && parent != activity) {
10244            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10245        }
10246        if (subject != null) {
10247            sb.append("Subject: ").append(subject).append("\n");
10248        }
10249        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10250        if (Debug.isDebuggerConnected()) {
10251            sb.append("Debugger: Connected\n");
10252        }
10253        sb.append("\n");
10254
10255        // Do the rest in a worker thread to avoid blocking the caller on I/O
10256        // (After this point, we shouldn't access AMS internal data structures.)
10257        Thread worker = new Thread("Error dump: " + dropboxTag) {
10258            @Override
10259            public void run() {
10260                if (report != null) {
10261                    sb.append(report);
10262                }
10263                if (logFile != null) {
10264                    try {
10265                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10266                                    "\n\n[[TRUNCATED]]"));
10267                    } catch (IOException e) {
10268                        Slog.e(TAG, "Error reading " + logFile, e);
10269                    }
10270                }
10271                if (crashInfo != null && crashInfo.stackTrace != null) {
10272                    sb.append(crashInfo.stackTrace);
10273                }
10274
10275                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10276                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10277                if (lines > 0) {
10278                    sb.append("\n");
10279
10280                    // Merge several logcat streams, and take the last N lines
10281                    InputStreamReader input = null;
10282                    try {
10283                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10284                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10285                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10286
10287                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10288                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10289                        input = new InputStreamReader(logcat.getInputStream());
10290
10291                        int num;
10292                        char[] buf = new char[8192];
10293                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10294                    } catch (IOException e) {
10295                        Slog.e(TAG, "Error running logcat", e);
10296                    } finally {
10297                        if (input != null) try { input.close(); } catch (IOException e) {}
10298                    }
10299                }
10300
10301                dbox.addText(dropboxTag, sb.toString());
10302            }
10303        };
10304
10305        if (process == null) {
10306            // If process is null, we are being called from some internal code
10307            // and may be about to die -- run this synchronously.
10308            worker.run();
10309        } else {
10310            worker.start();
10311        }
10312    }
10313
10314    /**
10315     * Bring up the "unexpected error" dialog box for a crashing app.
10316     * Deal with edge cases (intercepts from instrumented applications,
10317     * ActivityController, error intent receivers, that sort of thing).
10318     * @param r the application crashing
10319     * @param crashInfo describing the failure
10320     */
10321    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10322        long timeMillis = System.currentTimeMillis();
10323        String shortMsg = crashInfo.exceptionClassName;
10324        String longMsg = crashInfo.exceptionMessage;
10325        String stackTrace = crashInfo.stackTrace;
10326        if (shortMsg != null && longMsg != null) {
10327            longMsg = shortMsg + ": " + longMsg;
10328        } else if (shortMsg != null) {
10329            longMsg = shortMsg;
10330        }
10331
10332        AppErrorResult result = new AppErrorResult();
10333        synchronized (this) {
10334            if (mController != null) {
10335                try {
10336                    String name = r != null ? r.processName : null;
10337                    int pid = r != null ? r.pid : Binder.getCallingPid();
10338                    if (!mController.appCrashed(name, pid,
10339                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10340                        Slog.w(TAG, "Force-killing crashed app " + name
10341                                + " at watcher's request");
10342                        Process.killProcess(pid);
10343                        return;
10344                    }
10345                } catch (RemoteException e) {
10346                    mController = null;
10347                    Watchdog.getInstance().setActivityController(null);
10348                }
10349            }
10350
10351            final long origId = Binder.clearCallingIdentity();
10352
10353            // If this process is running instrumentation, finish it.
10354            if (r != null && r.instrumentationClass != null) {
10355                Slog.w(TAG, "Error in app " + r.processName
10356                      + " running instrumentation " + r.instrumentationClass + ":");
10357                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10358                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10359                Bundle info = new Bundle();
10360                info.putString("shortMsg", shortMsg);
10361                info.putString("longMsg", longMsg);
10362                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10363                Binder.restoreCallingIdentity(origId);
10364                return;
10365            }
10366
10367            // If we can't identify the process or it's already exceeded its crash quota,
10368            // quit right away without showing a crash dialog.
10369            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10370                Binder.restoreCallingIdentity(origId);
10371                return;
10372            }
10373
10374            Message msg = Message.obtain();
10375            msg.what = SHOW_ERROR_MSG;
10376            HashMap data = new HashMap();
10377            data.put("result", result);
10378            data.put("app", r);
10379            msg.obj = data;
10380            mHandler.sendMessage(msg);
10381
10382            Binder.restoreCallingIdentity(origId);
10383        }
10384
10385        int res = result.get();
10386
10387        Intent appErrorIntent = null;
10388        synchronized (this) {
10389            if (r != null && !r.isolated) {
10390                // XXX Can't keep track of crash time for isolated processes,
10391                // since they don't have a persistent identity.
10392                mProcessCrashTimes.put(r.info.processName, r.uid,
10393                        SystemClock.uptimeMillis());
10394            }
10395            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10396                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10397            }
10398        }
10399
10400        if (appErrorIntent != null) {
10401            try {
10402                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10403            } catch (ActivityNotFoundException e) {
10404                Slog.w(TAG, "bug report receiver dissappeared", e);
10405            }
10406        }
10407    }
10408
10409    Intent createAppErrorIntentLocked(ProcessRecord r,
10410            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10411        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10412        if (report == null) {
10413            return null;
10414        }
10415        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10416        result.setComponent(r.errorReportReceiver);
10417        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10418        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10419        return result;
10420    }
10421
10422    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10423            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10424        if (r.errorReportReceiver == null) {
10425            return null;
10426        }
10427
10428        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10429            return null;
10430        }
10431
10432        ApplicationErrorReport report = new ApplicationErrorReport();
10433        report.packageName = r.info.packageName;
10434        report.installerPackageName = r.errorReportReceiver.getPackageName();
10435        report.processName = r.processName;
10436        report.time = timeMillis;
10437        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10438
10439        if (r.crashing || r.forceCrashReport) {
10440            report.type = ApplicationErrorReport.TYPE_CRASH;
10441            report.crashInfo = crashInfo;
10442        } else if (r.notResponding) {
10443            report.type = ApplicationErrorReport.TYPE_ANR;
10444            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10445
10446            report.anrInfo.activity = r.notRespondingReport.tag;
10447            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10448            report.anrInfo.info = r.notRespondingReport.longMsg;
10449        }
10450
10451        return report;
10452    }
10453
10454    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10455        enforceNotIsolatedCaller("getProcessesInErrorState");
10456        // assume our apps are happy - lazy create the list
10457        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10458
10459        final boolean allUsers = ActivityManager.checkUidPermission(
10460                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10461                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10462        int userId = UserHandle.getUserId(Binder.getCallingUid());
10463
10464        synchronized (this) {
10465
10466            // iterate across all processes
10467            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10468                ProcessRecord app = mLruProcesses.get(i);
10469                if (!allUsers && app.userId != userId) {
10470                    continue;
10471                }
10472                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10473                    // This one's in trouble, so we'll generate a report for it
10474                    // crashes are higher priority (in case there's a crash *and* an anr)
10475                    ActivityManager.ProcessErrorStateInfo report = null;
10476                    if (app.crashing) {
10477                        report = app.crashingReport;
10478                    } else if (app.notResponding) {
10479                        report = app.notRespondingReport;
10480                    }
10481
10482                    if (report != null) {
10483                        if (errList == null) {
10484                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10485                        }
10486                        errList.add(report);
10487                    } else {
10488                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10489                                " crashing = " + app.crashing +
10490                                " notResponding = " + app.notResponding);
10491                    }
10492                }
10493            }
10494        }
10495
10496        return errList;
10497    }
10498
10499    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10500        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10501            if (currApp != null) {
10502                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10503            }
10504            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10505        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10506            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10507        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10508            if (currApp != null) {
10509                currApp.lru = 0;
10510            }
10511            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10512        } else if (adj >= ProcessList.SERVICE_ADJ) {
10513            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10514        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10515            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10516        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10517            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10518        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10519            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10520        } else {
10521            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10522        }
10523    }
10524
10525    private void fillInProcMemInfo(ProcessRecord app,
10526            ActivityManager.RunningAppProcessInfo outInfo) {
10527        outInfo.pid = app.pid;
10528        outInfo.uid = app.info.uid;
10529        if (mHeavyWeightProcess == app) {
10530            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10531        }
10532        if (app.persistent) {
10533            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10534        }
10535        if (app.activities.size() > 0) {
10536            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10537        }
10538        outInfo.lastTrimLevel = app.trimMemoryLevel;
10539        int adj = app.curAdj;
10540        outInfo.importance = oomAdjToImportance(adj, outInfo);
10541        outInfo.importanceReasonCode = app.adjTypeCode;
10542        outInfo.processState = app.curProcState;
10543    }
10544
10545    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10546        enforceNotIsolatedCaller("getRunningAppProcesses");
10547        // Lazy instantiation of list
10548        List<ActivityManager.RunningAppProcessInfo> runList = null;
10549        final boolean allUsers = ActivityManager.checkUidPermission(
10550                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10551                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10552        int userId = UserHandle.getUserId(Binder.getCallingUid());
10553        synchronized (this) {
10554            // Iterate across all processes
10555            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10556                ProcessRecord app = mLruProcesses.get(i);
10557                if (!allUsers && app.userId != userId) {
10558                    continue;
10559                }
10560                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10561                    // Generate process state info for running application
10562                    ActivityManager.RunningAppProcessInfo currApp =
10563                        new ActivityManager.RunningAppProcessInfo(app.processName,
10564                                app.pid, app.getPackageList());
10565                    fillInProcMemInfo(app, currApp);
10566                    if (app.adjSource instanceof ProcessRecord) {
10567                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10568                        currApp.importanceReasonImportance = oomAdjToImportance(
10569                                app.adjSourceOom, null);
10570                    } else if (app.adjSource instanceof ActivityRecord) {
10571                        ActivityRecord r = (ActivityRecord)app.adjSource;
10572                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10573                    }
10574                    if (app.adjTarget instanceof ComponentName) {
10575                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10576                    }
10577                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10578                    //        + " lru=" + currApp.lru);
10579                    if (runList == null) {
10580                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10581                    }
10582                    runList.add(currApp);
10583                }
10584            }
10585        }
10586        return runList;
10587    }
10588
10589    public List<ApplicationInfo> getRunningExternalApplications() {
10590        enforceNotIsolatedCaller("getRunningExternalApplications");
10591        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10592        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10593        if (runningApps != null && runningApps.size() > 0) {
10594            Set<String> extList = new HashSet<String>();
10595            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10596                if (app.pkgList != null) {
10597                    for (String pkg : app.pkgList) {
10598                        extList.add(pkg);
10599                    }
10600                }
10601            }
10602            IPackageManager pm = AppGlobals.getPackageManager();
10603            for (String pkg : extList) {
10604                try {
10605                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10606                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10607                        retList.add(info);
10608                    }
10609                } catch (RemoteException e) {
10610                }
10611            }
10612        }
10613        return retList;
10614    }
10615
10616    @Override
10617    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10618        enforceNotIsolatedCaller("getMyMemoryState");
10619        synchronized (this) {
10620            ProcessRecord proc;
10621            synchronized (mPidsSelfLocked) {
10622                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10623            }
10624            fillInProcMemInfo(proc, outInfo);
10625        }
10626    }
10627
10628    @Override
10629    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10630        if (checkCallingPermission(android.Manifest.permission.DUMP)
10631                != PackageManager.PERMISSION_GRANTED) {
10632            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10633                    + Binder.getCallingPid()
10634                    + ", uid=" + Binder.getCallingUid()
10635                    + " without permission "
10636                    + android.Manifest.permission.DUMP);
10637            return;
10638        }
10639
10640        boolean dumpAll = false;
10641        boolean dumpClient = false;
10642        String dumpPackage = null;
10643
10644        int opti = 0;
10645        while (opti < args.length) {
10646            String opt = args[opti];
10647            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10648                break;
10649            }
10650            opti++;
10651            if ("-a".equals(opt)) {
10652                dumpAll = true;
10653            } else if ("-c".equals(opt)) {
10654                dumpClient = true;
10655            } else if ("-h".equals(opt)) {
10656                pw.println("Activity manager dump options:");
10657                pw.println("  [-a] [-c] [-h] [cmd] ...");
10658                pw.println("  cmd may be one of:");
10659                pw.println("    a[ctivities]: activity stack state");
10660                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10661                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10662                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10663                pw.println("    o[om]: out of memory management");
10664                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10665                pw.println("    provider [COMP_SPEC]: provider client-side state");
10666                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10667                pw.println("    service [COMP_SPEC]: service client-side state");
10668                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10669                pw.println("    all: dump all activities");
10670                pw.println("    top: dump the top activity");
10671                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10672                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10673                pw.println("    a partial substring in a component name, a");
10674                pw.println("    hex object identifier.");
10675                pw.println("  -a: include all available server state.");
10676                pw.println("  -c: include client state.");
10677                return;
10678            } else {
10679                pw.println("Unknown argument: " + opt + "; use -h for help");
10680            }
10681        }
10682
10683        long origId = Binder.clearCallingIdentity();
10684        boolean more = false;
10685        // Is the caller requesting to dump a particular piece of data?
10686        if (opti < args.length) {
10687            String cmd = args[opti];
10688            opti++;
10689            if ("activities".equals(cmd) || "a".equals(cmd)) {
10690                synchronized (this) {
10691                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10692                }
10693            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10694                String[] newArgs;
10695                String name;
10696                if (opti >= args.length) {
10697                    name = null;
10698                    newArgs = EMPTY_STRING_ARRAY;
10699                } else {
10700                    name = args[opti];
10701                    opti++;
10702                    newArgs = new String[args.length - opti];
10703                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10704                            args.length - opti);
10705                }
10706                synchronized (this) {
10707                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10708                }
10709            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10710                String[] newArgs;
10711                String name;
10712                if (opti >= args.length) {
10713                    name = null;
10714                    newArgs = EMPTY_STRING_ARRAY;
10715                } else {
10716                    name = args[opti];
10717                    opti++;
10718                    newArgs = new String[args.length - opti];
10719                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10720                            args.length - opti);
10721                }
10722                synchronized (this) {
10723                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10724                }
10725            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10726                String[] newArgs;
10727                String name;
10728                if (opti >= args.length) {
10729                    name = null;
10730                    newArgs = EMPTY_STRING_ARRAY;
10731                } else {
10732                    name = args[opti];
10733                    opti++;
10734                    newArgs = new String[args.length - opti];
10735                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10736                            args.length - opti);
10737                }
10738                synchronized (this) {
10739                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10740                }
10741            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10742                synchronized (this) {
10743                    dumpOomLocked(fd, pw, args, opti, true);
10744                }
10745            } else if ("provider".equals(cmd)) {
10746                String[] newArgs;
10747                String name;
10748                if (opti >= args.length) {
10749                    name = null;
10750                    newArgs = EMPTY_STRING_ARRAY;
10751                } else {
10752                    name = args[opti];
10753                    opti++;
10754                    newArgs = new String[args.length - opti];
10755                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10756                }
10757                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10758                    pw.println("No providers match: " + name);
10759                    pw.println("Use -h for help.");
10760                }
10761            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10762                synchronized (this) {
10763                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10764                }
10765            } else if ("service".equals(cmd)) {
10766                String[] newArgs;
10767                String name;
10768                if (opti >= args.length) {
10769                    name = null;
10770                    newArgs = EMPTY_STRING_ARRAY;
10771                } else {
10772                    name = args[opti];
10773                    opti++;
10774                    newArgs = new String[args.length - opti];
10775                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10776                            args.length - opti);
10777                }
10778                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10779                    pw.println("No services match: " + name);
10780                    pw.println("Use -h for help.");
10781                }
10782            } else if ("package".equals(cmd)) {
10783                String[] newArgs;
10784                if (opti >= args.length) {
10785                    pw.println("package: no package name specified");
10786                    pw.println("Use -h for help.");
10787                } else {
10788                    dumpPackage = args[opti];
10789                    opti++;
10790                    newArgs = new String[args.length - opti];
10791                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10792                            args.length - opti);
10793                    args = newArgs;
10794                    opti = 0;
10795                    more = true;
10796                }
10797            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10798                synchronized (this) {
10799                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10800                }
10801            } else {
10802                // Dumping a single activity?
10803                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10804                    pw.println("Bad activity command, or no activities match: " + cmd);
10805                    pw.println("Use -h for help.");
10806                }
10807            }
10808            if (!more) {
10809                Binder.restoreCallingIdentity(origId);
10810                return;
10811            }
10812        }
10813
10814        // No piece of data specified, dump everything.
10815        synchronized (this) {
10816            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10817            pw.println();
10818            if (dumpAll) {
10819                pw.println("-------------------------------------------------------------------------------");
10820            }
10821            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10822            pw.println();
10823            if (dumpAll) {
10824                pw.println("-------------------------------------------------------------------------------");
10825            }
10826            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10827            pw.println();
10828            if (dumpAll) {
10829                pw.println("-------------------------------------------------------------------------------");
10830            }
10831            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10832            pw.println();
10833            if (dumpAll) {
10834                pw.println("-------------------------------------------------------------------------------");
10835            }
10836            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10837            pw.println();
10838            if (dumpAll) {
10839                pw.println("-------------------------------------------------------------------------------");
10840            }
10841            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10842        }
10843        Binder.restoreCallingIdentity(origId);
10844    }
10845
10846    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10847            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10848        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10849
10850        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10851                dumpPackage);
10852        boolean needSep = printedAnything;
10853
10854        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10855                dumpPackage, needSep, "  mFocusedActivity: ");
10856        if (printed) {
10857            printedAnything = true;
10858            needSep = false;
10859        }
10860
10861        if (dumpPackage == null) {
10862            if (needSep) {
10863                pw.println();
10864            }
10865            needSep = true;
10866            printedAnything = true;
10867            mStackSupervisor.dump(pw, "  ");
10868        }
10869
10870        if (mRecentTasks.size() > 0) {
10871            boolean printedHeader = false;
10872
10873            final int N = mRecentTasks.size();
10874            for (int i=0; i<N; i++) {
10875                TaskRecord tr = mRecentTasks.get(i);
10876                if (dumpPackage != null) {
10877                    if (tr.realActivity == null ||
10878                            !dumpPackage.equals(tr.realActivity)) {
10879                        continue;
10880                    }
10881                }
10882                if (!printedHeader) {
10883                    if (needSep) {
10884                        pw.println();
10885                    }
10886                    pw.println("  Recent tasks:");
10887                    printedHeader = true;
10888                    printedAnything = true;
10889                }
10890                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10891                        pw.println(tr);
10892                if (dumpAll) {
10893                    mRecentTasks.get(i).dump(pw, "    ");
10894                }
10895            }
10896        }
10897
10898        if (!printedAnything) {
10899            pw.println("  (nothing)");
10900        }
10901    }
10902
10903    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10904            int opti, boolean dumpAll, String dumpPackage) {
10905        boolean needSep = false;
10906        boolean printedAnything = false;
10907        int numPers = 0;
10908
10909        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
10910
10911        if (dumpAll) {
10912            final int NP = mProcessNames.getMap().size();
10913            for (int ip=0; ip<NP; ip++) {
10914                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
10915                final int NA = procs.size();
10916                for (int ia=0; ia<NA; ia++) {
10917                    ProcessRecord r = procs.valueAt(ia);
10918                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10919                        continue;
10920                    }
10921                    if (!needSep) {
10922                        pw.println("  All known processes:");
10923                        needSep = true;
10924                        printedAnything = true;
10925                    }
10926                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
10927                        pw.print(" UID "); pw.print(procs.keyAt(ia));
10928                        pw.print(" "); pw.println(r);
10929                    r.dump(pw, "    ");
10930                    if (r.persistent) {
10931                        numPers++;
10932                    }
10933                }
10934            }
10935        }
10936
10937        if (mIsolatedProcesses.size() > 0) {
10938            boolean printed = false;
10939            for (int i=0; i<mIsolatedProcesses.size(); i++) {
10940                ProcessRecord r = mIsolatedProcesses.valueAt(i);
10941                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10942                    continue;
10943                }
10944                if (!printed) {
10945                    if (needSep) {
10946                        pw.println();
10947                    }
10948                    pw.println("  Isolated process list (sorted by uid):");
10949                    printedAnything = true;
10950                    printed = true;
10951                    needSep = true;
10952                }
10953                pw.println(String.format("%sIsolated #%2d: %s",
10954                        "    ", i, r.toString()));
10955            }
10956        }
10957
10958        if (mLruProcesses.size() > 0) {
10959            if (needSep) {
10960                pw.println();
10961            }
10962            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
10963                    pw.print(" total, non-act at ");
10964                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10965                    pw.print(", non-svc at ");
10966                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10967                    pw.println("):");
10968            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
10969            needSep = true;
10970            printedAnything = true;
10971        }
10972
10973        if (dumpAll || dumpPackage != null) {
10974            synchronized (mPidsSelfLocked) {
10975                boolean printed = false;
10976                for (int i=0; i<mPidsSelfLocked.size(); i++) {
10977                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
10978                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10979                        continue;
10980                    }
10981                    if (!printed) {
10982                        if (needSep) pw.println();
10983                        needSep = true;
10984                        pw.println("  PID mappings:");
10985                        printed = true;
10986                        printedAnything = true;
10987                    }
10988                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
10989                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
10990                }
10991            }
10992        }
10993
10994        if (mForegroundProcesses.size() > 0) {
10995            synchronized (mPidsSelfLocked) {
10996                boolean printed = false;
10997                for (int i=0; i<mForegroundProcesses.size(); i++) {
10998                    ProcessRecord r = mPidsSelfLocked.get(
10999                            mForegroundProcesses.valueAt(i).pid);
11000                    if (dumpPackage != null && (r == null
11001                            || !r.pkgList.containsKey(dumpPackage))) {
11002                        continue;
11003                    }
11004                    if (!printed) {
11005                        if (needSep) pw.println();
11006                        needSep = true;
11007                        pw.println("  Foreground Processes:");
11008                        printed = true;
11009                        printedAnything = true;
11010                    }
11011                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11012                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11013                }
11014            }
11015        }
11016
11017        if (mPersistentStartingProcesses.size() > 0) {
11018            if (needSep) pw.println();
11019            needSep = true;
11020            printedAnything = true;
11021            pw.println("  Persisent processes that are starting:");
11022            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11023                    "Starting Norm", "Restarting PERS", dumpPackage);
11024        }
11025
11026        if (mRemovedProcesses.size() > 0) {
11027            if (needSep) pw.println();
11028            needSep = true;
11029            printedAnything = true;
11030            pw.println("  Processes that are being removed:");
11031            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11032                    "Removed Norm", "Removed PERS", dumpPackage);
11033        }
11034
11035        if (mProcessesOnHold.size() > 0) {
11036            if (needSep) pw.println();
11037            needSep = true;
11038            printedAnything = true;
11039            pw.println("  Processes that are on old until the system is ready:");
11040            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11041                    "OnHold Norm", "OnHold PERS", dumpPackage);
11042        }
11043
11044        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11045
11046        if (mProcessCrashTimes.getMap().size() > 0) {
11047            boolean printed = false;
11048            long now = SystemClock.uptimeMillis();
11049            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11050            final int NP = pmap.size();
11051            for (int ip=0; ip<NP; ip++) {
11052                String pname = pmap.keyAt(ip);
11053                SparseArray<Long> uids = pmap.valueAt(ip);
11054                final int N = uids.size();
11055                for (int i=0; i<N; i++) {
11056                    int puid = uids.keyAt(i);
11057                    ProcessRecord r = mProcessNames.get(pname, puid);
11058                    if (dumpPackage != null && (r == null
11059                            || !r.pkgList.containsKey(dumpPackage))) {
11060                        continue;
11061                    }
11062                    if (!printed) {
11063                        if (needSep) pw.println();
11064                        needSep = true;
11065                        pw.println("  Time since processes crashed:");
11066                        printed = true;
11067                        printedAnything = true;
11068                    }
11069                    pw.print("    Process "); pw.print(pname);
11070                            pw.print(" uid "); pw.print(puid);
11071                            pw.print(": last crashed ");
11072                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11073                            pw.println(" ago");
11074                }
11075            }
11076        }
11077
11078        if (mBadProcesses.getMap().size() > 0) {
11079            boolean printed = false;
11080            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11081            final int NP = pmap.size();
11082            for (int ip=0; ip<NP; ip++) {
11083                String pname = pmap.keyAt(ip);
11084                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11085                final int N = uids.size();
11086                for (int i=0; i<N; i++) {
11087                    int puid = uids.keyAt(i);
11088                    ProcessRecord r = mProcessNames.get(pname, puid);
11089                    if (dumpPackage != null && (r == null
11090                            || !r.pkgList.containsKey(dumpPackage))) {
11091                        continue;
11092                    }
11093                    if (!printed) {
11094                        if (needSep) pw.println();
11095                        needSep = true;
11096                        pw.println("  Bad processes:");
11097                        printedAnything = true;
11098                    }
11099                    BadProcessInfo info = uids.valueAt(i);
11100                    pw.print("    Bad process "); pw.print(pname);
11101                            pw.print(" uid "); pw.print(puid);
11102                            pw.print(": crashed at time "); pw.println(info.time);
11103                    if (info.shortMsg != null) {
11104                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11105                    }
11106                    if (info.longMsg != null) {
11107                        pw.print("      Long msg: "); pw.println(info.longMsg);
11108                    }
11109                    if (info.stack != null) {
11110                        pw.println("      Stack:");
11111                        int lastPos = 0;
11112                        for (int pos=0; pos<info.stack.length(); pos++) {
11113                            if (info.stack.charAt(pos) == '\n') {
11114                                pw.print("        ");
11115                                pw.write(info.stack, lastPos, pos-lastPos);
11116                                pw.println();
11117                                lastPos = pos+1;
11118                            }
11119                        }
11120                        if (lastPos < info.stack.length()) {
11121                            pw.print("        ");
11122                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11123                            pw.println();
11124                        }
11125                    }
11126                }
11127            }
11128        }
11129
11130        if (dumpPackage == null) {
11131            pw.println();
11132            needSep = false;
11133            pw.println("  mStartedUsers:");
11134            for (int i=0; i<mStartedUsers.size(); i++) {
11135                UserStartedState uss = mStartedUsers.valueAt(i);
11136                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11137                        pw.print(": "); uss.dump("", pw);
11138            }
11139            pw.print("  mStartedUserArray: [");
11140            for (int i=0; i<mStartedUserArray.length; i++) {
11141                if (i > 0) pw.print(", ");
11142                pw.print(mStartedUserArray[i]);
11143            }
11144            pw.println("]");
11145            pw.print("  mUserLru: [");
11146            for (int i=0; i<mUserLru.size(); i++) {
11147                if (i > 0) pw.print(", ");
11148                pw.print(mUserLru.get(i));
11149            }
11150            pw.println("]");
11151            if (dumpAll) {
11152                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11153            }
11154        }
11155        if (mHomeProcess != null && (dumpPackage == null
11156                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11157            if (needSep) {
11158                pw.println();
11159                needSep = false;
11160            }
11161            pw.println("  mHomeProcess: " + mHomeProcess);
11162        }
11163        if (mPreviousProcess != null && (dumpPackage == null
11164                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11165            if (needSep) {
11166                pw.println();
11167                needSep = false;
11168            }
11169            pw.println("  mPreviousProcess: " + mPreviousProcess);
11170        }
11171        if (dumpAll) {
11172            StringBuilder sb = new StringBuilder(128);
11173            sb.append("  mPreviousProcessVisibleTime: ");
11174            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11175            pw.println(sb);
11176        }
11177        if (mHeavyWeightProcess != null && (dumpPackage == null
11178                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11179            if (needSep) {
11180                pw.println();
11181                needSep = false;
11182            }
11183            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11184        }
11185        if (dumpPackage == null) {
11186            pw.println("  mConfiguration: " + mConfiguration);
11187        }
11188        if (dumpAll) {
11189            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11190            if (mCompatModePackages.getPackages().size() > 0) {
11191                boolean printed = false;
11192                for (Map.Entry<String, Integer> entry
11193                        : mCompatModePackages.getPackages().entrySet()) {
11194                    String pkg = entry.getKey();
11195                    int mode = entry.getValue();
11196                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11197                        continue;
11198                    }
11199                    if (!printed) {
11200                        pw.println("  mScreenCompatPackages:");
11201                        printed = true;
11202                    }
11203                    pw.print("    "); pw.print(pkg); pw.print(": ");
11204                            pw.print(mode); pw.println();
11205                }
11206            }
11207        }
11208        if (dumpPackage == null) {
11209            if (mSleeping || mWentToSleep || mLockScreenShown) {
11210                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11211                        + " mLockScreenShown " + mLockScreenShown);
11212            }
11213            if (mShuttingDown || mRunningVoice) {
11214                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11215            }
11216        }
11217        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11218                || mOrigWaitForDebugger) {
11219            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11220                    || dumpPackage.equals(mOrigDebugApp)) {
11221                if (needSep) {
11222                    pw.println();
11223                    needSep = false;
11224                }
11225                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11226                        + " mDebugTransient=" + mDebugTransient
11227                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11228            }
11229        }
11230        if (mOpenGlTraceApp != null) {
11231            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11232                if (needSep) {
11233                    pw.println();
11234                    needSep = false;
11235                }
11236                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11237            }
11238        }
11239        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11240                || mProfileFd != null) {
11241            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11242                if (needSep) {
11243                    pw.println();
11244                    needSep = false;
11245                }
11246                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11247                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11248                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11249                        + mAutoStopProfiler);
11250            }
11251        }
11252        if (dumpPackage == null) {
11253            if (mAlwaysFinishActivities || mController != null) {
11254                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11255                        + " mController=" + mController);
11256            }
11257            if (dumpAll) {
11258                pw.println("  Total persistent processes: " + numPers);
11259                pw.println("  mProcessesReady=" + mProcessesReady
11260                        + " mSystemReady=" + mSystemReady);
11261                pw.println("  mBooting=" + mBooting
11262                        + " mBooted=" + mBooted
11263                        + " mFactoryTest=" + mFactoryTest);
11264                pw.print("  mLastPowerCheckRealtime=");
11265                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11266                        pw.println("");
11267                pw.print("  mLastPowerCheckUptime=");
11268                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11269                        pw.println("");
11270                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11271                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11272                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11273                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11274                        + " (" + mLruProcesses.size() + " total)"
11275                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11276                        + " mNumServiceProcs=" + mNumServiceProcs
11277                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11278                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11279                        + " mLastMemoryLevel" + mLastMemoryLevel
11280                        + " mLastNumProcesses" + mLastNumProcesses);
11281                long now = SystemClock.uptimeMillis();
11282                pw.print("  mLastIdleTime=");
11283                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11284                        pw.print(" mLowRamSinceLastIdle=");
11285                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11286                        pw.println();
11287            }
11288        }
11289
11290        if (!printedAnything) {
11291            pw.println("  (nothing)");
11292        }
11293    }
11294
11295    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11296            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11297        if (mProcessesToGc.size() > 0) {
11298            boolean printed = false;
11299            long now = SystemClock.uptimeMillis();
11300            for (int i=0; i<mProcessesToGc.size(); i++) {
11301                ProcessRecord proc = mProcessesToGc.get(i);
11302                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11303                    continue;
11304                }
11305                if (!printed) {
11306                    if (needSep) pw.println();
11307                    needSep = true;
11308                    pw.println("  Processes that are waiting to GC:");
11309                    printed = true;
11310                }
11311                pw.print("    Process "); pw.println(proc);
11312                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11313                        pw.print(", last gced=");
11314                        pw.print(now-proc.lastRequestedGc);
11315                        pw.print(" ms ago, last lowMem=");
11316                        pw.print(now-proc.lastLowMemory);
11317                        pw.println(" ms ago");
11318
11319            }
11320        }
11321        return needSep;
11322    }
11323
11324    void printOomLevel(PrintWriter pw, String name, int adj) {
11325        pw.print("    ");
11326        if (adj >= 0) {
11327            pw.print(' ');
11328            if (adj < 10) pw.print(' ');
11329        } else {
11330            if (adj > -10) pw.print(' ');
11331        }
11332        pw.print(adj);
11333        pw.print(": ");
11334        pw.print(name);
11335        pw.print(" (");
11336        pw.print(mProcessList.getMemLevel(adj)/1024);
11337        pw.println(" kB)");
11338    }
11339
11340    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11341            int opti, boolean dumpAll) {
11342        boolean needSep = false;
11343
11344        if (mLruProcesses.size() > 0) {
11345            if (needSep) pw.println();
11346            needSep = true;
11347            pw.println("  OOM levels:");
11348            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11349            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11350            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11351            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11352            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11353            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11354            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11355            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11356            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11357            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11358            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11359            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11360            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11361
11362            if (needSep) pw.println();
11363            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11364                    pw.print(" total, non-act at ");
11365                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11366                    pw.print(", non-svc at ");
11367                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11368                    pw.println("):");
11369            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11370            needSep = true;
11371        }
11372
11373        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11374
11375        pw.println();
11376        pw.println("  mHomeProcess: " + mHomeProcess);
11377        pw.println("  mPreviousProcess: " + mPreviousProcess);
11378        if (mHeavyWeightProcess != null) {
11379            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11380        }
11381
11382        return true;
11383    }
11384
11385    /**
11386     * There are three ways to call this:
11387     *  - no provider specified: dump all the providers
11388     *  - a flattened component name that matched an existing provider was specified as the
11389     *    first arg: dump that one provider
11390     *  - the first arg isn't the flattened component name of an existing provider:
11391     *    dump all providers whose component contains the first arg as a substring
11392     */
11393    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11394            int opti, boolean dumpAll) {
11395        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11396    }
11397
11398    static class ItemMatcher {
11399        ArrayList<ComponentName> components;
11400        ArrayList<String> strings;
11401        ArrayList<Integer> objects;
11402        boolean all;
11403
11404        ItemMatcher() {
11405            all = true;
11406        }
11407
11408        void build(String name) {
11409            ComponentName componentName = ComponentName.unflattenFromString(name);
11410            if (componentName != null) {
11411                if (components == null) {
11412                    components = new ArrayList<ComponentName>();
11413                }
11414                components.add(componentName);
11415                all = false;
11416            } else {
11417                int objectId = 0;
11418                // Not a '/' separated full component name; maybe an object ID?
11419                try {
11420                    objectId = Integer.parseInt(name, 16);
11421                    if (objects == null) {
11422                        objects = new ArrayList<Integer>();
11423                    }
11424                    objects.add(objectId);
11425                    all = false;
11426                } catch (RuntimeException e) {
11427                    // Not an integer; just do string match.
11428                    if (strings == null) {
11429                        strings = new ArrayList<String>();
11430                    }
11431                    strings.add(name);
11432                    all = false;
11433                }
11434            }
11435        }
11436
11437        int build(String[] args, int opti) {
11438            for (; opti<args.length; opti++) {
11439                String name = args[opti];
11440                if ("--".equals(name)) {
11441                    return opti+1;
11442                }
11443                build(name);
11444            }
11445            return opti;
11446        }
11447
11448        boolean match(Object object, ComponentName comp) {
11449            if (all) {
11450                return true;
11451            }
11452            if (components != null) {
11453                for (int i=0; i<components.size(); i++) {
11454                    if (components.get(i).equals(comp)) {
11455                        return true;
11456                    }
11457                }
11458            }
11459            if (objects != null) {
11460                for (int i=0; i<objects.size(); i++) {
11461                    if (System.identityHashCode(object) == objects.get(i)) {
11462                        return true;
11463                    }
11464                }
11465            }
11466            if (strings != null) {
11467                String flat = comp.flattenToString();
11468                for (int i=0; i<strings.size(); i++) {
11469                    if (flat.contains(strings.get(i))) {
11470                        return true;
11471                    }
11472                }
11473            }
11474            return false;
11475        }
11476    }
11477
11478    /**
11479     * There are three things that cmd can be:
11480     *  - a flattened component name that matches an existing activity
11481     *  - the cmd arg isn't the flattened component name of an existing activity:
11482     *    dump all activity whose component contains the cmd as a substring
11483     *  - A hex number of the ActivityRecord object instance.
11484     */
11485    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11486            int opti, boolean dumpAll) {
11487        ArrayList<ActivityRecord> activities;
11488
11489        synchronized (this) {
11490            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11491        }
11492
11493        if (activities.size() <= 0) {
11494            return false;
11495        }
11496
11497        String[] newArgs = new String[args.length - opti];
11498        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11499
11500        TaskRecord lastTask = null;
11501        boolean needSep = false;
11502        for (int i=activities.size()-1; i>=0; i--) {
11503            ActivityRecord r = activities.get(i);
11504            if (needSep) {
11505                pw.println();
11506            }
11507            needSep = true;
11508            synchronized (this) {
11509                if (lastTask != r.task) {
11510                    lastTask = r.task;
11511                    pw.print("TASK "); pw.print(lastTask.affinity);
11512                            pw.print(" id="); pw.println(lastTask.taskId);
11513                    if (dumpAll) {
11514                        lastTask.dump(pw, "  ");
11515                    }
11516                }
11517            }
11518            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11519        }
11520        return true;
11521    }
11522
11523    /**
11524     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11525     * there is a thread associated with the activity.
11526     */
11527    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11528            final ActivityRecord r, String[] args, boolean dumpAll) {
11529        String innerPrefix = prefix + "  ";
11530        synchronized (this) {
11531            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11532                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11533                    pw.print(" pid=");
11534                    if (r.app != null) pw.println(r.app.pid);
11535                    else pw.println("(not running)");
11536            if (dumpAll) {
11537                r.dump(pw, innerPrefix);
11538            }
11539        }
11540        if (r.app != null && r.app.thread != null) {
11541            // flush anything that is already in the PrintWriter since the thread is going
11542            // to write to the file descriptor directly
11543            pw.flush();
11544            try {
11545                TransferPipe tp = new TransferPipe();
11546                try {
11547                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11548                            r.appToken, innerPrefix, args);
11549                    tp.go(fd);
11550                } finally {
11551                    tp.kill();
11552                }
11553            } catch (IOException e) {
11554                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11555            } catch (RemoteException e) {
11556                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11557            }
11558        }
11559    }
11560
11561    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11562            int opti, boolean dumpAll, String dumpPackage) {
11563        boolean needSep = false;
11564        boolean onlyHistory = false;
11565        boolean printedAnything = false;
11566
11567        if ("history".equals(dumpPackage)) {
11568            if (opti < args.length && "-s".equals(args[opti])) {
11569                dumpAll = false;
11570            }
11571            onlyHistory = true;
11572            dumpPackage = null;
11573        }
11574
11575        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11576        if (!onlyHistory && dumpAll) {
11577            if (mRegisteredReceivers.size() > 0) {
11578                boolean printed = false;
11579                Iterator it = mRegisteredReceivers.values().iterator();
11580                while (it.hasNext()) {
11581                    ReceiverList r = (ReceiverList)it.next();
11582                    if (dumpPackage != null && (r.app == null ||
11583                            !dumpPackage.equals(r.app.info.packageName))) {
11584                        continue;
11585                    }
11586                    if (!printed) {
11587                        pw.println("  Registered Receivers:");
11588                        needSep = true;
11589                        printed = true;
11590                        printedAnything = true;
11591                    }
11592                    pw.print("  * "); pw.println(r);
11593                    r.dump(pw, "    ");
11594                }
11595            }
11596
11597            if (mReceiverResolver.dump(pw, needSep ?
11598                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11599                    "    ", dumpPackage, false)) {
11600                needSep = true;
11601                printedAnything = true;
11602            }
11603        }
11604
11605        for (BroadcastQueue q : mBroadcastQueues) {
11606            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11607            printedAnything |= needSep;
11608        }
11609
11610        needSep = true;
11611
11612        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11613            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11614                if (needSep) {
11615                    pw.println();
11616                }
11617                needSep = true;
11618                printedAnything = true;
11619                pw.print("  Sticky broadcasts for user ");
11620                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11621                StringBuilder sb = new StringBuilder(128);
11622                for (Map.Entry<String, ArrayList<Intent>> ent
11623                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11624                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11625                    if (dumpAll) {
11626                        pw.println(":");
11627                        ArrayList<Intent> intents = ent.getValue();
11628                        final int N = intents.size();
11629                        for (int i=0; i<N; i++) {
11630                            sb.setLength(0);
11631                            sb.append("    Intent: ");
11632                            intents.get(i).toShortString(sb, false, true, false, false);
11633                            pw.println(sb.toString());
11634                            Bundle bundle = intents.get(i).getExtras();
11635                            if (bundle != null) {
11636                                pw.print("      ");
11637                                pw.println(bundle.toString());
11638                            }
11639                        }
11640                    } else {
11641                        pw.println("");
11642                    }
11643                }
11644            }
11645        }
11646
11647        if (!onlyHistory && dumpAll) {
11648            pw.println();
11649            for (BroadcastQueue queue : mBroadcastQueues) {
11650                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11651                        + queue.mBroadcastsScheduled);
11652            }
11653            pw.println("  mHandler:");
11654            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11655            needSep = true;
11656            printedAnything = true;
11657        }
11658
11659        if (!printedAnything) {
11660            pw.println("  (nothing)");
11661        }
11662    }
11663
11664    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11665            int opti, boolean dumpAll, String dumpPackage) {
11666        boolean needSep;
11667        boolean printedAnything = false;
11668
11669        ItemMatcher matcher = new ItemMatcher();
11670        matcher.build(args, opti);
11671
11672        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11673
11674        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11675        printedAnything |= needSep;
11676
11677        if (mLaunchingProviders.size() > 0) {
11678            boolean printed = false;
11679            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11680                ContentProviderRecord r = mLaunchingProviders.get(i);
11681                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11682                    continue;
11683                }
11684                if (!printed) {
11685                    if (needSep) pw.println();
11686                    needSep = true;
11687                    pw.println("  Launching content providers:");
11688                    printed = true;
11689                    printedAnything = true;
11690                }
11691                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11692                        pw.println(r);
11693            }
11694        }
11695
11696        if (mGrantedUriPermissions.size() > 0) {
11697            boolean printed = false;
11698            int dumpUid = -2;
11699            if (dumpPackage != null) {
11700                try {
11701                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11702                } catch (NameNotFoundException e) {
11703                    dumpUid = -1;
11704                }
11705            }
11706            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11707                int uid = mGrantedUriPermissions.keyAt(i);
11708                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11709                    continue;
11710                }
11711                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
11712                if (!printed) {
11713                    if (needSep) pw.println();
11714                    needSep = true;
11715                    pw.println("  Granted Uri Permissions:");
11716                    printed = true;
11717                    printedAnything = true;
11718                }
11719                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
11720                for (UriPermission perm : perms.values()) {
11721                    pw.print("    "); pw.println(perm);
11722                    if (dumpAll) {
11723                        perm.dump(pw, "      ");
11724                    }
11725                }
11726            }
11727        }
11728
11729        if (!printedAnything) {
11730            pw.println("  (nothing)");
11731        }
11732    }
11733
11734    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11735            int opti, boolean dumpAll, String dumpPackage) {
11736        boolean printed = false;
11737
11738        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11739
11740        if (mIntentSenderRecords.size() > 0) {
11741            Iterator<WeakReference<PendingIntentRecord>> it
11742                    = mIntentSenderRecords.values().iterator();
11743            while (it.hasNext()) {
11744                WeakReference<PendingIntentRecord> ref = it.next();
11745                PendingIntentRecord rec = ref != null ? ref.get(): null;
11746                if (dumpPackage != null && (rec == null
11747                        || !dumpPackage.equals(rec.key.packageName))) {
11748                    continue;
11749                }
11750                printed = true;
11751                if (rec != null) {
11752                    pw.print("  * "); pw.println(rec);
11753                    if (dumpAll) {
11754                        rec.dump(pw, "    ");
11755                    }
11756                } else {
11757                    pw.print("  * "); pw.println(ref);
11758                }
11759            }
11760        }
11761
11762        if (!printed) {
11763            pw.println("  (nothing)");
11764        }
11765    }
11766
11767    private static final int dumpProcessList(PrintWriter pw,
11768            ActivityManagerService service, List list,
11769            String prefix, String normalLabel, String persistentLabel,
11770            String dumpPackage) {
11771        int numPers = 0;
11772        final int N = list.size()-1;
11773        for (int i=N; i>=0; i--) {
11774            ProcessRecord r = (ProcessRecord)list.get(i);
11775            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11776                continue;
11777            }
11778            pw.println(String.format("%s%s #%2d: %s",
11779                    prefix, (r.persistent ? persistentLabel : normalLabel),
11780                    i, r.toString()));
11781            if (r.persistent) {
11782                numPers++;
11783            }
11784        }
11785        return numPers;
11786    }
11787
11788    private static final boolean dumpProcessOomList(PrintWriter pw,
11789            ActivityManagerService service, List<ProcessRecord> origList,
11790            String prefix, String normalLabel, String persistentLabel,
11791            boolean inclDetails, String dumpPackage) {
11792
11793        ArrayList<Pair<ProcessRecord, Integer>> list
11794                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11795        for (int i=0; i<origList.size(); i++) {
11796            ProcessRecord r = origList.get(i);
11797            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11798                continue;
11799            }
11800            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11801        }
11802
11803        if (list.size() <= 0) {
11804            return false;
11805        }
11806
11807        Comparator<Pair<ProcessRecord, Integer>> comparator
11808                = new Comparator<Pair<ProcessRecord, Integer>>() {
11809            @Override
11810            public int compare(Pair<ProcessRecord, Integer> object1,
11811                    Pair<ProcessRecord, Integer> object2) {
11812                if (object1.first.setAdj != object2.first.setAdj) {
11813                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11814                }
11815                if (object1.second.intValue() != object2.second.intValue()) {
11816                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11817                }
11818                return 0;
11819            }
11820        };
11821
11822        Collections.sort(list, comparator);
11823
11824        final long curRealtime = SystemClock.elapsedRealtime();
11825        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11826        final long curUptime = SystemClock.uptimeMillis();
11827        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11828
11829        for (int i=list.size()-1; i>=0; i--) {
11830            ProcessRecord r = list.get(i).first;
11831            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11832            char schedGroup;
11833            switch (r.setSchedGroup) {
11834                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11835                    schedGroup = 'B';
11836                    break;
11837                case Process.THREAD_GROUP_DEFAULT:
11838                    schedGroup = 'F';
11839                    break;
11840                default:
11841                    schedGroup = '?';
11842                    break;
11843            }
11844            char foreground;
11845            if (r.foregroundActivities) {
11846                foreground = 'A';
11847            } else if (r.foregroundServices) {
11848                foreground = 'S';
11849            } else {
11850                foreground = ' ';
11851            }
11852            String procState = ProcessList.makeProcStateString(r.curProcState);
11853            pw.print(prefix);
11854            pw.print(r.persistent ? persistentLabel : normalLabel);
11855            pw.print(" #");
11856            int num = (origList.size()-1)-list.get(i).second;
11857            if (num < 10) pw.print(' ');
11858            pw.print(num);
11859            pw.print(": ");
11860            pw.print(oomAdj);
11861            pw.print(' ');
11862            pw.print(schedGroup);
11863            pw.print('/');
11864            pw.print(foreground);
11865            pw.print('/');
11866            pw.print(procState);
11867            pw.print(" trm:");
11868            if (r.trimMemoryLevel < 10) pw.print(' ');
11869            pw.print(r.trimMemoryLevel);
11870            pw.print(' ');
11871            pw.print(r.toShortString());
11872            pw.print(" (");
11873            pw.print(r.adjType);
11874            pw.println(')');
11875            if (r.adjSource != null || r.adjTarget != null) {
11876                pw.print(prefix);
11877                pw.print("    ");
11878                if (r.adjTarget instanceof ComponentName) {
11879                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11880                } else if (r.adjTarget != null) {
11881                    pw.print(r.adjTarget.toString());
11882                } else {
11883                    pw.print("{null}");
11884                }
11885                pw.print("<=");
11886                if (r.adjSource instanceof ProcessRecord) {
11887                    pw.print("Proc{");
11888                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11889                    pw.println("}");
11890                } else if (r.adjSource != null) {
11891                    pw.println(r.adjSource.toString());
11892                } else {
11893                    pw.println("{null}");
11894                }
11895            }
11896            if (inclDetails) {
11897                pw.print(prefix);
11898                pw.print("    ");
11899                pw.print("oom: max="); pw.print(r.maxAdj);
11900                pw.print(" curRaw="); pw.print(r.curRawAdj);
11901                pw.print(" setRaw="); pw.print(r.setRawAdj);
11902                pw.print(" cur="); pw.print(r.curAdj);
11903                pw.print(" set="); pw.println(r.setAdj);
11904                pw.print(prefix);
11905                pw.print("    ");
11906                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
11907                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
11908                pw.print(" lastPss="); pw.print(r.lastPss);
11909                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
11910                pw.print(prefix);
11911                pw.print("    ");
11912                pw.print("keeping="); pw.print(r.keeping);
11913                pw.print(" cached="); pw.print(r.cached);
11914                pw.print(" empty="); pw.print(r.empty);
11915                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
11916
11917                if (!r.keeping) {
11918                    if (r.lastWakeTime != 0) {
11919                        long wtime;
11920                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
11921                        synchronized (stats) {
11922                            wtime = stats.getProcessWakeTime(r.info.uid,
11923                                    r.pid, curRealtime);
11924                        }
11925                        long timeUsed = wtime - r.lastWakeTime;
11926                        pw.print(prefix);
11927                        pw.print("    ");
11928                        pw.print("keep awake over ");
11929                        TimeUtils.formatDuration(realtimeSince, pw);
11930                        pw.print(" used ");
11931                        TimeUtils.formatDuration(timeUsed, pw);
11932                        pw.print(" (");
11933                        pw.print((timeUsed*100)/realtimeSince);
11934                        pw.println("%)");
11935                    }
11936                    if (r.lastCpuTime != 0) {
11937                        long timeUsed = r.curCpuTime - r.lastCpuTime;
11938                        pw.print(prefix);
11939                        pw.print("    ");
11940                        pw.print("run cpu over ");
11941                        TimeUtils.formatDuration(uptimeSince, pw);
11942                        pw.print(" used ");
11943                        TimeUtils.formatDuration(timeUsed, pw);
11944                        pw.print(" (");
11945                        pw.print((timeUsed*100)/uptimeSince);
11946                        pw.println("%)");
11947                    }
11948                }
11949            }
11950        }
11951        return true;
11952    }
11953
11954    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
11955        ArrayList<ProcessRecord> procs;
11956        synchronized (this) {
11957            if (args != null && args.length > start
11958                    && args[start].charAt(0) != '-') {
11959                procs = new ArrayList<ProcessRecord>();
11960                int pid = -1;
11961                try {
11962                    pid = Integer.parseInt(args[start]);
11963                } catch (NumberFormatException e) {
11964                }
11965                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11966                    ProcessRecord proc = mLruProcesses.get(i);
11967                    if (proc.pid == pid) {
11968                        procs.add(proc);
11969                    } else if (proc.processName.equals(args[start])) {
11970                        procs.add(proc);
11971                    }
11972                }
11973                if (procs.size() <= 0) {
11974                    return null;
11975                }
11976            } else {
11977                procs = new ArrayList<ProcessRecord>(mLruProcesses);
11978            }
11979        }
11980        return procs;
11981    }
11982
11983    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
11984            PrintWriter pw, String[] args) {
11985        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11986        if (procs == null) {
11987            pw.println("No process found for: " + args[0]);
11988            return;
11989        }
11990
11991        long uptime = SystemClock.uptimeMillis();
11992        long realtime = SystemClock.elapsedRealtime();
11993        pw.println("Applications Graphics Acceleration Info:");
11994        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11995
11996        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11997            ProcessRecord r = procs.get(i);
11998            if (r.thread != null) {
11999                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12000                pw.flush();
12001                try {
12002                    TransferPipe tp = new TransferPipe();
12003                    try {
12004                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12005                        tp.go(fd);
12006                    } finally {
12007                        tp.kill();
12008                    }
12009                } catch (IOException e) {
12010                    pw.println("Failure while dumping the app: " + r);
12011                    pw.flush();
12012                } catch (RemoteException e) {
12013                    pw.println("Got a RemoteException while dumping the app " + r);
12014                    pw.flush();
12015                }
12016            }
12017        }
12018    }
12019
12020    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12021        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12022        if (procs == null) {
12023            pw.println("No process found for: " + args[0]);
12024            return;
12025        }
12026
12027        pw.println("Applications Database Info:");
12028
12029        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12030            ProcessRecord r = procs.get(i);
12031            if (r.thread != null) {
12032                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12033                pw.flush();
12034                try {
12035                    TransferPipe tp = new TransferPipe();
12036                    try {
12037                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12038                        tp.go(fd);
12039                    } finally {
12040                        tp.kill();
12041                    }
12042                } catch (IOException e) {
12043                    pw.println("Failure while dumping the app: " + r);
12044                    pw.flush();
12045                } catch (RemoteException e) {
12046                    pw.println("Got a RemoteException while dumping the app " + r);
12047                    pw.flush();
12048                }
12049            }
12050        }
12051    }
12052
12053    final static class MemItem {
12054        final boolean isProc;
12055        final String label;
12056        final String shortLabel;
12057        final long pss;
12058        final int id;
12059        final boolean hasActivities;
12060        ArrayList<MemItem> subitems;
12061
12062        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12063                boolean _hasActivities) {
12064            isProc = true;
12065            label = _label;
12066            shortLabel = _shortLabel;
12067            pss = _pss;
12068            id = _id;
12069            hasActivities = _hasActivities;
12070        }
12071
12072        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12073            isProc = false;
12074            label = _label;
12075            shortLabel = _shortLabel;
12076            pss = _pss;
12077            id = _id;
12078            hasActivities = false;
12079        }
12080    }
12081
12082    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12083            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12084        if (sort && !isCompact) {
12085            Collections.sort(items, new Comparator<MemItem>() {
12086                @Override
12087                public int compare(MemItem lhs, MemItem rhs) {
12088                    if (lhs.pss < rhs.pss) {
12089                        return 1;
12090                    } else if (lhs.pss > rhs.pss) {
12091                        return -1;
12092                    }
12093                    return 0;
12094                }
12095            });
12096        }
12097
12098        for (int i=0; i<items.size(); i++) {
12099            MemItem mi = items.get(i);
12100            if (!isCompact) {
12101                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12102            } else if (mi.isProc) {
12103                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12104                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12105                pw.println(mi.hasActivities ? ",a" : ",e");
12106            } else {
12107                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12108                pw.println(mi.pss);
12109            }
12110            if (mi.subitems != null) {
12111                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12112                        true, isCompact);
12113            }
12114        }
12115    }
12116
12117    // These are in KB.
12118    static final long[] DUMP_MEM_BUCKETS = new long[] {
12119        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12120        120*1024, 160*1024, 200*1024,
12121        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12122        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12123    };
12124
12125    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12126            boolean stackLike) {
12127        int start = label.lastIndexOf('.');
12128        if (start >= 0) start++;
12129        else start = 0;
12130        int end = label.length();
12131        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12132            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12133                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12134                out.append(bucket);
12135                out.append(stackLike ? "MB." : "MB ");
12136                out.append(label, start, end);
12137                return;
12138            }
12139        }
12140        out.append(memKB/1024);
12141        out.append(stackLike ? "MB." : "MB ");
12142        out.append(label, start, end);
12143    }
12144
12145    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12146            ProcessList.NATIVE_ADJ,
12147            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12148            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12149            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12150            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12151            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12152    };
12153    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12154            "Native",
12155            "System", "Persistent", "Foreground",
12156            "Visible", "Perceptible",
12157            "Heavy Weight", "Backup",
12158            "A Services", "Home",
12159            "Previous", "B Services", "Cached"
12160    };
12161    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12162            "native",
12163            "sys", "pers", "fore",
12164            "vis", "percept",
12165            "heavy", "backup",
12166            "servicea", "home",
12167            "prev", "serviceb", "cached"
12168    };
12169
12170    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12171            long realtime, boolean isCheckinRequest, boolean isCompact) {
12172        if (isCheckinRequest || isCompact) {
12173            // short checkin version
12174            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12175        } else {
12176            pw.println("Applications Memory Usage (kB):");
12177            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12178        }
12179    }
12180
12181    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12182            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12183        boolean dumpDetails = false;
12184        boolean dumpFullDetails = false;
12185        boolean dumpDalvik = false;
12186        boolean oomOnly = false;
12187        boolean isCompact = false;
12188        boolean localOnly = false;
12189
12190        int opti = 0;
12191        while (opti < args.length) {
12192            String opt = args[opti];
12193            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12194                break;
12195            }
12196            opti++;
12197            if ("-a".equals(opt)) {
12198                dumpDetails = true;
12199                dumpFullDetails = true;
12200                dumpDalvik = true;
12201            } else if ("-d".equals(opt)) {
12202                dumpDalvik = true;
12203            } else if ("-c".equals(opt)) {
12204                isCompact = true;
12205            } else if ("--oom".equals(opt)) {
12206                oomOnly = true;
12207            } else if ("--local".equals(opt)) {
12208                localOnly = true;
12209            } else if ("-h".equals(opt)) {
12210                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12211                pw.println("  -a: include all available information for each process.");
12212                pw.println("  -d: include dalvik details when dumping process details.");
12213                pw.println("  -c: dump in a compact machine-parseable representation.");
12214                pw.println("  --oom: only show processes organized by oom adj.");
12215                pw.println("  --local: only collect details locally, don't call process.");
12216                pw.println("If [process] is specified it can be the name or ");
12217                pw.println("pid of a specific process to dump.");
12218                return;
12219            } else {
12220                pw.println("Unknown argument: " + opt + "; use -h for help");
12221            }
12222        }
12223
12224        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12225        long uptime = SystemClock.uptimeMillis();
12226        long realtime = SystemClock.elapsedRealtime();
12227        final long[] tmpLong = new long[1];
12228
12229        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12230        if (procs == null) {
12231            // No Java processes.  Maybe they want to print a native process.
12232            if (args != null && args.length > opti
12233                    && args[opti].charAt(0) != '-') {
12234                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12235                        = new ArrayList<ProcessCpuTracker.Stats>();
12236                updateCpuStatsNow();
12237                int findPid = -1;
12238                try {
12239                    findPid = Integer.parseInt(args[opti]);
12240                } catch (NumberFormatException e) {
12241                }
12242                synchronized (mProcessCpuThread) {
12243                    final int N = mProcessCpuTracker.countStats();
12244                    for (int i=0; i<N; i++) {
12245                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12246                        if (st.pid == findPid || (st.baseName != null
12247                                && st.baseName.equals(args[opti]))) {
12248                            nativeProcs.add(st);
12249                        }
12250                    }
12251                }
12252                if (nativeProcs.size() > 0) {
12253                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12254                            isCompact);
12255                    Debug.MemoryInfo mi = null;
12256                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12257                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12258                        final int pid = r.pid;
12259                        if (!isCheckinRequest && dumpDetails) {
12260                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12261                        }
12262                        if (mi == null) {
12263                            mi = new Debug.MemoryInfo();
12264                        }
12265                        if (dumpDetails || (!brief && !oomOnly)) {
12266                            Debug.getMemoryInfo(pid, mi);
12267                        } else {
12268                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12269                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12270                        }
12271                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12272                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12273                        if (isCheckinRequest) {
12274                            pw.println();
12275                        }
12276                    }
12277                    return;
12278                }
12279            }
12280            pw.println("No process found for: " + args[opti]);
12281            return;
12282        }
12283
12284        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12285            dumpDetails = true;
12286        }
12287
12288        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12289
12290        String[] innerArgs = new String[args.length-opti];
12291        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12292
12293        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12294        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12295        long nativePss=0, dalvikPss=0, otherPss=0;
12296        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12297
12298        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12299        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12300                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12301
12302        long totalPss = 0;
12303        long cachedPss = 0;
12304
12305        Debug.MemoryInfo mi = null;
12306        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12307            final ProcessRecord r = procs.get(i);
12308            final IApplicationThread thread;
12309            final int pid;
12310            final int oomAdj;
12311            final boolean hasActivities;
12312            synchronized (this) {
12313                thread = r.thread;
12314                pid = r.pid;
12315                oomAdj = r.getSetAdjWithServices();
12316                hasActivities = r.activities.size() > 0;
12317            }
12318            if (thread != null) {
12319                if (!isCheckinRequest && dumpDetails) {
12320                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12321                }
12322                if (mi == null) {
12323                    mi = new Debug.MemoryInfo();
12324                }
12325                if (dumpDetails || (!brief && !oomOnly)) {
12326                    Debug.getMemoryInfo(pid, mi);
12327                } else {
12328                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12329                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12330                }
12331                if (dumpDetails) {
12332                    if (localOnly) {
12333                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12334                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12335                        if (isCheckinRequest) {
12336                            pw.println();
12337                        }
12338                    } else {
12339                        try {
12340                            pw.flush();
12341                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12342                                    dumpDalvik, innerArgs);
12343                        } catch (RemoteException e) {
12344                            if (!isCheckinRequest) {
12345                                pw.println("Got RemoteException!");
12346                                pw.flush();
12347                            }
12348                        }
12349                    }
12350                }
12351
12352                final long myTotalPss = mi.getTotalPss();
12353                final long myTotalUss = mi.getTotalUss();
12354
12355                synchronized (this) {
12356                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12357                        // Record this for posterity if the process has been stable.
12358                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12359                    }
12360                }
12361
12362                if (!isCheckinRequest && mi != null) {
12363                    totalPss += myTotalPss;
12364                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12365                            (hasActivities ? " / activities)" : ")"),
12366                            r.processName, myTotalPss, pid, hasActivities);
12367                    procMems.add(pssItem);
12368                    procMemsMap.put(pid, pssItem);
12369
12370                    nativePss += mi.nativePss;
12371                    dalvikPss += mi.dalvikPss;
12372                    otherPss += mi.otherPss;
12373                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12374                        long mem = mi.getOtherPss(j);
12375                        miscPss[j] += mem;
12376                        otherPss -= mem;
12377                    }
12378
12379                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12380                        cachedPss += myTotalPss;
12381                    }
12382
12383                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12384                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12385                                || oomIndex == (oomPss.length-1)) {
12386                            oomPss[oomIndex] += myTotalPss;
12387                            if (oomProcs[oomIndex] == null) {
12388                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12389                            }
12390                            oomProcs[oomIndex].add(pssItem);
12391                            break;
12392                        }
12393                    }
12394                }
12395            }
12396        }
12397
12398        if (!isCheckinRequest && procs.size() > 1) {
12399            // If we are showing aggregations, also look for native processes to
12400            // include so that our aggregations are more accurate.
12401            updateCpuStatsNow();
12402            synchronized (mProcessCpuThread) {
12403                final int N = mProcessCpuTracker.countStats();
12404                for (int i=0; i<N; i++) {
12405                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12406                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12407                        if (mi == null) {
12408                            mi = new Debug.MemoryInfo();
12409                        }
12410                        if (!brief && !oomOnly) {
12411                            Debug.getMemoryInfo(st.pid, mi);
12412                        } else {
12413                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12414                            mi.nativePrivateDirty = (int)tmpLong[0];
12415                        }
12416
12417                        final long myTotalPss = mi.getTotalPss();
12418                        totalPss += myTotalPss;
12419
12420                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12421                                st.name, myTotalPss, st.pid, false);
12422                        procMems.add(pssItem);
12423
12424                        nativePss += mi.nativePss;
12425                        dalvikPss += mi.dalvikPss;
12426                        otherPss += mi.otherPss;
12427                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12428                            long mem = mi.getOtherPss(j);
12429                            miscPss[j] += mem;
12430                            otherPss -= mem;
12431                        }
12432                        oomPss[0] += myTotalPss;
12433                        if (oomProcs[0] == null) {
12434                            oomProcs[0] = new ArrayList<MemItem>();
12435                        }
12436                        oomProcs[0].add(pssItem);
12437                    }
12438                }
12439            }
12440
12441            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12442
12443            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12444            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12445            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12446            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12447                String label = Debug.MemoryInfo.getOtherLabel(j);
12448                catMems.add(new MemItem(label, label, miscPss[j], j));
12449            }
12450
12451            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12452            for (int j=0; j<oomPss.length; j++) {
12453                if (oomPss[j] != 0) {
12454                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12455                            : DUMP_MEM_OOM_LABEL[j];
12456                    MemItem item = new MemItem(label, label, oomPss[j],
12457                            DUMP_MEM_OOM_ADJ[j]);
12458                    item.subitems = oomProcs[j];
12459                    oomMems.add(item);
12460                }
12461            }
12462
12463            if (!brief && !oomOnly && !isCompact) {
12464                pw.println();
12465                pw.println("Total PSS by process:");
12466                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12467                pw.println();
12468            }
12469            if (!isCompact) {
12470                pw.println("Total PSS by OOM adjustment:");
12471            }
12472            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12473            if (!brief && !oomOnly) {
12474                PrintWriter out = categoryPw != null ? categoryPw : pw;
12475                if (!isCompact) {
12476                    out.println();
12477                    out.println("Total PSS by category:");
12478                }
12479                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12480            }
12481            if (!isCompact) {
12482                pw.println();
12483            }
12484            MemInfoReader memInfo = new MemInfoReader();
12485            memInfo.readMemInfo();
12486            if (!brief) {
12487                if (!isCompact) {
12488                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12489                    pw.print(" kB (status ");
12490                    switch (mLastMemoryLevel) {
12491                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12492                            pw.println("normal)");
12493                            break;
12494                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12495                            pw.println("moderate)");
12496                            break;
12497                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12498                            pw.println("low)");
12499                            break;
12500                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12501                            pw.println("critical)");
12502                            break;
12503                        default:
12504                            pw.print(mLastMemoryLevel);
12505                            pw.println(")");
12506                            break;
12507                    }
12508                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12509                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12510                            pw.print(cachedPss); pw.print(" cached pss + ");
12511                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12512                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12513                } else {
12514                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12515                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12516                            + memInfo.getFreeSizeKb()); pw.print(",");
12517                    pw.println(totalPss - cachedPss);
12518                }
12519            }
12520            if (!isCompact) {
12521                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12522                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12523                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12524                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12525                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12526                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12527                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12528                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12529                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12530                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12531                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12532            }
12533            if (!brief) {
12534                if (memInfo.getZramTotalSizeKb() != 0) {
12535                    if (!isCompact) {
12536                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12537                                pw.print(" kB physical used for ");
12538                                pw.print(memInfo.getSwapTotalSizeKb()
12539                                        - memInfo.getSwapFreeSizeKb());
12540                                pw.print(" kB in swap (");
12541                                pw.print(memInfo.getSwapTotalSizeKb());
12542                                pw.println(" kB total swap)");
12543                    } else {
12544                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12545                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12546                                pw.println(memInfo.getSwapFreeSizeKb());
12547                    }
12548                }
12549                final int[] SINGLE_LONG_FORMAT = new int[] {
12550                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12551                };
12552                long[] longOut = new long[1];
12553                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12554                        SINGLE_LONG_FORMAT, null, longOut, null);
12555                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12556                longOut[0] = 0;
12557                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12558                        SINGLE_LONG_FORMAT, null, longOut, null);
12559                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12560                longOut[0] = 0;
12561                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12562                        SINGLE_LONG_FORMAT, null, longOut, null);
12563                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12564                longOut[0] = 0;
12565                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12566                        SINGLE_LONG_FORMAT, null, longOut, null);
12567                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12568                if (!isCompact) {
12569                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12570                        pw.print("      KSM: "); pw.print(sharing);
12571                                pw.print(" kB saved from shared ");
12572                                pw.print(shared); pw.println(" kB");
12573                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12574                                pw.print(voltile); pw.println(" kB volatile");
12575                    }
12576                    pw.print("   Tuning: ");
12577                    pw.print(ActivityManager.staticGetMemoryClass());
12578                    pw.print(" (large ");
12579                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12580                    pw.print("), oom ");
12581                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12582                    pw.print(" kB");
12583                    pw.print(", restore limit ");
12584                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12585                    pw.print(" kB");
12586                    if (ActivityManager.isLowRamDeviceStatic()) {
12587                        pw.print(" (low-ram)");
12588                    }
12589                    if (ActivityManager.isHighEndGfx()) {
12590                        pw.print(" (high-end-gfx)");
12591                    }
12592                    pw.println();
12593                } else {
12594                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12595                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12596                    pw.println(voltile);
12597                    pw.print("tuning,");
12598                    pw.print(ActivityManager.staticGetMemoryClass());
12599                    pw.print(',');
12600                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12601                    pw.print(',');
12602                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12603                    if (ActivityManager.isLowRamDeviceStatic()) {
12604                        pw.print(",low-ram");
12605                    }
12606                    if (ActivityManager.isHighEndGfx()) {
12607                        pw.print(",high-end-gfx");
12608                    }
12609                    pw.println();
12610                }
12611            }
12612        }
12613    }
12614
12615    /**
12616     * Searches array of arguments for the specified string
12617     * @param args array of argument strings
12618     * @param value value to search for
12619     * @return true if the value is contained in the array
12620     */
12621    private static boolean scanArgs(String[] args, String value) {
12622        if (args != null) {
12623            for (String arg : args) {
12624                if (value.equals(arg)) {
12625                    return true;
12626                }
12627            }
12628        }
12629        return false;
12630    }
12631
12632    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12633            ContentProviderRecord cpr, boolean always) {
12634        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12635
12636        if (!inLaunching || always) {
12637            synchronized (cpr) {
12638                cpr.launchingApp = null;
12639                cpr.notifyAll();
12640            }
12641            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12642            String names[] = cpr.info.authority.split(";");
12643            for (int j = 0; j < names.length; j++) {
12644                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12645            }
12646        }
12647
12648        for (int i=0; i<cpr.connections.size(); i++) {
12649            ContentProviderConnection conn = cpr.connections.get(i);
12650            if (conn.waiting) {
12651                // If this connection is waiting for the provider, then we don't
12652                // need to mess with its process unless we are always removing
12653                // or for some reason the provider is not currently launching.
12654                if (inLaunching && !always) {
12655                    continue;
12656                }
12657            }
12658            ProcessRecord capp = conn.client;
12659            conn.dead = true;
12660            if (conn.stableCount > 0) {
12661                if (!capp.persistent && capp.thread != null
12662                        && capp.pid != 0
12663                        && capp.pid != MY_PID) {
12664                    killUnneededProcessLocked(capp, "depends on provider "
12665                            + cpr.name.flattenToShortString()
12666                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12667                }
12668            } else if (capp.thread != null && conn.provider.provider != null) {
12669                try {
12670                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12671                } catch (RemoteException e) {
12672                }
12673                // In the protocol here, we don't expect the client to correctly
12674                // clean up this connection, we'll just remove it.
12675                cpr.connections.remove(i);
12676                conn.client.conProviders.remove(conn);
12677            }
12678        }
12679
12680        if (inLaunching && always) {
12681            mLaunchingProviders.remove(cpr);
12682        }
12683        return inLaunching;
12684    }
12685
12686    /**
12687     * Main code for cleaning up a process when it has gone away.  This is
12688     * called both as a result of the process dying, or directly when stopping
12689     * a process when running in single process mode.
12690     */
12691    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12692            boolean restarting, boolean allowRestart, int index) {
12693        if (index >= 0) {
12694            removeLruProcessLocked(app);
12695            ProcessList.remove(app.pid);
12696        }
12697
12698        mProcessesToGc.remove(app);
12699        mPendingPssProcesses.remove(app);
12700
12701        // Dismiss any open dialogs.
12702        if (app.crashDialog != null && !app.forceCrashReport) {
12703            app.crashDialog.dismiss();
12704            app.crashDialog = null;
12705        }
12706        if (app.anrDialog != null) {
12707            app.anrDialog.dismiss();
12708            app.anrDialog = null;
12709        }
12710        if (app.waitDialog != null) {
12711            app.waitDialog.dismiss();
12712            app.waitDialog = null;
12713        }
12714
12715        app.crashing = false;
12716        app.notResponding = false;
12717
12718        app.resetPackageList(mProcessStats);
12719        app.unlinkDeathRecipient();
12720        app.makeInactive(mProcessStats);
12721        app.forcingToForeground = null;
12722        updateProcessForegroundLocked(app, false, false);
12723        app.foregroundActivities = false;
12724        app.hasShownUi = false;
12725        app.treatLikeActivity = false;
12726        app.hasAboveClient = false;
12727        app.hasClientActivities = false;
12728
12729        mServices.killServicesLocked(app, allowRestart);
12730
12731        boolean restart = false;
12732
12733        // Remove published content providers.
12734        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12735            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12736            final boolean always = app.bad || !allowRestart;
12737            if (removeDyingProviderLocked(app, cpr, always) || always) {
12738                // We left the provider in the launching list, need to
12739                // restart it.
12740                restart = true;
12741            }
12742
12743            cpr.provider = null;
12744            cpr.proc = null;
12745        }
12746        app.pubProviders.clear();
12747
12748        // Take care of any launching providers waiting for this process.
12749        if (checkAppInLaunchingProvidersLocked(app, false)) {
12750            restart = true;
12751        }
12752
12753        // Unregister from connected content providers.
12754        if (!app.conProviders.isEmpty()) {
12755            for (int i=0; i<app.conProviders.size(); i++) {
12756                ContentProviderConnection conn = app.conProviders.get(i);
12757                conn.provider.connections.remove(conn);
12758            }
12759            app.conProviders.clear();
12760        }
12761
12762        // At this point there may be remaining entries in mLaunchingProviders
12763        // where we were the only one waiting, so they are no longer of use.
12764        // Look for these and clean up if found.
12765        // XXX Commented out for now.  Trying to figure out a way to reproduce
12766        // the actual situation to identify what is actually going on.
12767        if (false) {
12768            for (int i=0; i<mLaunchingProviders.size(); i++) {
12769                ContentProviderRecord cpr = (ContentProviderRecord)
12770                        mLaunchingProviders.get(i);
12771                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12772                    synchronized (cpr) {
12773                        cpr.launchingApp = null;
12774                        cpr.notifyAll();
12775                    }
12776                }
12777            }
12778        }
12779
12780        skipCurrentReceiverLocked(app);
12781
12782        // Unregister any receivers.
12783        for (int i=app.receivers.size()-1; i>=0; i--) {
12784            removeReceiverLocked(app.receivers.valueAt(i));
12785        }
12786        app.receivers.clear();
12787
12788        // If the app is undergoing backup, tell the backup manager about it
12789        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12790            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12791                    + mBackupTarget.appInfo + " died during backup");
12792            try {
12793                IBackupManager bm = IBackupManager.Stub.asInterface(
12794                        ServiceManager.getService(Context.BACKUP_SERVICE));
12795                bm.agentDisconnected(app.info.packageName);
12796            } catch (RemoteException e) {
12797                // can't happen; backup manager is local
12798            }
12799        }
12800
12801        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12802            ProcessChangeItem item = mPendingProcessChanges.get(i);
12803            if (item.pid == app.pid) {
12804                mPendingProcessChanges.remove(i);
12805                mAvailProcessChanges.add(item);
12806            }
12807        }
12808        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12809
12810        // If the caller is restarting this app, then leave it in its
12811        // current lists and let the caller take care of it.
12812        if (restarting) {
12813            return;
12814        }
12815
12816        if (!app.persistent || app.isolated) {
12817            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12818                    "Removing non-persistent process during cleanup: " + app);
12819            mProcessNames.remove(app.processName, app.uid);
12820            mIsolatedProcesses.remove(app.uid);
12821            if (mHeavyWeightProcess == app) {
12822                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12823                        mHeavyWeightProcess.userId, 0));
12824                mHeavyWeightProcess = null;
12825            }
12826        } else if (!app.removed) {
12827            // This app is persistent, so we need to keep its record around.
12828            // If it is not already on the pending app list, add it there
12829            // and start a new process for it.
12830            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12831                mPersistentStartingProcesses.add(app);
12832                restart = true;
12833            }
12834        }
12835        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12836                "Clean-up removing on hold: " + app);
12837        mProcessesOnHold.remove(app);
12838
12839        if (app == mHomeProcess) {
12840            mHomeProcess = null;
12841        }
12842        if (app == mPreviousProcess) {
12843            mPreviousProcess = null;
12844        }
12845
12846        if (restart && !app.isolated) {
12847            // We have components that still need to be running in the
12848            // process, so re-launch it.
12849            mProcessNames.put(app.processName, app.uid, app);
12850            startProcessLocked(app, "restart", app.processName);
12851        } else if (app.pid > 0 && app.pid != MY_PID) {
12852            // Goodbye!
12853            boolean removed;
12854            synchronized (mPidsSelfLocked) {
12855                mPidsSelfLocked.remove(app.pid);
12856                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12857            }
12858            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
12859                    app.processName, app.info.uid);
12860            if (app.isolated) {
12861                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
12862            }
12863            app.setPid(0);
12864        }
12865    }
12866
12867    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12868        // Look through the content providers we are waiting to have launched,
12869        // and if any run in this process then either schedule a restart of
12870        // the process or kill the client waiting for it if this process has
12871        // gone bad.
12872        int NL = mLaunchingProviders.size();
12873        boolean restart = false;
12874        for (int i=0; i<NL; i++) {
12875            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12876            if (cpr.launchingApp == app) {
12877                if (!alwaysBad && !app.bad) {
12878                    restart = true;
12879                } else {
12880                    removeDyingProviderLocked(app, cpr, true);
12881                    // cpr should have been removed from mLaunchingProviders
12882                    NL = mLaunchingProviders.size();
12883                    i--;
12884                }
12885            }
12886        }
12887        return restart;
12888    }
12889
12890    // =========================================================
12891    // SERVICES
12892    // =========================================================
12893
12894    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12895            int flags) {
12896        enforceNotIsolatedCaller("getServices");
12897        synchronized (this) {
12898            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12899        }
12900    }
12901
12902    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12903        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12904        synchronized (this) {
12905            return mServices.getRunningServiceControlPanelLocked(name);
12906        }
12907    }
12908
12909    public ComponentName startService(IApplicationThread caller, Intent service,
12910            String resolvedType, int userId) {
12911        enforceNotIsolatedCaller("startService");
12912        // Refuse possible leaked file descriptors
12913        if (service != null && service.hasFileDescriptors() == true) {
12914            throw new IllegalArgumentException("File descriptors passed in Intent");
12915        }
12916
12917        if (DEBUG_SERVICE)
12918            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
12919        synchronized(this) {
12920            final int callingPid = Binder.getCallingPid();
12921            final int callingUid = Binder.getCallingUid();
12922            final long origId = Binder.clearCallingIdentity();
12923            ComponentName res = mServices.startServiceLocked(caller, service,
12924                    resolvedType, callingPid, callingUid, userId);
12925            Binder.restoreCallingIdentity(origId);
12926            return res;
12927        }
12928    }
12929
12930    ComponentName startServiceInPackage(int uid,
12931            Intent service, String resolvedType, int userId) {
12932        synchronized(this) {
12933            if (DEBUG_SERVICE)
12934                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
12935            final long origId = Binder.clearCallingIdentity();
12936            ComponentName res = mServices.startServiceLocked(null, service,
12937                    resolvedType, -1, uid, userId);
12938            Binder.restoreCallingIdentity(origId);
12939            return res;
12940        }
12941    }
12942
12943    public int stopService(IApplicationThread caller, Intent service,
12944            String resolvedType, int userId) {
12945        enforceNotIsolatedCaller("stopService");
12946        // Refuse possible leaked file descriptors
12947        if (service != null && service.hasFileDescriptors() == true) {
12948            throw new IllegalArgumentException("File descriptors passed in Intent");
12949        }
12950
12951        synchronized(this) {
12952            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
12953        }
12954    }
12955
12956    public IBinder peekService(Intent service, String resolvedType) {
12957        enforceNotIsolatedCaller("peekService");
12958        // Refuse possible leaked file descriptors
12959        if (service != null && service.hasFileDescriptors() == true) {
12960            throw new IllegalArgumentException("File descriptors passed in Intent");
12961        }
12962        synchronized(this) {
12963            return mServices.peekServiceLocked(service, resolvedType);
12964        }
12965    }
12966
12967    public boolean stopServiceToken(ComponentName className, IBinder token,
12968            int startId) {
12969        synchronized(this) {
12970            return mServices.stopServiceTokenLocked(className, token, startId);
12971        }
12972    }
12973
12974    public void setServiceForeground(ComponentName className, IBinder token,
12975            int id, Notification notification, boolean removeNotification) {
12976        synchronized(this) {
12977            mServices.setServiceForegroundLocked(className, token, id, notification,
12978                    removeNotification);
12979        }
12980    }
12981
12982    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
12983            boolean requireFull, String name, String callerPackage) {
12984        final int callingUserId = UserHandle.getUserId(callingUid);
12985        if (callingUserId != userId) {
12986            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
12987                if ((requireFull || checkComponentPermission(
12988                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12989                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
12990                        && checkComponentPermission(
12991                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
12992                                callingPid, callingUid, -1, true)
12993                                != PackageManager.PERMISSION_GRANTED) {
12994                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
12995                        // In this case, they would like to just execute as their
12996                        // owner user instead of failing.
12997                        userId = callingUserId;
12998                    } else {
12999                        StringBuilder builder = new StringBuilder(128);
13000                        builder.append("Permission Denial: ");
13001                        builder.append(name);
13002                        if (callerPackage != null) {
13003                            builder.append(" from ");
13004                            builder.append(callerPackage);
13005                        }
13006                        builder.append(" asks to run as user ");
13007                        builder.append(userId);
13008                        builder.append(" but is calling from user ");
13009                        builder.append(UserHandle.getUserId(callingUid));
13010                        builder.append("; this requires ");
13011                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
13012                        if (!requireFull) {
13013                            builder.append(" or ");
13014                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
13015                        }
13016                        String msg = builder.toString();
13017                        Slog.w(TAG, msg);
13018                        throw new SecurityException(msg);
13019                    }
13020                }
13021            }
13022            if (userId == UserHandle.USER_CURRENT
13023                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
13024                // Note that we may be accessing this outside of a lock...
13025                // shouldn't be a big deal, if this is being called outside
13026                // of a locked context there is intrinsically a race with
13027                // the value the caller will receive and someone else changing it.
13028                userId = mCurrentUserId;
13029            }
13030            if (!allowAll && userId < 0) {
13031                throw new IllegalArgumentException(
13032                        "Call does not support special user #" + userId);
13033            }
13034        }
13035        return userId;
13036    }
13037
13038    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13039            String className, int flags) {
13040        boolean result = false;
13041        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13042            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
13043                if (ActivityManager.checkUidPermission(
13044                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13045                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13046                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13047                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13048                            + " requests FLAG_SINGLE_USER, but app does not hold "
13049                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
13050                    Slog.w(TAG, msg);
13051                    throw new SecurityException(msg);
13052                }
13053                result = true;
13054            }
13055        } else if (componentProcessName == aInfo.packageName) {
13056            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13057        } else if ("system".equals(componentProcessName)) {
13058            result = true;
13059        }
13060        if (DEBUG_MU) {
13061            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13062                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13063        }
13064        return result;
13065    }
13066
13067    public int bindService(IApplicationThread caller, IBinder token,
13068            Intent service, String resolvedType,
13069            IServiceConnection connection, int flags, int userId) {
13070        enforceNotIsolatedCaller("bindService");
13071        // Refuse possible leaked file descriptors
13072        if (service != null && service.hasFileDescriptors() == true) {
13073            throw new IllegalArgumentException("File descriptors passed in Intent");
13074        }
13075
13076        synchronized(this) {
13077            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13078                    connection, flags, userId);
13079        }
13080    }
13081
13082    public boolean unbindService(IServiceConnection connection) {
13083        synchronized (this) {
13084            return mServices.unbindServiceLocked(connection);
13085        }
13086    }
13087
13088    public void publishService(IBinder token, Intent intent, IBinder service) {
13089        // Refuse possible leaked file descriptors
13090        if (intent != null && intent.hasFileDescriptors() == true) {
13091            throw new IllegalArgumentException("File descriptors passed in Intent");
13092        }
13093
13094        synchronized(this) {
13095            if (!(token instanceof ServiceRecord)) {
13096                throw new IllegalArgumentException("Invalid service token");
13097            }
13098            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13099        }
13100    }
13101
13102    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13103        // Refuse possible leaked file descriptors
13104        if (intent != null && intent.hasFileDescriptors() == true) {
13105            throw new IllegalArgumentException("File descriptors passed in Intent");
13106        }
13107
13108        synchronized(this) {
13109            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13110        }
13111    }
13112
13113    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13114        synchronized(this) {
13115            if (!(token instanceof ServiceRecord)) {
13116                throw new IllegalArgumentException("Invalid service token");
13117            }
13118            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13119        }
13120    }
13121
13122    // =========================================================
13123    // BACKUP AND RESTORE
13124    // =========================================================
13125
13126    // Cause the target app to be launched if necessary and its backup agent
13127    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13128    // activity manager to announce its creation.
13129    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13130        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13131        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
13132
13133        synchronized(this) {
13134            // !!! TODO: currently no check here that we're already bound
13135            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13136            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13137            synchronized (stats) {
13138                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13139            }
13140
13141            // Backup agent is now in use, its package can't be stopped.
13142            try {
13143                AppGlobals.getPackageManager().setPackageStoppedState(
13144                        app.packageName, false, UserHandle.getUserId(app.uid));
13145            } catch (RemoteException e) {
13146            } catch (IllegalArgumentException e) {
13147                Slog.w(TAG, "Failed trying to unstop package "
13148                        + app.packageName + ": " + e);
13149            }
13150
13151            BackupRecord r = new BackupRecord(ss, app, backupMode);
13152            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13153                    ? new ComponentName(app.packageName, app.backupAgentName)
13154                    : new ComponentName("android", "FullBackupAgent");
13155            // startProcessLocked() returns existing proc's record if it's already running
13156            ProcessRecord proc = startProcessLocked(app.processName, app,
13157                    false, 0, "backup", hostingName, false, false, false);
13158            if (proc == null) {
13159                Slog.e(TAG, "Unable to start backup agent process " + r);
13160                return false;
13161            }
13162
13163            r.app = proc;
13164            mBackupTarget = r;
13165            mBackupAppName = app.packageName;
13166
13167            // Try not to kill the process during backup
13168            updateOomAdjLocked(proc);
13169
13170            // If the process is already attached, schedule the creation of the backup agent now.
13171            // If it is not yet live, this will be done when it attaches to the framework.
13172            if (proc.thread != null) {
13173                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13174                try {
13175                    proc.thread.scheduleCreateBackupAgent(app,
13176                            compatibilityInfoForPackageLocked(app), backupMode);
13177                } catch (RemoteException e) {
13178                    // Will time out on the backup manager side
13179                }
13180            } else {
13181                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13182            }
13183            // Invariants: at this point, the target app process exists and the application
13184            // is either already running or in the process of coming up.  mBackupTarget and
13185            // mBackupAppName describe the app, so that when it binds back to the AM we
13186            // know that it's scheduled for a backup-agent operation.
13187        }
13188
13189        return true;
13190    }
13191
13192    @Override
13193    public void clearPendingBackup() {
13194        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13195        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13196
13197        synchronized (this) {
13198            mBackupTarget = null;
13199            mBackupAppName = null;
13200        }
13201    }
13202
13203    // A backup agent has just come up
13204    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13205        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13206                + " = " + agent);
13207
13208        synchronized(this) {
13209            if (!agentPackageName.equals(mBackupAppName)) {
13210                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13211                return;
13212            }
13213        }
13214
13215        long oldIdent = Binder.clearCallingIdentity();
13216        try {
13217            IBackupManager bm = IBackupManager.Stub.asInterface(
13218                    ServiceManager.getService(Context.BACKUP_SERVICE));
13219            bm.agentConnected(agentPackageName, agent);
13220        } catch (RemoteException e) {
13221            // can't happen; the backup manager service is local
13222        } catch (Exception e) {
13223            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13224            e.printStackTrace();
13225        } finally {
13226            Binder.restoreCallingIdentity(oldIdent);
13227        }
13228    }
13229
13230    // done with this agent
13231    public void unbindBackupAgent(ApplicationInfo appInfo) {
13232        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13233        if (appInfo == null) {
13234            Slog.w(TAG, "unbind backup agent for null app");
13235            return;
13236        }
13237
13238        synchronized(this) {
13239            try {
13240                if (mBackupAppName == null) {
13241                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13242                    return;
13243                }
13244
13245                if (!mBackupAppName.equals(appInfo.packageName)) {
13246                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13247                    return;
13248                }
13249
13250                // Not backing this app up any more; reset its OOM adjustment
13251                final ProcessRecord proc = mBackupTarget.app;
13252                updateOomAdjLocked(proc);
13253
13254                // If the app crashed during backup, 'thread' will be null here
13255                if (proc.thread != null) {
13256                    try {
13257                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13258                                compatibilityInfoForPackageLocked(appInfo));
13259                    } catch (Exception e) {
13260                        Slog.e(TAG, "Exception when unbinding backup agent:");
13261                        e.printStackTrace();
13262                    }
13263                }
13264            } finally {
13265                mBackupTarget = null;
13266                mBackupAppName = null;
13267            }
13268        }
13269    }
13270    // =========================================================
13271    // BROADCASTS
13272    // =========================================================
13273
13274    private final List getStickiesLocked(String action, IntentFilter filter,
13275            List cur, int userId) {
13276        final ContentResolver resolver = mContext.getContentResolver();
13277        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13278        if (stickies == null) {
13279            return cur;
13280        }
13281        final ArrayList<Intent> list = stickies.get(action);
13282        if (list == null) {
13283            return cur;
13284        }
13285        int N = list.size();
13286        for (int i=0; i<N; i++) {
13287            Intent intent = list.get(i);
13288            if (filter.match(resolver, intent, true, TAG) >= 0) {
13289                if (cur == null) {
13290                    cur = new ArrayList<Intent>();
13291                }
13292                cur.add(intent);
13293            }
13294        }
13295        return cur;
13296    }
13297
13298    boolean isPendingBroadcastProcessLocked(int pid) {
13299        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13300                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13301    }
13302
13303    void skipPendingBroadcastLocked(int pid) {
13304            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13305            for (BroadcastQueue queue : mBroadcastQueues) {
13306                queue.skipPendingBroadcastLocked(pid);
13307            }
13308    }
13309
13310    // The app just attached; send any pending broadcasts that it should receive
13311    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13312        boolean didSomething = false;
13313        for (BroadcastQueue queue : mBroadcastQueues) {
13314            didSomething |= queue.sendPendingBroadcastsLocked(app);
13315        }
13316        return didSomething;
13317    }
13318
13319    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13320            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13321        enforceNotIsolatedCaller("registerReceiver");
13322        int callingUid;
13323        int callingPid;
13324        synchronized(this) {
13325            ProcessRecord callerApp = null;
13326            if (caller != null) {
13327                callerApp = getRecordForAppLocked(caller);
13328                if (callerApp == null) {
13329                    throw new SecurityException(
13330                            "Unable to find app for caller " + caller
13331                            + " (pid=" + Binder.getCallingPid()
13332                            + ") when registering receiver " + receiver);
13333                }
13334                if (callerApp.info.uid != Process.SYSTEM_UID &&
13335                        !callerApp.pkgList.containsKey(callerPackage) &&
13336                        !"android".equals(callerPackage)) {
13337                    throw new SecurityException("Given caller package " + callerPackage
13338                            + " is not running in process " + callerApp);
13339                }
13340                callingUid = callerApp.info.uid;
13341                callingPid = callerApp.pid;
13342            } else {
13343                callerPackage = null;
13344                callingUid = Binder.getCallingUid();
13345                callingPid = Binder.getCallingPid();
13346            }
13347
13348            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13349                    true, true, "registerReceiver", callerPackage);
13350
13351            List allSticky = null;
13352
13353            // Look for any matching sticky broadcasts...
13354            Iterator actions = filter.actionsIterator();
13355            if (actions != null) {
13356                while (actions.hasNext()) {
13357                    String action = (String)actions.next();
13358                    allSticky = getStickiesLocked(action, filter, allSticky,
13359                            UserHandle.USER_ALL);
13360                    allSticky = getStickiesLocked(action, filter, allSticky,
13361                            UserHandle.getUserId(callingUid));
13362                }
13363            } else {
13364                allSticky = getStickiesLocked(null, filter, allSticky,
13365                        UserHandle.USER_ALL);
13366                allSticky = getStickiesLocked(null, filter, allSticky,
13367                        UserHandle.getUserId(callingUid));
13368            }
13369
13370            // The first sticky in the list is returned directly back to
13371            // the client.
13372            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13373
13374            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13375                    + ": " + sticky);
13376
13377            if (receiver == null) {
13378                return sticky;
13379            }
13380
13381            ReceiverList rl
13382                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13383            if (rl == null) {
13384                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13385                        userId, receiver);
13386                if (rl.app != null) {
13387                    rl.app.receivers.add(rl);
13388                } else {
13389                    try {
13390                        receiver.asBinder().linkToDeath(rl, 0);
13391                    } catch (RemoteException e) {
13392                        return sticky;
13393                    }
13394                    rl.linkedToDeath = true;
13395                }
13396                mRegisteredReceivers.put(receiver.asBinder(), rl);
13397            } else if (rl.uid != callingUid) {
13398                throw new IllegalArgumentException(
13399                        "Receiver requested to register for uid " + callingUid
13400                        + " was previously registered for uid " + rl.uid);
13401            } else if (rl.pid != callingPid) {
13402                throw new IllegalArgumentException(
13403                        "Receiver requested to register for pid " + callingPid
13404                        + " was previously registered for pid " + rl.pid);
13405            } else if (rl.userId != userId) {
13406                throw new IllegalArgumentException(
13407                        "Receiver requested to register for user " + userId
13408                        + " was previously registered for user " + rl.userId);
13409            }
13410            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13411                    permission, callingUid, userId);
13412            rl.add(bf);
13413            if (!bf.debugCheck()) {
13414                Slog.w(TAG, "==> For Dynamic broadast");
13415            }
13416            mReceiverResolver.addFilter(bf);
13417
13418            // Enqueue broadcasts for all existing stickies that match
13419            // this filter.
13420            if (allSticky != null) {
13421                ArrayList receivers = new ArrayList();
13422                receivers.add(bf);
13423
13424                int N = allSticky.size();
13425                for (int i=0; i<N; i++) {
13426                    Intent intent = (Intent)allSticky.get(i);
13427                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13428                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13429                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13430                            null, null, false, true, true, -1);
13431                    queue.enqueueParallelBroadcastLocked(r);
13432                    queue.scheduleBroadcastsLocked();
13433                }
13434            }
13435
13436            return sticky;
13437        }
13438    }
13439
13440    public void unregisterReceiver(IIntentReceiver receiver) {
13441        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13442
13443        final long origId = Binder.clearCallingIdentity();
13444        try {
13445            boolean doTrim = false;
13446
13447            synchronized(this) {
13448                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13449                if (rl != null) {
13450                    if (rl.curBroadcast != null) {
13451                        BroadcastRecord r = rl.curBroadcast;
13452                        final boolean doNext = finishReceiverLocked(
13453                                receiver.asBinder(), r.resultCode, r.resultData,
13454                                r.resultExtras, r.resultAbort);
13455                        if (doNext) {
13456                            doTrim = true;
13457                            r.queue.processNextBroadcast(false);
13458                        }
13459                    }
13460
13461                    if (rl.app != null) {
13462                        rl.app.receivers.remove(rl);
13463                    }
13464                    removeReceiverLocked(rl);
13465                    if (rl.linkedToDeath) {
13466                        rl.linkedToDeath = false;
13467                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13468                    }
13469                }
13470            }
13471
13472            // If we actually concluded any broadcasts, we might now be able
13473            // to trim the recipients' apps from our working set
13474            if (doTrim) {
13475                trimApplications();
13476                return;
13477            }
13478
13479        } finally {
13480            Binder.restoreCallingIdentity(origId);
13481        }
13482    }
13483
13484    void removeReceiverLocked(ReceiverList rl) {
13485        mRegisteredReceivers.remove(rl.receiver.asBinder());
13486        int N = rl.size();
13487        for (int i=0; i<N; i++) {
13488            mReceiverResolver.removeFilter(rl.get(i));
13489        }
13490    }
13491
13492    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13493        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13494            ProcessRecord r = mLruProcesses.get(i);
13495            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13496                try {
13497                    r.thread.dispatchPackageBroadcast(cmd, packages);
13498                } catch (RemoteException ex) {
13499                }
13500            }
13501        }
13502    }
13503
13504    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13505            int[] users) {
13506        List<ResolveInfo> receivers = null;
13507        try {
13508            HashSet<ComponentName> singleUserReceivers = null;
13509            boolean scannedFirstReceivers = false;
13510            for (int user : users) {
13511                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13512                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13513                if (user != 0 && newReceivers != null) {
13514                    // If this is not the primary user, we need to check for
13515                    // any receivers that should be filtered out.
13516                    for (int i=0; i<newReceivers.size(); i++) {
13517                        ResolveInfo ri = newReceivers.get(i);
13518                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13519                            newReceivers.remove(i);
13520                            i--;
13521                        }
13522                    }
13523                }
13524                if (newReceivers != null && newReceivers.size() == 0) {
13525                    newReceivers = null;
13526                }
13527                if (receivers == null) {
13528                    receivers = newReceivers;
13529                } else if (newReceivers != null) {
13530                    // We need to concatenate the additional receivers
13531                    // found with what we have do far.  This would be easy,
13532                    // but we also need to de-dup any receivers that are
13533                    // singleUser.
13534                    if (!scannedFirstReceivers) {
13535                        // Collect any single user receivers we had already retrieved.
13536                        scannedFirstReceivers = true;
13537                        for (int i=0; i<receivers.size(); i++) {
13538                            ResolveInfo ri = receivers.get(i);
13539                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13540                                ComponentName cn = new ComponentName(
13541                                        ri.activityInfo.packageName, ri.activityInfo.name);
13542                                if (singleUserReceivers == null) {
13543                                    singleUserReceivers = new HashSet<ComponentName>();
13544                                }
13545                                singleUserReceivers.add(cn);
13546                            }
13547                        }
13548                    }
13549                    // Add the new results to the existing results, tracking
13550                    // and de-dupping single user receivers.
13551                    for (int i=0; i<newReceivers.size(); i++) {
13552                        ResolveInfo ri = newReceivers.get(i);
13553                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13554                            ComponentName cn = new ComponentName(
13555                                    ri.activityInfo.packageName, ri.activityInfo.name);
13556                            if (singleUserReceivers == null) {
13557                                singleUserReceivers = new HashSet<ComponentName>();
13558                            }
13559                            if (!singleUserReceivers.contains(cn)) {
13560                                singleUserReceivers.add(cn);
13561                                receivers.add(ri);
13562                            }
13563                        } else {
13564                            receivers.add(ri);
13565                        }
13566                    }
13567                }
13568            }
13569        } catch (RemoteException ex) {
13570            // pm is in same process, this will never happen.
13571        }
13572        return receivers;
13573    }
13574
13575    private final int broadcastIntentLocked(ProcessRecord callerApp,
13576            String callerPackage, Intent intent, String resolvedType,
13577            IIntentReceiver resultTo, int resultCode, String resultData,
13578            Bundle map, String requiredPermission, int appOp,
13579            boolean ordered, boolean sticky, int callingPid, int callingUid,
13580            int userId) {
13581        intent = new Intent(intent);
13582
13583        // By default broadcasts do not go to stopped apps.
13584        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13585
13586        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13587            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13588            + " ordered=" + ordered + " userid=" + userId);
13589        if ((resultTo != null) && !ordered) {
13590            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13591        }
13592
13593        userId = handleIncomingUser(callingPid, callingUid, userId,
13594                true, false, "broadcast", callerPackage);
13595
13596        // Make sure that the user who is receiving this broadcast is started.
13597        // If not, we will just skip it.
13598        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13599            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13600                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13601                Slog.w(TAG, "Skipping broadcast of " + intent
13602                        + ": user " + userId + " is stopped");
13603                return ActivityManager.BROADCAST_SUCCESS;
13604            }
13605        }
13606
13607        /*
13608         * Prevent non-system code (defined here to be non-persistent
13609         * processes) from sending protected broadcasts.
13610         */
13611        int callingAppId = UserHandle.getAppId(callingUid);
13612        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13613            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13614            callingUid == 0) {
13615            // Always okay.
13616        } else if (callerApp == null || !callerApp.persistent) {
13617            try {
13618                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13619                        intent.getAction())) {
13620                    String msg = "Permission Denial: not allowed to send broadcast "
13621                            + intent.getAction() + " from pid="
13622                            + callingPid + ", uid=" + callingUid;
13623                    Slog.w(TAG, msg);
13624                    throw new SecurityException(msg);
13625                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13626                    // Special case for compatibility: we don't want apps to send this,
13627                    // but historically it has not been protected and apps may be using it
13628                    // to poke their own app widget.  So, instead of making it protected,
13629                    // just limit it to the caller.
13630                    if (callerApp == null) {
13631                        String msg = "Permission Denial: not allowed to send broadcast "
13632                                + intent.getAction() + " from unknown caller.";
13633                        Slog.w(TAG, msg);
13634                        throw new SecurityException(msg);
13635                    } else if (intent.getComponent() != null) {
13636                        // They are good enough to send to an explicit component...  verify
13637                        // it is being sent to the calling app.
13638                        if (!intent.getComponent().getPackageName().equals(
13639                                callerApp.info.packageName)) {
13640                            String msg = "Permission Denial: not allowed to send broadcast "
13641                                    + intent.getAction() + " to "
13642                                    + intent.getComponent().getPackageName() + " from "
13643                                    + callerApp.info.packageName;
13644                            Slog.w(TAG, msg);
13645                            throw new SecurityException(msg);
13646                        }
13647                    } else {
13648                        // Limit broadcast to their own package.
13649                        intent.setPackage(callerApp.info.packageName);
13650                    }
13651                }
13652            } catch (RemoteException e) {
13653                Slog.w(TAG, "Remote exception", e);
13654                return ActivityManager.BROADCAST_SUCCESS;
13655            }
13656        }
13657
13658        // Handle special intents: if this broadcast is from the package
13659        // manager about a package being removed, we need to remove all of
13660        // its activities from the history stack.
13661        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13662                intent.getAction());
13663        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13664                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13665                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13666                || uidRemoved) {
13667            if (checkComponentPermission(
13668                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13669                    callingPid, callingUid, -1, true)
13670                    == PackageManager.PERMISSION_GRANTED) {
13671                if (uidRemoved) {
13672                    final Bundle intentExtras = intent.getExtras();
13673                    final int uid = intentExtras != null
13674                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13675                    if (uid >= 0) {
13676                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13677                        synchronized (bs) {
13678                            bs.removeUidStatsLocked(uid);
13679                        }
13680                        mAppOpsService.uidRemoved(uid);
13681                    }
13682                } else {
13683                    // If resources are unavailable just force stop all
13684                    // those packages and flush the attribute cache as well.
13685                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13686                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13687                        if (list != null && (list.length > 0)) {
13688                            for (String pkg : list) {
13689                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13690                                        "storage unmount");
13691                            }
13692                            sendPackageBroadcastLocked(
13693                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13694                        }
13695                    } else {
13696                        Uri data = intent.getData();
13697                        String ssp;
13698                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13699                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13700                                    intent.getAction());
13701                            boolean fullUninstall = removed &&
13702                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13703                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13704                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13705                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13706                                        false, fullUninstall, userId,
13707                                        removed ? "pkg removed" : "pkg changed");
13708                            }
13709                            if (removed) {
13710                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13711                                        new String[] {ssp}, userId);
13712                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13713                                    mAppOpsService.packageRemoved(
13714                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13715
13716                                    // Remove all permissions granted from/to this package
13717                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13718                                }
13719                            }
13720                        }
13721                    }
13722                }
13723            } else {
13724                String msg = "Permission Denial: " + intent.getAction()
13725                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13726                        + ", uid=" + callingUid + ")"
13727                        + " requires "
13728                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13729                Slog.w(TAG, msg);
13730                throw new SecurityException(msg);
13731            }
13732
13733        // Special case for adding a package: by default turn on compatibility
13734        // mode.
13735        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13736            Uri data = intent.getData();
13737            String ssp;
13738            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13739                mCompatModePackages.handlePackageAddedLocked(ssp,
13740                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13741            }
13742        }
13743
13744        /*
13745         * If this is the time zone changed action, queue up a message that will reset the timezone
13746         * of all currently running processes. This message will get queued up before the broadcast
13747         * happens.
13748         */
13749        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13750            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13751        }
13752
13753        /*
13754         * If the user set the time, let all running processes know.
13755         */
13756        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
13757            final int is24Hour = intent.getBooleanExtra(
13758                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
13759            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
13760        }
13761
13762        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13763            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13764        }
13765
13766        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13767            ProxyInfo proxy = intent.getParcelableExtra("proxy");
13768            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13769        }
13770
13771        // Add to the sticky list if requested.
13772        if (sticky) {
13773            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13774                    callingPid, callingUid)
13775                    != PackageManager.PERMISSION_GRANTED) {
13776                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13777                        + callingPid + ", uid=" + callingUid
13778                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13779                Slog.w(TAG, msg);
13780                throw new SecurityException(msg);
13781            }
13782            if (requiredPermission != null) {
13783                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13784                        + " and enforce permission " + requiredPermission);
13785                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13786            }
13787            if (intent.getComponent() != null) {
13788                throw new SecurityException(
13789                        "Sticky broadcasts can't target a specific component");
13790            }
13791            // We use userId directly here, since the "all" target is maintained
13792            // as a separate set of sticky broadcasts.
13793            if (userId != UserHandle.USER_ALL) {
13794                // But first, if this is not a broadcast to all users, then
13795                // make sure it doesn't conflict with an existing broadcast to
13796                // all users.
13797                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13798                        UserHandle.USER_ALL);
13799                if (stickies != null) {
13800                    ArrayList<Intent> list = stickies.get(intent.getAction());
13801                    if (list != null) {
13802                        int N = list.size();
13803                        int i;
13804                        for (i=0; i<N; i++) {
13805                            if (intent.filterEquals(list.get(i))) {
13806                                throw new IllegalArgumentException(
13807                                        "Sticky broadcast " + intent + " for user "
13808                                        + userId + " conflicts with existing global broadcast");
13809                            }
13810                        }
13811                    }
13812                }
13813            }
13814            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13815            if (stickies == null) {
13816                stickies = new ArrayMap<String, ArrayList<Intent>>();
13817                mStickyBroadcasts.put(userId, stickies);
13818            }
13819            ArrayList<Intent> list = stickies.get(intent.getAction());
13820            if (list == null) {
13821                list = new ArrayList<Intent>();
13822                stickies.put(intent.getAction(), list);
13823            }
13824            int N = list.size();
13825            int i;
13826            for (i=0; i<N; i++) {
13827                if (intent.filterEquals(list.get(i))) {
13828                    // This sticky already exists, replace it.
13829                    list.set(i, new Intent(intent));
13830                    break;
13831                }
13832            }
13833            if (i >= N) {
13834                list.add(new Intent(intent));
13835            }
13836        }
13837
13838        int[] users;
13839        if (userId == UserHandle.USER_ALL) {
13840            // Caller wants broadcast to go to all started users.
13841            users = mStartedUserArray;
13842        } else {
13843            // Caller wants broadcast to go to one specific user.
13844            users = new int[] {userId};
13845        }
13846
13847        // Figure out who all will receive this broadcast.
13848        List receivers = null;
13849        List<BroadcastFilter> registeredReceivers = null;
13850        // Need to resolve the intent to interested receivers...
13851        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13852                 == 0) {
13853            receivers = collectReceiverComponents(intent, resolvedType, users);
13854        }
13855        if (intent.getComponent() == null) {
13856            registeredReceivers = mReceiverResolver.queryIntent(intent,
13857                    resolvedType, false, userId);
13858        }
13859
13860        final boolean replacePending =
13861                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13862
13863        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13864                + " replacePending=" + replacePending);
13865
13866        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13867        if (!ordered && NR > 0) {
13868            // If we are not serializing this broadcast, then send the
13869            // registered receivers separately so they don't wait for the
13870            // components to be launched.
13871            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13872            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13873                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13874                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13875                    ordered, sticky, false, userId);
13876            if (DEBUG_BROADCAST) Slog.v(
13877                    TAG, "Enqueueing parallel broadcast " + r);
13878            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13879            if (!replaced) {
13880                queue.enqueueParallelBroadcastLocked(r);
13881                queue.scheduleBroadcastsLocked();
13882            }
13883            registeredReceivers = null;
13884            NR = 0;
13885        }
13886
13887        // Merge into one list.
13888        int ir = 0;
13889        if (receivers != null) {
13890            // A special case for PACKAGE_ADDED: do not allow the package
13891            // being added to see this broadcast.  This prevents them from
13892            // using this as a back door to get run as soon as they are
13893            // installed.  Maybe in the future we want to have a special install
13894            // broadcast or such for apps, but we'd like to deliberately make
13895            // this decision.
13896            String skipPackages[] = null;
13897            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13898                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13899                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13900                Uri data = intent.getData();
13901                if (data != null) {
13902                    String pkgName = data.getSchemeSpecificPart();
13903                    if (pkgName != null) {
13904                        skipPackages = new String[] { pkgName };
13905                    }
13906                }
13907            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13908                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13909            }
13910            if (skipPackages != null && (skipPackages.length > 0)) {
13911                for (String skipPackage : skipPackages) {
13912                    if (skipPackage != null) {
13913                        int NT = receivers.size();
13914                        for (int it=0; it<NT; it++) {
13915                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
13916                            if (curt.activityInfo.packageName.equals(skipPackage)) {
13917                                receivers.remove(it);
13918                                it--;
13919                                NT--;
13920                            }
13921                        }
13922                    }
13923                }
13924            }
13925
13926            int NT = receivers != null ? receivers.size() : 0;
13927            int it = 0;
13928            ResolveInfo curt = null;
13929            BroadcastFilter curr = null;
13930            while (it < NT && ir < NR) {
13931                if (curt == null) {
13932                    curt = (ResolveInfo)receivers.get(it);
13933                }
13934                if (curr == null) {
13935                    curr = registeredReceivers.get(ir);
13936                }
13937                if (curr.getPriority() >= curt.priority) {
13938                    // Insert this broadcast record into the final list.
13939                    receivers.add(it, curr);
13940                    ir++;
13941                    curr = null;
13942                    it++;
13943                    NT++;
13944                } else {
13945                    // Skip to the next ResolveInfo in the final list.
13946                    it++;
13947                    curt = null;
13948                }
13949            }
13950        }
13951        while (ir < NR) {
13952            if (receivers == null) {
13953                receivers = new ArrayList();
13954            }
13955            receivers.add(registeredReceivers.get(ir));
13956            ir++;
13957        }
13958
13959        if ((receivers != null && receivers.size() > 0)
13960                || resultTo != null) {
13961            BroadcastQueue queue = broadcastQueueForIntent(intent);
13962            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13963                    callerPackage, callingPid, callingUid, resolvedType,
13964                    requiredPermission, appOp, receivers, resultTo, resultCode,
13965                    resultData, map, ordered, sticky, false, userId);
13966            if (DEBUG_BROADCAST) Slog.v(
13967                    TAG, "Enqueueing ordered broadcast " + r
13968                    + ": prev had " + queue.mOrderedBroadcasts.size());
13969            if (DEBUG_BROADCAST) {
13970                int seq = r.intent.getIntExtra("seq", -1);
13971                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
13972            }
13973            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
13974            if (!replaced) {
13975                queue.enqueueOrderedBroadcastLocked(r);
13976                queue.scheduleBroadcastsLocked();
13977            }
13978        }
13979
13980        return ActivityManager.BROADCAST_SUCCESS;
13981    }
13982
13983    final Intent verifyBroadcastLocked(Intent intent) {
13984        // Refuse possible leaked file descriptors
13985        if (intent != null && intent.hasFileDescriptors() == true) {
13986            throw new IllegalArgumentException("File descriptors passed in Intent");
13987        }
13988
13989        int flags = intent.getFlags();
13990
13991        if (!mProcessesReady) {
13992            // if the caller really truly claims to know what they're doing, go
13993            // ahead and allow the broadcast without launching any receivers
13994            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
13995                intent = new Intent(intent);
13996                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13997            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
13998                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
13999                        + " before boot completion");
14000                throw new IllegalStateException("Cannot broadcast before boot completed");
14001            }
14002        }
14003
14004        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14005            throw new IllegalArgumentException(
14006                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14007        }
14008
14009        return intent;
14010    }
14011
14012    public final int broadcastIntent(IApplicationThread caller,
14013            Intent intent, String resolvedType, IIntentReceiver resultTo,
14014            int resultCode, String resultData, Bundle map,
14015            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14016        enforceNotIsolatedCaller("broadcastIntent");
14017        synchronized(this) {
14018            intent = verifyBroadcastLocked(intent);
14019
14020            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14021            final int callingPid = Binder.getCallingPid();
14022            final int callingUid = Binder.getCallingUid();
14023            final long origId = Binder.clearCallingIdentity();
14024            int res = broadcastIntentLocked(callerApp,
14025                    callerApp != null ? callerApp.info.packageName : null,
14026                    intent, resolvedType, resultTo,
14027                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14028                    callingPid, callingUid, userId);
14029            Binder.restoreCallingIdentity(origId);
14030            return res;
14031        }
14032    }
14033
14034    int broadcastIntentInPackage(String packageName, int uid,
14035            Intent intent, String resolvedType, IIntentReceiver resultTo,
14036            int resultCode, String resultData, Bundle map,
14037            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14038        synchronized(this) {
14039            intent = verifyBroadcastLocked(intent);
14040
14041            final long origId = Binder.clearCallingIdentity();
14042            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14043                    resultTo, resultCode, resultData, map, requiredPermission,
14044                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14045            Binder.restoreCallingIdentity(origId);
14046            return res;
14047        }
14048    }
14049
14050    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14051        // Refuse possible leaked file descriptors
14052        if (intent != null && intent.hasFileDescriptors() == true) {
14053            throw new IllegalArgumentException("File descriptors passed in Intent");
14054        }
14055
14056        userId = handleIncomingUser(Binder.getCallingPid(),
14057                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
14058
14059        synchronized(this) {
14060            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14061                    != PackageManager.PERMISSION_GRANTED) {
14062                String msg = "Permission Denial: unbroadcastIntent() from pid="
14063                        + Binder.getCallingPid()
14064                        + ", uid=" + Binder.getCallingUid()
14065                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14066                Slog.w(TAG, msg);
14067                throw new SecurityException(msg);
14068            }
14069            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14070            if (stickies != null) {
14071                ArrayList<Intent> list = stickies.get(intent.getAction());
14072                if (list != null) {
14073                    int N = list.size();
14074                    int i;
14075                    for (i=0; i<N; i++) {
14076                        if (intent.filterEquals(list.get(i))) {
14077                            list.remove(i);
14078                            break;
14079                        }
14080                    }
14081                    if (list.size() <= 0) {
14082                        stickies.remove(intent.getAction());
14083                    }
14084                }
14085                if (stickies.size() <= 0) {
14086                    mStickyBroadcasts.remove(userId);
14087                }
14088            }
14089        }
14090    }
14091
14092    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14093            String resultData, Bundle resultExtras, boolean resultAbort) {
14094        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14095        if (r == null) {
14096            Slog.w(TAG, "finishReceiver called but not found on queue");
14097            return false;
14098        }
14099
14100        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14101    }
14102
14103    void backgroundServicesFinishedLocked(int userId) {
14104        for (BroadcastQueue queue : mBroadcastQueues) {
14105            queue.backgroundServicesFinishedLocked(userId);
14106        }
14107    }
14108
14109    public void finishReceiver(IBinder who, int resultCode, String resultData,
14110            Bundle resultExtras, boolean resultAbort) {
14111        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14112
14113        // Refuse possible leaked file descriptors
14114        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14115            throw new IllegalArgumentException("File descriptors passed in Bundle");
14116        }
14117
14118        final long origId = Binder.clearCallingIdentity();
14119        try {
14120            boolean doNext = false;
14121            BroadcastRecord r;
14122
14123            synchronized(this) {
14124                r = broadcastRecordForReceiverLocked(who);
14125                if (r != null) {
14126                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14127                        resultData, resultExtras, resultAbort, true);
14128                }
14129            }
14130
14131            if (doNext) {
14132                r.queue.processNextBroadcast(false);
14133            }
14134            trimApplications();
14135        } finally {
14136            Binder.restoreCallingIdentity(origId);
14137        }
14138    }
14139
14140    // =========================================================
14141    // INSTRUMENTATION
14142    // =========================================================
14143
14144    public boolean startInstrumentation(ComponentName className,
14145            String profileFile, int flags, Bundle arguments,
14146            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14147            int userId) {
14148        enforceNotIsolatedCaller("startInstrumentation");
14149        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14150                userId, false, true, "startInstrumentation", null);
14151        // Refuse possible leaked file descriptors
14152        if (arguments != null && arguments.hasFileDescriptors()) {
14153            throw new IllegalArgumentException("File descriptors passed in Bundle");
14154        }
14155
14156        synchronized(this) {
14157            InstrumentationInfo ii = null;
14158            ApplicationInfo ai = null;
14159            try {
14160                ii = mContext.getPackageManager().getInstrumentationInfo(
14161                    className, STOCK_PM_FLAGS);
14162                ai = AppGlobals.getPackageManager().getApplicationInfo(
14163                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14164            } catch (PackageManager.NameNotFoundException e) {
14165            } catch (RemoteException e) {
14166            }
14167            if (ii == null) {
14168                reportStartInstrumentationFailure(watcher, className,
14169                        "Unable to find instrumentation info for: " + className);
14170                return false;
14171            }
14172            if (ai == null) {
14173                reportStartInstrumentationFailure(watcher, className,
14174                        "Unable to find instrumentation target package: " + ii.targetPackage);
14175                return false;
14176            }
14177
14178            int match = mContext.getPackageManager().checkSignatures(
14179                    ii.targetPackage, ii.packageName);
14180            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14181                String msg = "Permission Denial: starting instrumentation "
14182                        + className + " from pid="
14183                        + Binder.getCallingPid()
14184                        + ", uid=" + Binder.getCallingPid()
14185                        + " not allowed because package " + ii.packageName
14186                        + " does not have a signature matching the target "
14187                        + ii.targetPackage;
14188                reportStartInstrumentationFailure(watcher, className, msg);
14189                throw new SecurityException(msg);
14190            }
14191
14192            final long origId = Binder.clearCallingIdentity();
14193            // Instrumentation can kill and relaunch even persistent processes
14194            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14195                    "start instr");
14196            ProcessRecord app = addAppLocked(ai, false);
14197            app.instrumentationClass = className;
14198            app.instrumentationInfo = ai;
14199            app.instrumentationProfileFile = profileFile;
14200            app.instrumentationArguments = arguments;
14201            app.instrumentationWatcher = watcher;
14202            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14203            app.instrumentationResultClass = className;
14204            Binder.restoreCallingIdentity(origId);
14205        }
14206
14207        return true;
14208    }
14209
14210    /**
14211     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14212     * error to the logs, but if somebody is watching, send the report there too.  This enables
14213     * the "am" command to report errors with more information.
14214     *
14215     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14216     * @param cn The component name of the instrumentation.
14217     * @param report The error report.
14218     */
14219    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14220            ComponentName cn, String report) {
14221        Slog.w(TAG, report);
14222        try {
14223            if (watcher != null) {
14224                Bundle results = new Bundle();
14225                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14226                results.putString("Error", report);
14227                watcher.instrumentationStatus(cn, -1, results);
14228            }
14229        } catch (RemoteException e) {
14230            Slog.w(TAG, e);
14231        }
14232    }
14233
14234    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14235        if (app.instrumentationWatcher != null) {
14236            try {
14237                // NOTE:  IInstrumentationWatcher *must* be oneway here
14238                app.instrumentationWatcher.instrumentationFinished(
14239                    app.instrumentationClass,
14240                    resultCode,
14241                    results);
14242            } catch (RemoteException e) {
14243            }
14244        }
14245        if (app.instrumentationUiAutomationConnection != null) {
14246            try {
14247                app.instrumentationUiAutomationConnection.shutdown();
14248            } catch (RemoteException re) {
14249                /* ignore */
14250            }
14251            // Only a UiAutomation can set this flag and now that
14252            // it is finished we make sure it is reset to its default.
14253            mUserIsMonkey = false;
14254        }
14255        app.instrumentationWatcher = null;
14256        app.instrumentationUiAutomationConnection = null;
14257        app.instrumentationClass = null;
14258        app.instrumentationInfo = null;
14259        app.instrumentationProfileFile = null;
14260        app.instrumentationArguments = null;
14261
14262        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14263                "finished inst");
14264    }
14265
14266    public void finishInstrumentation(IApplicationThread target,
14267            int resultCode, Bundle results) {
14268        int userId = UserHandle.getCallingUserId();
14269        // Refuse possible leaked file descriptors
14270        if (results != null && results.hasFileDescriptors()) {
14271            throw new IllegalArgumentException("File descriptors passed in Intent");
14272        }
14273
14274        synchronized(this) {
14275            ProcessRecord app = getRecordForAppLocked(target);
14276            if (app == null) {
14277                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14278                return;
14279            }
14280            final long origId = Binder.clearCallingIdentity();
14281            finishInstrumentationLocked(app, resultCode, results);
14282            Binder.restoreCallingIdentity(origId);
14283        }
14284    }
14285
14286    // =========================================================
14287    // CONFIGURATION
14288    // =========================================================
14289
14290    public ConfigurationInfo getDeviceConfigurationInfo() {
14291        ConfigurationInfo config = new ConfigurationInfo();
14292        synchronized (this) {
14293            config.reqTouchScreen = mConfiguration.touchscreen;
14294            config.reqKeyboardType = mConfiguration.keyboard;
14295            config.reqNavigation = mConfiguration.navigation;
14296            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14297                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14298                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14299            }
14300            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14301                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14302                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14303            }
14304            config.reqGlEsVersion = GL_ES_VERSION;
14305        }
14306        return config;
14307    }
14308
14309    ActivityStack getFocusedStack() {
14310        return mStackSupervisor.getFocusedStack();
14311    }
14312
14313    public Configuration getConfiguration() {
14314        Configuration ci;
14315        synchronized(this) {
14316            ci = new Configuration(mConfiguration);
14317        }
14318        return ci;
14319    }
14320
14321    public void updatePersistentConfiguration(Configuration values) {
14322        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14323                "updateConfiguration()");
14324        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14325                "updateConfiguration()");
14326        if (values == null) {
14327            throw new NullPointerException("Configuration must not be null");
14328        }
14329
14330        synchronized(this) {
14331            final long origId = Binder.clearCallingIdentity();
14332            updateConfigurationLocked(values, null, true, false);
14333            Binder.restoreCallingIdentity(origId);
14334        }
14335    }
14336
14337    public void updateConfiguration(Configuration values) {
14338        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14339                "updateConfiguration()");
14340
14341        synchronized(this) {
14342            if (values == null && mWindowManager != null) {
14343                // sentinel: fetch the current configuration from the window manager
14344                values = mWindowManager.computeNewConfiguration();
14345            }
14346
14347            if (mWindowManager != null) {
14348                mProcessList.applyDisplaySize(mWindowManager);
14349            }
14350
14351            final long origId = Binder.clearCallingIdentity();
14352            if (values != null) {
14353                Settings.System.clearConfiguration(values);
14354            }
14355            updateConfigurationLocked(values, null, false, false);
14356            Binder.restoreCallingIdentity(origId);
14357        }
14358    }
14359
14360    /**
14361     * Do either or both things: (1) change the current configuration, and (2)
14362     * make sure the given activity is running with the (now) current
14363     * configuration.  Returns true if the activity has been left running, or
14364     * false if <var>starting</var> is being destroyed to match the new
14365     * configuration.
14366     * @param persistent TODO
14367     */
14368    boolean updateConfigurationLocked(Configuration values,
14369            ActivityRecord starting, boolean persistent, boolean initLocale) {
14370        int changes = 0;
14371
14372        if (values != null) {
14373            Configuration newConfig = new Configuration(mConfiguration);
14374            changes = newConfig.updateFrom(values);
14375            if (changes != 0) {
14376                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14377                    Slog.i(TAG, "Updating configuration to: " + values);
14378                }
14379
14380                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14381
14382                if (values.locale != null && !initLocale) {
14383                    saveLocaleLocked(values.locale,
14384                                     !values.locale.equals(mConfiguration.locale),
14385                                     values.userSetLocale);
14386                }
14387
14388                mConfigurationSeq++;
14389                if (mConfigurationSeq <= 0) {
14390                    mConfigurationSeq = 1;
14391                }
14392                newConfig.seq = mConfigurationSeq;
14393                mConfiguration = newConfig;
14394                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14395                mUsageStatsService.noteStartConfig(newConfig);
14396
14397                final Configuration configCopy = new Configuration(mConfiguration);
14398
14399                // TODO: If our config changes, should we auto dismiss any currently
14400                // showing dialogs?
14401                mShowDialogs = shouldShowDialogs(newConfig);
14402
14403                AttributeCache ac = AttributeCache.instance();
14404                if (ac != null) {
14405                    ac.updateConfiguration(configCopy);
14406                }
14407
14408                // Make sure all resources in our process are updated
14409                // right now, so that anyone who is going to retrieve
14410                // resource values after we return will be sure to get
14411                // the new ones.  This is especially important during
14412                // boot, where the first config change needs to guarantee
14413                // all resources have that config before following boot
14414                // code is executed.
14415                mSystemThread.applyConfigurationToResources(configCopy);
14416
14417                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14418                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14419                    msg.obj = new Configuration(configCopy);
14420                    mHandler.sendMessage(msg);
14421                }
14422
14423                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14424                    ProcessRecord app = mLruProcesses.get(i);
14425                    try {
14426                        if (app.thread != null) {
14427                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14428                                    + app.processName + " new config " + mConfiguration);
14429                            app.thread.scheduleConfigurationChanged(configCopy);
14430                        }
14431                    } catch (Exception e) {
14432                    }
14433                }
14434                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14435                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14436                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14437                        | Intent.FLAG_RECEIVER_FOREGROUND);
14438                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14439                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14440                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14441                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14442                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14443                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14444                    broadcastIntentLocked(null, null, intent,
14445                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14446                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14447                }
14448            }
14449        }
14450
14451        boolean kept = true;
14452        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14453        // mainStack is null during startup.
14454        if (mainStack != null) {
14455            if (changes != 0 && starting == null) {
14456                // If the configuration changed, and the caller is not already
14457                // in the process of starting an activity, then find the top
14458                // activity to check if its configuration needs to change.
14459                starting = mainStack.topRunningActivityLocked(null);
14460            }
14461
14462            if (starting != null) {
14463                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14464                // And we need to make sure at this point that all other activities
14465                // are made visible with the correct configuration.
14466                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14467            }
14468        }
14469
14470        if (values != null && mWindowManager != null) {
14471            mWindowManager.setNewConfiguration(mConfiguration);
14472        }
14473
14474        return kept;
14475    }
14476
14477    /**
14478     * Decide based on the configuration whether we should shouw the ANR,
14479     * crash, etc dialogs.  The idea is that if there is no affordnace to
14480     * press the on-screen buttons, we shouldn't show the dialog.
14481     *
14482     * A thought: SystemUI might also want to get told about this, the Power
14483     * dialog / global actions also might want different behaviors.
14484     */
14485    private static final boolean shouldShowDialogs(Configuration config) {
14486        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14487                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14488    }
14489
14490    /**
14491     * Save the locale.  You must be inside a synchronized (this) block.
14492     */
14493    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14494        if(isDiff) {
14495            SystemProperties.set("user.language", l.getLanguage());
14496            SystemProperties.set("user.region", l.getCountry());
14497        }
14498
14499        if(isPersist) {
14500            SystemProperties.set("persist.sys.language", l.getLanguage());
14501            SystemProperties.set("persist.sys.country", l.getCountry());
14502            SystemProperties.set("persist.sys.localevar", l.getVariant());
14503        }
14504    }
14505
14506    @Override
14507    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14508        ActivityRecord srec = ActivityRecord.forToken(token);
14509        return srec != null && srec.task.affinity != null &&
14510                srec.task.affinity.equals(destAffinity);
14511    }
14512
14513    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14514            Intent resultData) {
14515
14516        synchronized (this) {
14517            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14518            if (stack != null) {
14519                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14520            }
14521            return false;
14522        }
14523    }
14524
14525    public int getLaunchedFromUid(IBinder activityToken) {
14526        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14527        if (srec == null) {
14528            return -1;
14529        }
14530        return srec.launchedFromUid;
14531    }
14532
14533    public String getLaunchedFromPackage(IBinder activityToken) {
14534        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14535        if (srec == null) {
14536            return null;
14537        }
14538        return srec.launchedFromPackage;
14539    }
14540
14541    // =========================================================
14542    // LIFETIME MANAGEMENT
14543    // =========================================================
14544
14545    // Returns which broadcast queue the app is the current [or imminent] receiver
14546    // on, or 'null' if the app is not an active broadcast recipient.
14547    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14548        BroadcastRecord r = app.curReceiver;
14549        if (r != null) {
14550            return r.queue;
14551        }
14552
14553        // It's not the current receiver, but it might be starting up to become one
14554        synchronized (this) {
14555            for (BroadcastQueue queue : mBroadcastQueues) {
14556                r = queue.mPendingBroadcast;
14557                if (r != null && r.curApp == app) {
14558                    // found it; report which queue it's in
14559                    return queue;
14560                }
14561            }
14562        }
14563
14564        return null;
14565    }
14566
14567    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14568            boolean doingAll, long now) {
14569        if (mAdjSeq == app.adjSeq) {
14570            // This adjustment has already been computed.
14571            return app.curRawAdj;
14572        }
14573
14574        if (app.thread == null) {
14575            app.adjSeq = mAdjSeq;
14576            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14577            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14578            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14579        }
14580
14581        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14582        app.adjSource = null;
14583        app.adjTarget = null;
14584        app.empty = false;
14585        app.cached = false;
14586
14587        final int activitiesSize = app.activities.size();
14588
14589        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14590            // The max adjustment doesn't allow this app to be anything
14591            // below foreground, so it is not worth doing work for it.
14592            app.adjType = "fixed";
14593            app.adjSeq = mAdjSeq;
14594            app.curRawAdj = app.maxAdj;
14595            app.foregroundActivities = false;
14596            app.keeping = true;
14597            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14598            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14599            // System processes can do UI, and when they do we want to have
14600            // them trim their memory after the user leaves the UI.  To
14601            // facilitate this, here we need to determine whether or not it
14602            // is currently showing UI.
14603            app.systemNoUi = true;
14604            if (app == TOP_APP) {
14605                app.systemNoUi = false;
14606            } else if (activitiesSize > 0) {
14607                for (int j = 0; j < activitiesSize; j++) {
14608                    final ActivityRecord r = app.activities.get(j);
14609                    if (r.visible) {
14610                        app.systemNoUi = false;
14611                    }
14612                }
14613            }
14614            if (!app.systemNoUi) {
14615                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14616            }
14617            return (app.curAdj=app.maxAdj);
14618        }
14619
14620        app.keeping = false;
14621        app.systemNoUi = false;
14622
14623        // Determine the importance of the process, starting with most
14624        // important to least, and assign an appropriate OOM adjustment.
14625        int adj;
14626        int schedGroup;
14627        int procState;
14628        boolean foregroundActivities = false;
14629        boolean interesting = false;
14630        BroadcastQueue queue;
14631        if (app == TOP_APP) {
14632            // The last app on the list is the foreground app.
14633            adj = ProcessList.FOREGROUND_APP_ADJ;
14634            schedGroup = Process.THREAD_GROUP_DEFAULT;
14635            app.adjType = "top-activity";
14636            foregroundActivities = true;
14637            interesting = true;
14638            procState = ActivityManager.PROCESS_STATE_TOP;
14639        } else if (app.instrumentationClass != null) {
14640            // Don't want to kill running instrumentation.
14641            adj = ProcessList.FOREGROUND_APP_ADJ;
14642            schedGroup = Process.THREAD_GROUP_DEFAULT;
14643            app.adjType = "instrumentation";
14644            interesting = true;
14645            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14646        } else if ((queue = isReceivingBroadcast(app)) != null) {
14647            // An app that is currently receiving a broadcast also
14648            // counts as being in the foreground for OOM killer purposes.
14649            // It's placed in a sched group based on the nature of the
14650            // broadcast as reflected by which queue it's active in.
14651            adj = ProcessList.FOREGROUND_APP_ADJ;
14652            schedGroup = (queue == mFgBroadcastQueue)
14653                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14654            app.adjType = "broadcast";
14655            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14656        } else if (app.executingServices.size() > 0) {
14657            // An app that is currently executing a service callback also
14658            // counts as being in the foreground.
14659            adj = ProcessList.FOREGROUND_APP_ADJ;
14660            schedGroup = app.execServicesFg ?
14661                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14662            app.adjType = "exec-service";
14663            procState = ActivityManager.PROCESS_STATE_SERVICE;
14664            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14665        } else {
14666            // As far as we know the process is empty.  We may change our mind later.
14667            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14668            // At this point we don't actually know the adjustment.  Use the cached adj
14669            // value that the caller wants us to.
14670            adj = cachedAdj;
14671            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14672            app.cached = true;
14673            app.empty = true;
14674            app.adjType = "cch-empty";
14675        }
14676
14677        // Examine all activities if not already foreground.
14678        if (!foregroundActivities && activitiesSize > 0) {
14679            for (int j = 0; j < activitiesSize; j++) {
14680                final ActivityRecord r = app.activities.get(j);
14681                if (r.app != app) {
14682                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14683                            + app + "?!?");
14684                    continue;
14685                }
14686                if (r.visible) {
14687                    // App has a visible activity; only upgrade adjustment.
14688                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14689                        adj = ProcessList.VISIBLE_APP_ADJ;
14690                        app.adjType = "visible";
14691                    }
14692                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14693                        procState = ActivityManager.PROCESS_STATE_TOP;
14694                    }
14695                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14696                    app.cached = false;
14697                    app.empty = false;
14698                    foregroundActivities = true;
14699                    break;
14700                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14701                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14702                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14703                        app.adjType = "pausing";
14704                    }
14705                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14706                        procState = ActivityManager.PROCESS_STATE_TOP;
14707                    }
14708                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14709                    app.cached = false;
14710                    app.empty = false;
14711                    foregroundActivities = true;
14712                } else if (r.state == ActivityState.STOPPING) {
14713                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14714                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14715                        app.adjType = "stopping";
14716                    }
14717                    // For the process state, we will at this point consider the
14718                    // process to be cached.  It will be cached either as an activity
14719                    // or empty depending on whether the activity is finishing.  We do
14720                    // this so that we can treat the process as cached for purposes of
14721                    // memory trimming (determing current memory level, trim command to
14722                    // send to process) since there can be an arbitrary number of stopping
14723                    // processes and they should soon all go into the cached state.
14724                    if (!r.finishing) {
14725                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14726                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14727                        }
14728                    }
14729                    app.cached = false;
14730                    app.empty = false;
14731                    foregroundActivities = true;
14732                } else {
14733                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14734                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14735                        app.adjType = "cch-act";
14736                    }
14737                }
14738            }
14739        }
14740
14741        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14742            if (app.foregroundServices) {
14743                // The user is aware of this app, so make it visible.
14744                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14745                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14746                app.cached = false;
14747                app.adjType = "fg-service";
14748                schedGroup = Process.THREAD_GROUP_DEFAULT;
14749            } else if (app.forcingToForeground != null) {
14750                // The user is aware of this app, so make it visible.
14751                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14752                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14753                app.cached = false;
14754                app.adjType = "force-fg";
14755                app.adjSource = app.forcingToForeground;
14756                schedGroup = Process.THREAD_GROUP_DEFAULT;
14757            }
14758        }
14759
14760        if (app.foregroundServices) {
14761            interesting = true;
14762        }
14763
14764        if (app == mHeavyWeightProcess) {
14765            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14766                // We don't want to kill the current heavy-weight process.
14767                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14768                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14769                app.cached = false;
14770                app.adjType = "heavy";
14771            }
14772            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14773                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14774            }
14775        }
14776
14777        if (app == mHomeProcess) {
14778            if (adj > ProcessList.HOME_APP_ADJ) {
14779                // This process is hosting what we currently consider to be the
14780                // home app, so we don't want to let it go into the background.
14781                adj = ProcessList.HOME_APP_ADJ;
14782                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14783                app.cached = false;
14784                app.adjType = "home";
14785            }
14786            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14787                procState = ActivityManager.PROCESS_STATE_HOME;
14788            }
14789        }
14790
14791        if (app == mPreviousProcess && app.activities.size() > 0) {
14792            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14793                // This was the previous process that showed UI to the user.
14794                // We want to try to keep it around more aggressively, to give
14795                // a good experience around switching between two apps.
14796                adj = ProcessList.PREVIOUS_APP_ADJ;
14797                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14798                app.cached = false;
14799                app.adjType = "previous";
14800            }
14801            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14802                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14803            }
14804        }
14805
14806        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14807                + " reason=" + app.adjType);
14808
14809        // By default, we use the computed adjustment.  It may be changed if
14810        // there are applications dependent on our services or providers, but
14811        // this gives us a baseline and makes sure we don't get into an
14812        // infinite recursion.
14813        app.adjSeq = mAdjSeq;
14814        app.curRawAdj = adj;
14815        app.hasStartedServices = false;
14816
14817        if (mBackupTarget != null && app == mBackupTarget.app) {
14818            // If possible we want to avoid killing apps while they're being backed up
14819            if (adj > ProcessList.BACKUP_APP_ADJ) {
14820                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14821                adj = ProcessList.BACKUP_APP_ADJ;
14822                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14823                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14824                }
14825                app.adjType = "backup";
14826                app.cached = false;
14827            }
14828            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14829                procState = ActivityManager.PROCESS_STATE_BACKUP;
14830            }
14831        }
14832
14833        boolean mayBeTop = false;
14834
14835        for (int is = app.services.size()-1;
14836                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14837                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14838                        || procState > ActivityManager.PROCESS_STATE_TOP);
14839                is--) {
14840            ServiceRecord s = app.services.valueAt(is);
14841            if (s.startRequested) {
14842                app.hasStartedServices = true;
14843                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14844                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14845                }
14846                if (app.hasShownUi && app != mHomeProcess) {
14847                    // If this process has shown some UI, let it immediately
14848                    // go to the LRU list because it may be pretty heavy with
14849                    // UI stuff.  We'll tag it with a label just to help
14850                    // debug and understand what is going on.
14851                    if (adj > ProcessList.SERVICE_ADJ) {
14852                        app.adjType = "cch-started-ui-services";
14853                    }
14854                } else {
14855                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14856                        // This service has seen some activity within
14857                        // recent memory, so we will keep its process ahead
14858                        // of the background processes.
14859                        if (adj > ProcessList.SERVICE_ADJ) {
14860                            adj = ProcessList.SERVICE_ADJ;
14861                            app.adjType = "started-services";
14862                            app.cached = false;
14863                        }
14864                    }
14865                    // If we have let the service slide into the background
14866                    // state, still have some text describing what it is doing
14867                    // even though the service no longer has an impact.
14868                    if (adj > ProcessList.SERVICE_ADJ) {
14869                        app.adjType = "cch-started-services";
14870                    }
14871                }
14872                // Don't kill this process because it is doing work; it
14873                // has said it is doing work.
14874                app.keeping = true;
14875            }
14876            for (int conni = s.connections.size()-1;
14877                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14878                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14879                            || procState > ActivityManager.PROCESS_STATE_TOP);
14880                    conni--) {
14881                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14882                for (int i = 0;
14883                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14884                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14885                                || procState > ActivityManager.PROCESS_STATE_TOP);
14886                        i++) {
14887                    // XXX should compute this based on the max of
14888                    // all connected clients.
14889                    ConnectionRecord cr = clist.get(i);
14890                    if (cr.binding.client == app) {
14891                        // Binding to ourself is not interesting.
14892                        continue;
14893                    }
14894                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14895                        ProcessRecord client = cr.binding.client;
14896                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14897                                TOP_APP, doingAll, now);
14898                        int clientProcState = client.curProcState;
14899                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14900                            // If the other app is cached for any reason, for purposes here
14901                            // we are going to consider it empty.  The specific cached state
14902                            // doesn't propagate except under certain conditions.
14903                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14904                        }
14905                        String adjType = null;
14906                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14907                            // Not doing bind OOM management, so treat
14908                            // this guy more like a started service.
14909                            if (app.hasShownUi && app != mHomeProcess) {
14910                                // If this process has shown some UI, let it immediately
14911                                // go to the LRU list because it may be pretty heavy with
14912                                // UI stuff.  We'll tag it with a label just to help
14913                                // debug and understand what is going on.
14914                                if (adj > clientAdj) {
14915                                    adjType = "cch-bound-ui-services";
14916                                }
14917                                app.cached = false;
14918                                clientAdj = adj;
14919                                clientProcState = procState;
14920                            } else {
14921                                if (now >= (s.lastActivity
14922                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14923                                    // This service has not seen activity within
14924                                    // recent memory, so allow it to drop to the
14925                                    // LRU list if there is no other reason to keep
14926                                    // it around.  We'll also tag it with a label just
14927                                    // to help debug and undertand what is going on.
14928                                    if (adj > clientAdj) {
14929                                        adjType = "cch-bound-services";
14930                                    }
14931                                    clientAdj = adj;
14932                                }
14933                            }
14934                        }
14935                        if (adj > clientAdj) {
14936                            // If this process has recently shown UI, and
14937                            // the process that is binding to it is less
14938                            // important than being visible, then we don't
14939                            // care about the binding as much as we care
14940                            // about letting this process get into the LRU
14941                            // list to be killed and restarted if needed for
14942                            // memory.
14943                            if (app.hasShownUi && app != mHomeProcess
14944                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14945                                adjType = "cch-bound-ui-services";
14946                            } else {
14947                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14948                                        |Context.BIND_IMPORTANT)) != 0) {
14949                                    adj = clientAdj;
14950                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14951                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14952                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14953                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14954                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
14955                                    adj = clientAdj;
14956                                } else {
14957                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14958                                        adj = ProcessList.VISIBLE_APP_ADJ;
14959                                    }
14960                                }
14961                                if (!client.cached) {
14962                                    app.cached = false;
14963                                }
14964                                if (client.keeping) {
14965                                    app.keeping = true;
14966                                }
14967                                adjType = "service";
14968                            }
14969                        }
14970                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14971                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14972                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14973                            }
14974                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14975                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14976                                    // Special handling of clients who are in the top state.
14977                                    // We *may* want to consider this process to be in the
14978                                    // top state as well, but only if there is not another
14979                                    // reason for it to be running.  Being on the top is a
14980                                    // special state, meaning you are specifically running
14981                                    // for the current top app.  If the process is already
14982                                    // running in the background for some other reason, it
14983                                    // is more important to continue considering it to be
14984                                    // in the background state.
14985                                    mayBeTop = true;
14986                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14987                                } else {
14988                                    // Special handling for above-top states (persistent
14989                                    // processes).  These should not bring the current process
14990                                    // into the top state, since they are not on top.  Instead
14991                                    // give them the best state after that.
14992                                    clientProcState =
14993                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14994                                }
14995                            }
14996                        } else {
14997                            if (clientProcState <
14998                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14999                                clientProcState =
15000                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15001                            }
15002                        }
15003                        if (procState > clientProcState) {
15004                            procState = clientProcState;
15005                        }
15006                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15007                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15008                            app.pendingUiClean = true;
15009                        }
15010                        if (adjType != null) {
15011                            app.adjType = adjType;
15012                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15013                                    .REASON_SERVICE_IN_USE;
15014                            app.adjSource = cr.binding.client;
15015                            app.adjSourceOom = clientAdj;
15016                            app.adjTarget = s.name;
15017                        }
15018                    }
15019                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15020                        app.treatLikeActivity = true;
15021                    }
15022                    final ActivityRecord a = cr.activity;
15023                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15024                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15025                                (a.visible || a.state == ActivityState.RESUMED
15026                                 || a.state == ActivityState.PAUSING)) {
15027                            adj = ProcessList.FOREGROUND_APP_ADJ;
15028                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15029                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15030                            }
15031                            app.cached = false;
15032                            app.adjType = "service";
15033                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15034                                    .REASON_SERVICE_IN_USE;
15035                            app.adjSource = a;
15036                            app.adjSourceOom = adj;
15037                            app.adjTarget = s.name;
15038                        }
15039                    }
15040                }
15041            }
15042        }
15043
15044        for (int provi = app.pubProviders.size()-1;
15045                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15046                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15047                        || procState > ActivityManager.PROCESS_STATE_TOP);
15048                provi--) {
15049            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15050            for (int i = cpr.connections.size()-1;
15051                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15052                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15053                            || procState > ActivityManager.PROCESS_STATE_TOP);
15054                    i--) {
15055                ContentProviderConnection conn = cpr.connections.get(i);
15056                ProcessRecord client = conn.client;
15057                if (client == app) {
15058                    // Being our own client is not interesting.
15059                    continue;
15060                }
15061                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15062                int clientProcState = client.curProcState;
15063                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15064                    // If the other app is cached for any reason, for purposes here
15065                    // we are going to consider it empty.
15066                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15067                }
15068                if (adj > clientAdj) {
15069                    if (app.hasShownUi && app != mHomeProcess
15070                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15071                        app.adjType = "cch-ui-provider";
15072                    } else {
15073                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15074                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15075                        app.adjType = "provider";
15076                    }
15077                    app.cached &= client.cached;
15078                    app.keeping |= client.keeping;
15079                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15080                            .REASON_PROVIDER_IN_USE;
15081                    app.adjSource = client;
15082                    app.adjSourceOom = clientAdj;
15083                    app.adjTarget = cpr.name;
15084                }
15085                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15086                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15087                        // Special handling of clients who are in the top state.
15088                        // We *may* want to consider this process to be in the
15089                        // top state as well, but only if there is not another
15090                        // reason for it to be running.  Being on the top is a
15091                        // special state, meaning you are specifically running
15092                        // for the current top app.  If the process is already
15093                        // running in the background for some other reason, it
15094                        // is more important to continue considering it to be
15095                        // in the background state.
15096                        mayBeTop = true;
15097                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15098                    } else {
15099                        // Special handling for above-top states (persistent
15100                        // processes).  These should not bring the current process
15101                        // into the top state, since they are not on top.  Instead
15102                        // give them the best state after that.
15103                        clientProcState =
15104                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15105                    }
15106                }
15107                if (procState > clientProcState) {
15108                    procState = clientProcState;
15109                }
15110                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15111                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15112                }
15113            }
15114            // If the provider has external (non-framework) process
15115            // dependencies, ensure that its adjustment is at least
15116            // FOREGROUND_APP_ADJ.
15117            if (cpr.hasExternalProcessHandles()) {
15118                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15119                    adj = ProcessList.FOREGROUND_APP_ADJ;
15120                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15121                    app.cached = false;
15122                    app.keeping = true;
15123                    app.adjType = "provider";
15124                    app.adjTarget = cpr.name;
15125                }
15126                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15127                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15128                }
15129            }
15130        }
15131
15132        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15133            // A client of one of our services or providers is in the top state.  We
15134            // *may* want to be in the top state, but not if we are already running in
15135            // the background for some other reason.  For the decision here, we are going
15136            // to pick out a few specific states that we want to remain in when a client
15137            // is top (states that tend to be longer-term) and otherwise allow it to go
15138            // to the top state.
15139            switch (procState) {
15140                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15141                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15142                case ActivityManager.PROCESS_STATE_SERVICE:
15143                    // These all are longer-term states, so pull them up to the top
15144                    // of the background states, but not all the way to the top state.
15145                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15146                    break;
15147                default:
15148                    // Otherwise, top is a better choice, so take it.
15149                    procState = ActivityManager.PROCESS_STATE_TOP;
15150                    break;
15151            }
15152        }
15153
15154        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15155            if (app.hasClientActivities) {
15156                // This is a cached process, but with client activities.  Mark it so.
15157                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15158                app.adjType = "cch-client-act";
15159            } else if (app.treatLikeActivity) {
15160                // This is a cached process, but somebody wants us to treat it like it has
15161                // an activity, okay!
15162                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15163                app.adjType = "cch-as-act";
15164            }
15165        }
15166
15167        if (adj == ProcessList.SERVICE_ADJ) {
15168            if (doingAll) {
15169                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15170                mNewNumServiceProcs++;
15171                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15172                if (!app.serviceb) {
15173                    // This service isn't far enough down on the LRU list to
15174                    // normally be a B service, but if we are low on RAM and it
15175                    // is large we want to force it down since we would prefer to
15176                    // keep launcher over it.
15177                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15178                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15179                        app.serviceHighRam = true;
15180                        app.serviceb = true;
15181                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15182                    } else {
15183                        mNewNumAServiceProcs++;
15184                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15185                    }
15186                } else {
15187                    app.serviceHighRam = false;
15188                }
15189            }
15190            if (app.serviceb) {
15191                adj = ProcessList.SERVICE_B_ADJ;
15192            }
15193        }
15194
15195        app.curRawAdj = adj;
15196
15197        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15198        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15199        if (adj > app.maxAdj) {
15200            adj = app.maxAdj;
15201            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15202                schedGroup = Process.THREAD_GROUP_DEFAULT;
15203            }
15204        }
15205        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15206            app.keeping = true;
15207        }
15208
15209        // Do final modification to adj.  Everything we do between here and applying
15210        // the final setAdj must be done in this function, because we will also use
15211        // it when computing the final cached adj later.  Note that we don't need to
15212        // worry about this for max adj above, since max adj will always be used to
15213        // keep it out of the cached vaues.
15214        app.curAdj = app.modifyRawOomAdj(adj);
15215        app.curSchedGroup = schedGroup;
15216        app.curProcState = procState;
15217        app.foregroundActivities = foregroundActivities;
15218
15219        return app.curRawAdj;
15220    }
15221
15222    /**
15223     * Schedule PSS collection of a process.
15224     */
15225    void requestPssLocked(ProcessRecord proc, int procState) {
15226        if (mPendingPssProcesses.contains(proc)) {
15227            return;
15228        }
15229        if (mPendingPssProcesses.size() == 0) {
15230            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15231        }
15232        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15233        proc.pssProcState = procState;
15234        mPendingPssProcesses.add(proc);
15235    }
15236
15237    /**
15238     * Schedule PSS collection of all processes.
15239     */
15240    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15241        if (!always) {
15242            if (now < (mLastFullPssTime +
15243                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15244                return;
15245            }
15246        }
15247        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15248        mLastFullPssTime = now;
15249        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15250        mPendingPssProcesses.clear();
15251        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15252            ProcessRecord app = mLruProcesses.get(i);
15253            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15254                app.pssProcState = app.setProcState;
15255                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15256                        isSleeping(), now);
15257                mPendingPssProcesses.add(app);
15258            }
15259        }
15260        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15261    }
15262
15263    /**
15264     * Ask a given process to GC right now.
15265     */
15266    final void performAppGcLocked(ProcessRecord app) {
15267        try {
15268            app.lastRequestedGc = SystemClock.uptimeMillis();
15269            if (app.thread != null) {
15270                if (app.reportLowMemory) {
15271                    app.reportLowMemory = false;
15272                    app.thread.scheduleLowMemory();
15273                } else {
15274                    app.thread.processInBackground();
15275                }
15276            }
15277        } catch (Exception e) {
15278            // whatever.
15279        }
15280    }
15281
15282    /**
15283     * Returns true if things are idle enough to perform GCs.
15284     */
15285    private final boolean canGcNowLocked() {
15286        boolean processingBroadcasts = false;
15287        for (BroadcastQueue q : mBroadcastQueues) {
15288            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15289                processingBroadcasts = true;
15290            }
15291        }
15292        return !processingBroadcasts
15293                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15294    }
15295
15296    /**
15297     * Perform GCs on all processes that are waiting for it, but only
15298     * if things are idle.
15299     */
15300    final void performAppGcsLocked() {
15301        final int N = mProcessesToGc.size();
15302        if (N <= 0) {
15303            return;
15304        }
15305        if (canGcNowLocked()) {
15306            while (mProcessesToGc.size() > 0) {
15307                ProcessRecord proc = mProcessesToGc.remove(0);
15308                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15309                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15310                            <= SystemClock.uptimeMillis()) {
15311                        // To avoid spamming the system, we will GC processes one
15312                        // at a time, waiting a few seconds between each.
15313                        performAppGcLocked(proc);
15314                        scheduleAppGcsLocked();
15315                        return;
15316                    } else {
15317                        // It hasn't been long enough since we last GCed this
15318                        // process...  put it in the list to wait for its time.
15319                        addProcessToGcListLocked(proc);
15320                        break;
15321                    }
15322                }
15323            }
15324
15325            scheduleAppGcsLocked();
15326        }
15327    }
15328
15329    /**
15330     * If all looks good, perform GCs on all processes waiting for them.
15331     */
15332    final void performAppGcsIfAppropriateLocked() {
15333        if (canGcNowLocked()) {
15334            performAppGcsLocked();
15335            return;
15336        }
15337        // Still not idle, wait some more.
15338        scheduleAppGcsLocked();
15339    }
15340
15341    /**
15342     * Schedule the execution of all pending app GCs.
15343     */
15344    final void scheduleAppGcsLocked() {
15345        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15346
15347        if (mProcessesToGc.size() > 0) {
15348            // Schedule a GC for the time to the next process.
15349            ProcessRecord proc = mProcessesToGc.get(0);
15350            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15351
15352            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15353            long now = SystemClock.uptimeMillis();
15354            if (when < (now+GC_TIMEOUT)) {
15355                when = now + GC_TIMEOUT;
15356            }
15357            mHandler.sendMessageAtTime(msg, when);
15358        }
15359    }
15360
15361    /**
15362     * Add a process to the array of processes waiting to be GCed.  Keeps the
15363     * list in sorted order by the last GC time.  The process can't already be
15364     * on the list.
15365     */
15366    final void addProcessToGcListLocked(ProcessRecord proc) {
15367        boolean added = false;
15368        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15369            if (mProcessesToGc.get(i).lastRequestedGc <
15370                    proc.lastRequestedGc) {
15371                added = true;
15372                mProcessesToGc.add(i+1, proc);
15373                break;
15374            }
15375        }
15376        if (!added) {
15377            mProcessesToGc.add(0, proc);
15378        }
15379    }
15380
15381    /**
15382     * Set up to ask a process to GC itself.  This will either do it
15383     * immediately, or put it on the list of processes to gc the next
15384     * time things are idle.
15385     */
15386    final void scheduleAppGcLocked(ProcessRecord app) {
15387        long now = SystemClock.uptimeMillis();
15388        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15389            return;
15390        }
15391        if (!mProcessesToGc.contains(app)) {
15392            addProcessToGcListLocked(app);
15393            scheduleAppGcsLocked();
15394        }
15395    }
15396
15397    final void checkExcessivePowerUsageLocked(boolean doKills) {
15398        updateCpuStatsNow();
15399
15400        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15401        boolean doWakeKills = doKills;
15402        boolean doCpuKills = doKills;
15403        if (mLastPowerCheckRealtime == 0) {
15404            doWakeKills = false;
15405        }
15406        if (mLastPowerCheckUptime == 0) {
15407            doCpuKills = false;
15408        }
15409        if (stats.isScreenOn()) {
15410            doWakeKills = false;
15411        }
15412        final long curRealtime = SystemClock.elapsedRealtime();
15413        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15414        final long curUptime = SystemClock.uptimeMillis();
15415        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15416        mLastPowerCheckRealtime = curRealtime;
15417        mLastPowerCheckUptime = curUptime;
15418        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15419            doWakeKills = false;
15420        }
15421        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15422            doCpuKills = false;
15423        }
15424        int i = mLruProcesses.size();
15425        while (i > 0) {
15426            i--;
15427            ProcessRecord app = mLruProcesses.get(i);
15428            if (!app.keeping) {
15429                long wtime;
15430                synchronized (stats) {
15431                    wtime = stats.getProcessWakeTime(app.info.uid,
15432                            app.pid, curRealtime);
15433                }
15434                long wtimeUsed = wtime - app.lastWakeTime;
15435                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15436                if (DEBUG_POWER) {
15437                    StringBuilder sb = new StringBuilder(128);
15438                    sb.append("Wake for ");
15439                    app.toShortString(sb);
15440                    sb.append(": over ");
15441                    TimeUtils.formatDuration(realtimeSince, sb);
15442                    sb.append(" used ");
15443                    TimeUtils.formatDuration(wtimeUsed, sb);
15444                    sb.append(" (");
15445                    sb.append((wtimeUsed*100)/realtimeSince);
15446                    sb.append("%)");
15447                    Slog.i(TAG, sb.toString());
15448                    sb.setLength(0);
15449                    sb.append("CPU for ");
15450                    app.toShortString(sb);
15451                    sb.append(": over ");
15452                    TimeUtils.formatDuration(uptimeSince, sb);
15453                    sb.append(" used ");
15454                    TimeUtils.formatDuration(cputimeUsed, sb);
15455                    sb.append(" (");
15456                    sb.append((cputimeUsed*100)/uptimeSince);
15457                    sb.append("%)");
15458                    Slog.i(TAG, sb.toString());
15459                }
15460                // If a process has held a wake lock for more
15461                // than 50% of the time during this period,
15462                // that sounds bad.  Kill!
15463                if (doWakeKills && realtimeSince > 0
15464                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15465                    synchronized (stats) {
15466                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15467                                realtimeSince, wtimeUsed);
15468                    }
15469                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15470                            + " during " + realtimeSince);
15471                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15472                } else if (doCpuKills && uptimeSince > 0
15473                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15474                    synchronized (stats) {
15475                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15476                                uptimeSince, cputimeUsed);
15477                    }
15478                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15479                            + " during " + uptimeSince);
15480                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15481                } else {
15482                    app.lastWakeTime = wtime;
15483                    app.lastCpuTime = app.curCpuTime;
15484                }
15485            }
15486        }
15487    }
15488
15489    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15490            ProcessRecord TOP_APP, boolean doingAll, long now) {
15491        boolean success = true;
15492
15493        if (app.curRawAdj != app.setRawAdj) {
15494            if (wasKeeping && !app.keeping) {
15495                // This app is no longer something we want to keep.  Note
15496                // its current wake lock time to later know to kill it if
15497                // it is not behaving well.
15498                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15499                synchronized (stats) {
15500                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15501                            app.pid, SystemClock.elapsedRealtime());
15502                }
15503                app.lastCpuTime = app.curCpuTime;
15504            }
15505
15506            app.setRawAdj = app.curRawAdj;
15507        }
15508
15509        int changes = 0;
15510
15511        if (app.curAdj != app.setAdj) {
15512            ProcessList.setOomAdj(app.pid, app.curAdj);
15513            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15514                TAG, "Set " + app.pid + " " + app.processName +
15515                " adj " + app.curAdj + ": " + app.adjType);
15516            app.setAdj = app.curAdj;
15517        }
15518
15519        if (app.setSchedGroup != app.curSchedGroup) {
15520            app.setSchedGroup = app.curSchedGroup;
15521            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15522                    "Setting process group of " + app.processName
15523                    + " to " + app.curSchedGroup);
15524            if (app.waitingToKill != null &&
15525                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15526                killUnneededProcessLocked(app, app.waitingToKill);
15527                success = false;
15528            } else {
15529                if (true) {
15530                    long oldId = Binder.clearCallingIdentity();
15531                    try {
15532                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15533                    } catch (Exception e) {
15534                        Slog.w(TAG, "Failed setting process group of " + app.pid
15535                                + " to " + app.curSchedGroup);
15536                        e.printStackTrace();
15537                    } finally {
15538                        Binder.restoreCallingIdentity(oldId);
15539                    }
15540                } else {
15541                    if (app.thread != null) {
15542                        try {
15543                            app.thread.setSchedulingGroup(app.curSchedGroup);
15544                        } catch (RemoteException e) {
15545                        }
15546                    }
15547                }
15548                Process.setSwappiness(app.pid,
15549                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15550            }
15551        }
15552        if (app.repForegroundActivities != app.foregroundActivities) {
15553            app.repForegroundActivities = app.foregroundActivities;
15554            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15555        }
15556        if (app.repProcState != app.curProcState) {
15557            app.repProcState = app.curProcState;
15558            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
15559            if (app.thread != null) {
15560                try {
15561                    if (false) {
15562                        //RuntimeException h = new RuntimeException("here");
15563                        Slog.i(TAG, "Sending new process state " + app.repProcState
15564                                + " to " + app /*, h*/);
15565                    }
15566                    app.thread.setProcessState(app.repProcState);
15567                } catch (RemoteException e) {
15568                }
15569            }
15570        }
15571        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15572                app.setProcState)) {
15573            app.lastStateTime = now;
15574            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15575                    isSleeping(), now);
15576            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15577                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15578                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15579                    + (app.nextPssTime-now) + ": " + app);
15580        } else {
15581            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15582                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15583                requestPssLocked(app, app.setProcState);
15584                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15585                        isSleeping(), now);
15586            } else if (false && DEBUG_PSS) {
15587                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15588            }
15589        }
15590        if (app.setProcState != app.curProcState) {
15591            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15592                    "Proc state change of " + app.processName
15593                    + " to " + app.curProcState);
15594            app.setProcState = app.curProcState;
15595            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15596                app.notCachedSinceIdle = false;
15597            }
15598            if (!doingAll) {
15599                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15600            } else {
15601                app.procStateChanged = true;
15602            }
15603        }
15604
15605        if (changes != 0) {
15606            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15607            int i = mPendingProcessChanges.size()-1;
15608            ProcessChangeItem item = null;
15609            while (i >= 0) {
15610                item = mPendingProcessChanges.get(i);
15611                if (item.pid == app.pid) {
15612                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15613                    break;
15614                }
15615                i--;
15616            }
15617            if (i < 0) {
15618                // No existing item in pending changes; need a new one.
15619                final int NA = mAvailProcessChanges.size();
15620                if (NA > 0) {
15621                    item = mAvailProcessChanges.remove(NA-1);
15622                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15623                } else {
15624                    item = new ProcessChangeItem();
15625                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15626                }
15627                item.changes = 0;
15628                item.pid = app.pid;
15629                item.uid = app.info.uid;
15630                if (mPendingProcessChanges.size() == 0) {
15631                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15632                            "*** Enqueueing dispatch processes changed!");
15633                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15634                }
15635                mPendingProcessChanges.add(item);
15636            }
15637            item.changes |= changes;
15638            item.processState = app.repProcState;
15639            item.foregroundActivities = app.repForegroundActivities;
15640            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
15641                    + Integer.toHexString(System.identityHashCode(item))
15642                    + " " + app.toShortString() + ": changes=" + item.changes
15643                    + " procState=" + item.processState
15644                    + " foreground=" + item.foregroundActivities
15645                    + " type=" + app.adjType + " source=" + app.adjSource
15646                    + " target=" + app.adjTarget);
15647        }
15648
15649        return success;
15650    }
15651
15652    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15653        if (proc.thread != null && proc.baseProcessTracker != null) {
15654            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15655        }
15656    }
15657
15658    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15659            ProcessRecord TOP_APP, boolean doingAll, long now) {
15660        if (app.thread == null) {
15661            return false;
15662        }
15663
15664        final boolean wasKeeping = app.keeping;
15665
15666        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15667
15668        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now);
15669    }
15670
15671    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15672            boolean oomAdj) {
15673        if (isForeground != proc.foregroundServices) {
15674            proc.foregroundServices = isForeground;
15675            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15676                    proc.info.uid);
15677            if (isForeground) {
15678                if (curProcs == null) {
15679                    curProcs = new ArrayList<ProcessRecord>();
15680                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15681                }
15682                if (!curProcs.contains(proc)) {
15683                    curProcs.add(proc);
15684                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15685                            proc.info.packageName, proc.info.uid);
15686                }
15687            } else {
15688                if (curProcs != null) {
15689                    if (curProcs.remove(proc)) {
15690                        mBatteryStatsService.noteEvent(
15691                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15692                                proc.info.packageName, proc.info.uid);
15693                        if (curProcs.size() <= 0) {
15694                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15695                        }
15696                    }
15697                }
15698            }
15699            if (oomAdj) {
15700                updateOomAdjLocked();
15701            }
15702        }
15703    }
15704
15705    private final ActivityRecord resumedAppLocked() {
15706        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15707        String pkg;
15708        int uid;
15709        if (act != null && !act.sleeping) {
15710            pkg = act.packageName;
15711            uid = act.info.applicationInfo.uid;
15712        } else {
15713            pkg = null;
15714            uid = -1;
15715        }
15716        // Has the UID or resumed package name changed?
15717        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15718                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15719            if (mCurResumedPackage != null) {
15720                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15721                        mCurResumedPackage, mCurResumedUid);
15722            }
15723            mCurResumedPackage = pkg;
15724            mCurResumedUid = uid;
15725            if (mCurResumedPackage != null) {
15726                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15727                        mCurResumedPackage, mCurResumedUid);
15728            }
15729        }
15730        return act;
15731    }
15732
15733    final boolean updateOomAdjLocked(ProcessRecord app) {
15734        final ActivityRecord TOP_ACT = resumedAppLocked();
15735        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15736        final boolean wasCached = app.cached;
15737
15738        mAdjSeq++;
15739
15740        // This is the desired cached adjusment we want to tell it to use.
15741        // If our app is currently cached, we know it, and that is it.  Otherwise,
15742        // we don't know it yet, and it needs to now be cached we will then
15743        // need to do a complete oom adj.
15744        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15745                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15746        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
15747                SystemClock.uptimeMillis());
15748        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15749            // Changed to/from cached state, so apps after it in the LRU
15750            // list may also be changed.
15751            updateOomAdjLocked();
15752        }
15753        return success;
15754    }
15755
15756    final void updateOomAdjLocked() {
15757        final ActivityRecord TOP_ACT = resumedAppLocked();
15758        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15759        final long now = SystemClock.uptimeMillis();
15760        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15761        final int N = mLruProcesses.size();
15762
15763        if (false) {
15764            RuntimeException e = new RuntimeException();
15765            e.fillInStackTrace();
15766            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15767        }
15768
15769        mAdjSeq++;
15770        mNewNumServiceProcs = 0;
15771        mNewNumAServiceProcs = 0;
15772
15773        final int emptyProcessLimit;
15774        final int cachedProcessLimit;
15775        if (mProcessLimit <= 0) {
15776            emptyProcessLimit = cachedProcessLimit = 0;
15777        } else if (mProcessLimit == 1) {
15778            emptyProcessLimit = 1;
15779            cachedProcessLimit = 0;
15780        } else {
15781            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15782            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15783        }
15784
15785        // Let's determine how many processes we have running vs.
15786        // how many slots we have for background processes; we may want
15787        // to put multiple processes in a slot of there are enough of
15788        // them.
15789        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15790                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15791        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15792        if (numEmptyProcs > cachedProcessLimit) {
15793            // If there are more empty processes than our limit on cached
15794            // processes, then use the cached process limit for the factor.
15795            // This ensures that the really old empty processes get pushed
15796            // down to the bottom, so if we are running low on memory we will
15797            // have a better chance at keeping around more cached processes
15798            // instead of a gazillion empty processes.
15799            numEmptyProcs = cachedProcessLimit;
15800        }
15801        int emptyFactor = numEmptyProcs/numSlots;
15802        if (emptyFactor < 1) emptyFactor = 1;
15803        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15804        if (cachedFactor < 1) cachedFactor = 1;
15805        int stepCached = 0;
15806        int stepEmpty = 0;
15807        int numCached = 0;
15808        int numEmpty = 0;
15809        int numTrimming = 0;
15810
15811        mNumNonCachedProcs = 0;
15812        mNumCachedHiddenProcs = 0;
15813
15814        // First update the OOM adjustment for each of the
15815        // application processes based on their current state.
15816        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15817        int nextCachedAdj = curCachedAdj+1;
15818        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15819        int nextEmptyAdj = curEmptyAdj+2;
15820        for (int i=N-1; i>=0; i--) {
15821            ProcessRecord app = mLruProcesses.get(i);
15822            if (!app.killedByAm && app.thread != null) {
15823                app.procStateChanged = false;
15824                final boolean wasKeeping = app.keeping;
15825                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15826
15827                // If we haven't yet assigned the final cached adj
15828                // to the process, do that now.
15829                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15830                    switch (app.curProcState) {
15831                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15832                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15833                            // This process is a cached process holding activities...
15834                            // assign it the next cached value for that type, and then
15835                            // step that cached level.
15836                            app.curRawAdj = curCachedAdj;
15837                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15838                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15839                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15840                                    + ")");
15841                            if (curCachedAdj != nextCachedAdj) {
15842                                stepCached++;
15843                                if (stepCached >= cachedFactor) {
15844                                    stepCached = 0;
15845                                    curCachedAdj = nextCachedAdj;
15846                                    nextCachedAdj += 2;
15847                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15848                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15849                                    }
15850                                }
15851                            }
15852                            break;
15853                        default:
15854                            // For everything else, assign next empty cached process
15855                            // level and bump that up.  Note that this means that
15856                            // long-running services that have dropped down to the
15857                            // cached level will be treated as empty (since their process
15858                            // state is still as a service), which is what we want.
15859                            app.curRawAdj = curEmptyAdj;
15860                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15861                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15862                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15863                                    + ")");
15864                            if (curEmptyAdj != nextEmptyAdj) {
15865                                stepEmpty++;
15866                                if (stepEmpty >= emptyFactor) {
15867                                    stepEmpty = 0;
15868                                    curEmptyAdj = nextEmptyAdj;
15869                                    nextEmptyAdj += 2;
15870                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15871                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15872                                    }
15873                                }
15874                            }
15875                            break;
15876                    }
15877                }
15878
15879                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now);
15880
15881                // Count the number of process types.
15882                switch (app.curProcState) {
15883                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15884                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15885                        mNumCachedHiddenProcs++;
15886                        numCached++;
15887                        if (numCached > cachedProcessLimit) {
15888                            killUnneededProcessLocked(app, "cached #" + numCached);
15889                        }
15890                        break;
15891                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15892                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15893                                && app.lastActivityTime < oldTime) {
15894                            killUnneededProcessLocked(app, "empty for "
15895                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15896                                    / 1000) + "s");
15897                        } else {
15898                            numEmpty++;
15899                            if (numEmpty > emptyProcessLimit) {
15900                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15901                            }
15902                        }
15903                        break;
15904                    default:
15905                        mNumNonCachedProcs++;
15906                        break;
15907                }
15908
15909                if (app.isolated && app.services.size() <= 0) {
15910                    // If this is an isolated process, and there are no
15911                    // services running in it, then the process is no longer
15912                    // needed.  We agressively kill these because we can by
15913                    // definition not re-use the same process again, and it is
15914                    // good to avoid having whatever code was running in them
15915                    // left sitting around after no longer needed.
15916                    killUnneededProcessLocked(app, "isolated not needed");
15917                }
15918
15919                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15920                        && !app.killedByAm) {
15921                    numTrimming++;
15922                }
15923            }
15924        }
15925
15926        mNumServiceProcs = mNewNumServiceProcs;
15927
15928        // Now determine the memory trimming level of background processes.
15929        // Unfortunately we need to start at the back of the list to do this
15930        // properly.  We only do this if the number of background apps we
15931        // are managing to keep around is less than half the maximum we desire;
15932        // if we are keeping a good number around, we'll let them use whatever
15933        // memory they want.
15934        final int numCachedAndEmpty = numCached + numEmpty;
15935        int memFactor;
15936        if (numCached <= ProcessList.TRIM_CACHED_APPS
15937                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
15938            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
15939                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
15940            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
15941                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
15942            } else {
15943                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
15944            }
15945        } else {
15946            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
15947        }
15948        // We always allow the memory level to go up (better).  We only allow it to go
15949        // down if we are in a state where that is allowed, *and* the total number of processes
15950        // has gone down since last time.
15951        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
15952                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
15953                + " last=" + mLastNumProcesses);
15954        if (memFactor > mLastMemoryLevel) {
15955            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
15956                memFactor = mLastMemoryLevel;
15957                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
15958            }
15959        }
15960        mLastMemoryLevel = memFactor;
15961        mLastNumProcesses = mLruProcesses.size();
15962        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
15963        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
15964        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
15965            if (mLowRamStartTime == 0) {
15966                mLowRamStartTime = now;
15967            }
15968            int step = 0;
15969            int fgTrimLevel;
15970            switch (memFactor) {
15971                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15972                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
15973                    break;
15974                case ProcessStats.ADJ_MEM_FACTOR_LOW:
15975                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
15976                    break;
15977                default:
15978                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
15979                    break;
15980            }
15981            int factor = numTrimming/3;
15982            int minFactor = 2;
15983            if (mHomeProcess != null) minFactor++;
15984            if (mPreviousProcess != null) minFactor++;
15985            if (factor < minFactor) factor = minFactor;
15986            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
15987            for (int i=N-1; i>=0; i--) {
15988                ProcessRecord app = mLruProcesses.get(i);
15989                if (allChanged || app.procStateChanged) {
15990                    setProcessTrackerState(app, trackerMemFactor, now);
15991                    app.procStateChanged = false;
15992                }
15993                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15994                        && !app.killedByAm) {
15995                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
15996                        try {
15997                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15998                                    "Trimming memory of " + app.processName
15999                                    + " to " + curLevel);
16000                            app.thread.scheduleTrimMemory(curLevel);
16001                        } catch (RemoteException e) {
16002                        }
16003                        if (false) {
16004                            // For now we won't do this; our memory trimming seems
16005                            // to be good enough at this point that destroying
16006                            // activities causes more harm than good.
16007                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16008                                    && app != mHomeProcess && app != mPreviousProcess) {
16009                                // Need to do this on its own message because the stack may not
16010                                // be in a consistent state at this point.
16011                                // For these apps we will also finish their activities
16012                                // to help them free memory.
16013                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16014                            }
16015                        }
16016                    }
16017                    app.trimMemoryLevel = curLevel;
16018                    step++;
16019                    if (step >= factor) {
16020                        step = 0;
16021                        switch (curLevel) {
16022                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16023                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16024                                break;
16025                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16026                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16027                                break;
16028                        }
16029                    }
16030                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16031                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16032                            && app.thread != null) {
16033                        try {
16034                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16035                                    "Trimming memory of heavy-weight " + app.processName
16036                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16037                            app.thread.scheduleTrimMemory(
16038                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16039                        } catch (RemoteException e) {
16040                        }
16041                    }
16042                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16043                } else {
16044                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16045                            || app.systemNoUi) && app.pendingUiClean) {
16046                        // If this application is now in the background and it
16047                        // had done UI, then give it the special trim level to
16048                        // have it free UI resources.
16049                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16050                        if (app.trimMemoryLevel < level && app.thread != null) {
16051                            try {
16052                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16053                                        "Trimming memory of bg-ui " + app.processName
16054                                        + " to " + level);
16055                                app.thread.scheduleTrimMemory(level);
16056                            } catch (RemoteException e) {
16057                            }
16058                        }
16059                        app.pendingUiClean = false;
16060                    }
16061                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16062                        try {
16063                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16064                                    "Trimming memory of fg " + app.processName
16065                                    + " to " + fgTrimLevel);
16066                            app.thread.scheduleTrimMemory(fgTrimLevel);
16067                        } catch (RemoteException e) {
16068                        }
16069                    }
16070                    app.trimMemoryLevel = fgTrimLevel;
16071                }
16072            }
16073        } else {
16074            if (mLowRamStartTime != 0) {
16075                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16076                mLowRamStartTime = 0;
16077            }
16078            for (int i=N-1; i>=0; i--) {
16079                ProcessRecord app = mLruProcesses.get(i);
16080                if (allChanged || app.procStateChanged) {
16081                    setProcessTrackerState(app, trackerMemFactor, now);
16082                    app.procStateChanged = false;
16083                }
16084                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16085                        || app.systemNoUi) && app.pendingUiClean) {
16086                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16087                            && app.thread != null) {
16088                        try {
16089                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16090                                    "Trimming memory of ui hidden " + app.processName
16091                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16092                            app.thread.scheduleTrimMemory(
16093                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16094                        } catch (RemoteException e) {
16095                        }
16096                    }
16097                    app.pendingUiClean = false;
16098                }
16099                app.trimMemoryLevel = 0;
16100            }
16101        }
16102
16103        if (mAlwaysFinishActivities) {
16104            // Need to do this on its own message because the stack may not
16105            // be in a consistent state at this point.
16106            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16107        }
16108
16109        if (allChanged) {
16110            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16111        }
16112
16113        if (mProcessStats.shouldWriteNowLocked(now)) {
16114            mHandler.post(new Runnable() {
16115                @Override public void run() {
16116                    synchronized (ActivityManagerService.this) {
16117                        mProcessStats.writeStateAsyncLocked();
16118                    }
16119                }
16120            });
16121        }
16122
16123        if (DEBUG_OOM_ADJ) {
16124            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16125        }
16126    }
16127
16128    final void trimApplications() {
16129        synchronized (this) {
16130            int i;
16131
16132            // First remove any unused application processes whose package
16133            // has been removed.
16134            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16135                final ProcessRecord app = mRemovedProcesses.get(i);
16136                if (app.activities.size() == 0
16137                        && app.curReceiver == null && app.services.size() == 0) {
16138                    Slog.i(
16139                        TAG, "Exiting empty application process "
16140                        + app.processName + " ("
16141                        + (app.thread != null ? app.thread.asBinder() : null)
16142                        + ")\n");
16143                    if (app.pid > 0 && app.pid != MY_PID) {
16144                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16145                                app.processName, app.setAdj, "empty");
16146                        app.killedByAm = true;
16147                        Process.killProcessQuiet(app.pid);
16148                    } else {
16149                        try {
16150                            app.thread.scheduleExit();
16151                        } catch (Exception e) {
16152                            // Ignore exceptions.
16153                        }
16154                    }
16155                    cleanUpApplicationRecordLocked(app, false, true, -1);
16156                    mRemovedProcesses.remove(i);
16157
16158                    if (app.persistent) {
16159                        if (app.persistent) {
16160                            addAppLocked(app.info, false);
16161                        }
16162                    }
16163                }
16164            }
16165
16166            // Now update the oom adj for all processes.
16167            updateOomAdjLocked();
16168        }
16169    }
16170
16171    /** This method sends the specified signal to each of the persistent apps */
16172    public void signalPersistentProcesses(int sig) throws RemoteException {
16173        if (sig != Process.SIGNAL_USR1) {
16174            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16175        }
16176
16177        synchronized (this) {
16178            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16179                    != PackageManager.PERMISSION_GRANTED) {
16180                throw new SecurityException("Requires permission "
16181                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16182            }
16183
16184            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16185                ProcessRecord r = mLruProcesses.get(i);
16186                if (r.thread != null && r.persistent) {
16187                    Process.sendSignal(r.pid, sig);
16188                }
16189            }
16190        }
16191    }
16192
16193    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16194        if (proc == null || proc == mProfileProc) {
16195            proc = mProfileProc;
16196            path = mProfileFile;
16197            profileType = mProfileType;
16198            clearProfilerLocked();
16199        }
16200        if (proc == null) {
16201            return;
16202        }
16203        try {
16204            proc.thread.profilerControl(false, path, null, profileType);
16205        } catch (RemoteException e) {
16206            throw new IllegalStateException("Process disappeared");
16207        }
16208    }
16209
16210    private void clearProfilerLocked() {
16211        if (mProfileFd != null) {
16212            try {
16213                mProfileFd.close();
16214            } catch (IOException e) {
16215            }
16216        }
16217        mProfileApp = null;
16218        mProfileProc = null;
16219        mProfileFile = null;
16220        mProfileType = 0;
16221        mAutoStopProfiler = false;
16222    }
16223
16224    public boolean profileControl(String process, int userId, boolean start,
16225            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16226
16227        try {
16228            synchronized (this) {
16229                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16230                // its own permission.
16231                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16232                        != PackageManager.PERMISSION_GRANTED) {
16233                    throw new SecurityException("Requires permission "
16234                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16235                }
16236
16237                if (start && fd == null) {
16238                    throw new IllegalArgumentException("null fd");
16239                }
16240
16241                ProcessRecord proc = null;
16242                if (process != null) {
16243                    proc = findProcessLocked(process, userId, "profileControl");
16244                }
16245
16246                if (start && (proc == null || proc.thread == null)) {
16247                    throw new IllegalArgumentException("Unknown process: " + process);
16248                }
16249
16250                if (start) {
16251                    stopProfilerLocked(null, null, 0);
16252                    setProfileApp(proc.info, proc.processName, path, fd, false);
16253                    mProfileProc = proc;
16254                    mProfileType = profileType;
16255                    try {
16256                        fd = fd.dup();
16257                    } catch (IOException e) {
16258                        fd = null;
16259                    }
16260                    proc.thread.profilerControl(start, path, fd, profileType);
16261                    fd = null;
16262                    mProfileFd = null;
16263                } else {
16264                    stopProfilerLocked(proc, path, profileType);
16265                    if (fd != null) {
16266                        try {
16267                            fd.close();
16268                        } catch (IOException e) {
16269                        }
16270                    }
16271                }
16272
16273                return true;
16274            }
16275        } catch (RemoteException e) {
16276            throw new IllegalStateException("Process disappeared");
16277        } finally {
16278            if (fd != null) {
16279                try {
16280                    fd.close();
16281                } catch (IOException e) {
16282                }
16283            }
16284        }
16285    }
16286
16287    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16288        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16289                userId, true, true, callName, null);
16290        ProcessRecord proc = null;
16291        try {
16292            int pid = Integer.parseInt(process);
16293            synchronized (mPidsSelfLocked) {
16294                proc = mPidsSelfLocked.get(pid);
16295            }
16296        } catch (NumberFormatException e) {
16297        }
16298
16299        if (proc == null) {
16300            ArrayMap<String, SparseArray<ProcessRecord>> all
16301                    = mProcessNames.getMap();
16302            SparseArray<ProcessRecord> procs = all.get(process);
16303            if (procs != null && procs.size() > 0) {
16304                proc = procs.valueAt(0);
16305                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16306                    for (int i=1; i<procs.size(); i++) {
16307                        ProcessRecord thisProc = procs.valueAt(i);
16308                        if (thisProc.userId == userId) {
16309                            proc = thisProc;
16310                            break;
16311                        }
16312                    }
16313                }
16314            }
16315        }
16316
16317        return proc;
16318    }
16319
16320    public boolean dumpHeap(String process, int userId, boolean managed,
16321            String path, ParcelFileDescriptor fd) throws RemoteException {
16322
16323        try {
16324            synchronized (this) {
16325                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16326                // its own permission (same as profileControl).
16327                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16328                        != PackageManager.PERMISSION_GRANTED) {
16329                    throw new SecurityException("Requires permission "
16330                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16331                }
16332
16333                if (fd == null) {
16334                    throw new IllegalArgumentException("null fd");
16335                }
16336
16337                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16338                if (proc == null || proc.thread == null) {
16339                    throw new IllegalArgumentException("Unknown process: " + process);
16340                }
16341
16342                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16343                if (!isDebuggable) {
16344                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16345                        throw new SecurityException("Process not debuggable: " + proc);
16346                    }
16347                }
16348
16349                proc.thread.dumpHeap(managed, path, fd);
16350                fd = null;
16351                return true;
16352            }
16353        } catch (RemoteException e) {
16354            throw new IllegalStateException("Process disappeared");
16355        } finally {
16356            if (fd != null) {
16357                try {
16358                    fd.close();
16359                } catch (IOException e) {
16360                }
16361            }
16362        }
16363    }
16364
16365    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16366    public void monitor() {
16367        synchronized (this) { }
16368    }
16369
16370    void onCoreSettingsChange(Bundle settings) {
16371        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16372            ProcessRecord processRecord = mLruProcesses.get(i);
16373            try {
16374                if (processRecord.thread != null) {
16375                    processRecord.thread.setCoreSettings(settings);
16376                }
16377            } catch (RemoteException re) {
16378                /* ignore */
16379            }
16380        }
16381    }
16382
16383    // Multi-user methods
16384
16385    /**
16386     * Start user, if its not already running, but don't bring it to foreground.
16387     */
16388    @Override
16389    public boolean startUserInBackground(final int userId) {
16390        return startUser(userId, /* foreground */ false);
16391    }
16392
16393    /**
16394     * Refreshes the list of users related to the current user when either a
16395     * user switch happens or when a new related user is started in the
16396     * background.
16397     */
16398    private void updateCurrentProfileIdsLocked() {
16399        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16400                mCurrentUserId, false /* enabledOnly */);
16401        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16402        for (int i = 0; i < currentProfileIds.length; i++) {
16403            currentProfileIds[i] = profiles.get(i).id;
16404        }
16405        mCurrentProfileIds = currentProfileIds;
16406    }
16407
16408    private Set getProfileIdsLocked(int userId) {
16409        Set userIds = new HashSet<Integer>();
16410        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16411                userId, false /* enabledOnly */);
16412        for (UserInfo user : profiles) {
16413            userIds.add(Integer.valueOf(user.id));
16414        }
16415        return userIds;
16416    }
16417
16418    @Override
16419    public boolean switchUser(final int userId) {
16420        return startUser(userId, /* foregound */ true);
16421    }
16422
16423    private boolean startUser(final int userId, boolean foreground) {
16424        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16425                != PackageManager.PERMISSION_GRANTED) {
16426            String msg = "Permission Denial: switchUser() from pid="
16427                    + Binder.getCallingPid()
16428                    + ", uid=" + Binder.getCallingUid()
16429                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16430            Slog.w(TAG, msg);
16431            throw new SecurityException(msg);
16432        }
16433
16434        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16435
16436        final long ident = Binder.clearCallingIdentity();
16437        try {
16438            synchronized (this) {
16439                final int oldUserId = mCurrentUserId;
16440                if (oldUserId == userId) {
16441                    return true;
16442                }
16443
16444                mStackSupervisor.setLockTaskModeLocked(null);
16445
16446                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16447                if (userInfo == null) {
16448                    Slog.w(TAG, "No user info for user #" + userId);
16449                    return false;
16450                }
16451
16452                if (foreground) {
16453                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16454                            R.anim.screen_user_enter);
16455                }
16456
16457                boolean needStart = false;
16458
16459                // If the user we are switching to is not currently started, then
16460                // we need to start it now.
16461                if (mStartedUsers.get(userId) == null) {
16462                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16463                    updateStartedUserArrayLocked();
16464                    needStart = true;
16465                }
16466
16467                final Integer userIdInt = Integer.valueOf(userId);
16468                mUserLru.remove(userIdInt);
16469                mUserLru.add(userIdInt);
16470
16471                if (foreground) {
16472                    mCurrentUserId = userId;
16473                    updateCurrentProfileIdsLocked();
16474                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16475                    // Once the internal notion of the active user has switched, we lock the device
16476                    // with the option to show the user switcher on the keyguard.
16477                    mWindowManager.lockNow(null);
16478                } else {
16479                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16480                    updateCurrentProfileIdsLocked();
16481                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16482                    mUserLru.remove(currentUserIdInt);
16483                    mUserLru.add(currentUserIdInt);
16484                }
16485
16486                final UserStartedState uss = mStartedUsers.get(userId);
16487
16488                // Make sure user is in the started state.  If it is currently
16489                // stopping, we need to knock that off.
16490                if (uss.mState == UserStartedState.STATE_STOPPING) {
16491                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16492                    // so we can just fairly silently bring the user back from
16493                    // the almost-dead.
16494                    uss.mState = UserStartedState.STATE_RUNNING;
16495                    updateStartedUserArrayLocked();
16496                    needStart = true;
16497                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16498                    // This means ACTION_SHUTDOWN has been sent, so we will
16499                    // need to treat this as a new boot of the user.
16500                    uss.mState = UserStartedState.STATE_BOOTING;
16501                    updateStartedUserArrayLocked();
16502                    needStart = true;
16503                }
16504
16505                if (uss.mState == UserStartedState.STATE_BOOTING) {
16506                    // Booting up a new user, need to tell system services about it.
16507                    // Note that this is on the same handler as scheduling of broadcasts,
16508                    // which is important because it needs to go first.
16509                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
16510                }
16511
16512                if (foreground) {
16513                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId));
16514                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16515                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16516                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16517                            oldUserId, userId, uss));
16518                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16519                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16520                }
16521
16522                if (needStart) {
16523                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16524                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16525                            | Intent.FLAG_RECEIVER_FOREGROUND);
16526                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16527                    broadcastIntentLocked(null, null, intent,
16528                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16529                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16530                }
16531
16532                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16533                    if (userId != UserHandle.USER_OWNER) {
16534                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16535                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16536                        broadcastIntentLocked(null, null, intent, null,
16537                                new IIntentReceiver.Stub() {
16538                                    public void performReceive(Intent intent, int resultCode,
16539                                            String data, Bundle extras, boolean ordered,
16540                                            boolean sticky, int sendingUser) {
16541                                        userInitialized(uss, userId);
16542                                    }
16543                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16544                                true, false, MY_PID, Process.SYSTEM_UID,
16545                                userId);
16546                        uss.initializing = true;
16547                    } else {
16548                        getUserManagerLocked().makeInitialized(userInfo.id);
16549                    }
16550                }
16551
16552                if (foreground) {
16553                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16554                    if (homeInFront) {
16555                        startHomeActivityLocked(userId);
16556                    } else {
16557                        mStackSupervisor.resumeTopActivitiesLocked();
16558                    }
16559                    EventLogTags.writeAmSwitchUser(userId);
16560                    getUserManagerLocked().userForeground(userId);
16561                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16562                } else {
16563                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
16564                }
16565
16566                if (needStart) {
16567                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16568                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16569                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16570                    broadcastIntentLocked(null, null, intent,
16571                            null, new IIntentReceiver.Stub() {
16572                                @Override
16573                                public void performReceive(Intent intent, int resultCode, String data,
16574                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16575                                        throws RemoteException {
16576                                }
16577                            }, 0, null, null,
16578                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16579                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16580                }
16581            }
16582        } finally {
16583            Binder.restoreCallingIdentity(ident);
16584        }
16585
16586        return true;
16587    }
16588
16589    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16590        long ident = Binder.clearCallingIdentity();
16591        try {
16592            Intent intent;
16593            if (oldUserId >= 0) {
16594                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16595                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16596                        | Intent.FLAG_RECEIVER_FOREGROUND);
16597                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16598                broadcastIntentLocked(null, null, intent,
16599                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16600                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16601            }
16602            if (newUserId >= 0) {
16603                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16604                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16605                        | Intent.FLAG_RECEIVER_FOREGROUND);
16606                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16607                broadcastIntentLocked(null, null, intent,
16608                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16609                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16610                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16611                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16612                        | Intent.FLAG_RECEIVER_FOREGROUND);
16613                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16614                broadcastIntentLocked(null, null, intent,
16615                        null, null, 0, null, null,
16616                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16617                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16618            }
16619        } finally {
16620            Binder.restoreCallingIdentity(ident);
16621        }
16622    }
16623
16624    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16625            final int newUserId) {
16626        final int N = mUserSwitchObservers.beginBroadcast();
16627        if (N > 0) {
16628            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16629                int mCount = 0;
16630                @Override
16631                public void sendResult(Bundle data) throws RemoteException {
16632                    synchronized (ActivityManagerService.this) {
16633                        if (mCurUserSwitchCallback == this) {
16634                            mCount++;
16635                            if (mCount == N) {
16636                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16637                            }
16638                        }
16639                    }
16640                }
16641            };
16642            synchronized (this) {
16643                uss.switching = true;
16644                mCurUserSwitchCallback = callback;
16645            }
16646            for (int i=0; i<N; i++) {
16647                try {
16648                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16649                            newUserId, callback);
16650                } catch (RemoteException e) {
16651                }
16652            }
16653        } else {
16654            synchronized (this) {
16655                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16656            }
16657        }
16658        mUserSwitchObservers.finishBroadcast();
16659    }
16660
16661    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16662        synchronized (this) {
16663            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16664            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16665        }
16666    }
16667
16668    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16669        mCurUserSwitchCallback = null;
16670        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16671        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16672                oldUserId, newUserId, uss));
16673    }
16674
16675    void userInitialized(UserStartedState uss, int newUserId) {
16676        completeSwitchAndInitalize(uss, newUserId, true, false);
16677    }
16678
16679    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16680        completeSwitchAndInitalize(uss, newUserId, false, true);
16681    }
16682
16683    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16684            boolean clearInitializing, boolean clearSwitching) {
16685        boolean unfrozen = false;
16686        synchronized (this) {
16687            if (clearInitializing) {
16688                uss.initializing = false;
16689                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16690            }
16691            if (clearSwitching) {
16692                uss.switching = false;
16693            }
16694            if (!uss.switching && !uss.initializing) {
16695                mWindowManager.stopFreezingScreen();
16696                unfrozen = true;
16697            }
16698        }
16699        if (unfrozen) {
16700            final int N = mUserSwitchObservers.beginBroadcast();
16701            for (int i=0; i<N; i++) {
16702                try {
16703                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16704                } catch (RemoteException e) {
16705                }
16706            }
16707            mUserSwitchObservers.finishBroadcast();
16708        }
16709    }
16710
16711    void scheduleStartProfilesLocked() {
16712        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
16713            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
16714                    DateUtils.SECOND_IN_MILLIS);
16715        }
16716    }
16717
16718    void startProfilesLocked() {
16719        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
16720        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16721                mCurrentUserId, false /* enabledOnly */);
16722        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
16723        for (UserInfo user : profiles) {
16724            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
16725                    && user.id != mCurrentUserId) {
16726                toStart.add(user);
16727            }
16728        }
16729        final int n = toStart.size();
16730        int i = 0;
16731        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
16732            startUserInBackground(toStart.get(i).id);
16733        }
16734        if (i < n) {
16735            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
16736        }
16737    }
16738
16739    void finishUserBoot(UserStartedState uss) {
16740        synchronized (this) {
16741            if (uss.mState == UserStartedState.STATE_BOOTING
16742                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16743                uss.mState = UserStartedState.STATE_RUNNING;
16744                final int userId = uss.mHandle.getIdentifier();
16745                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16746                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16747                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16748                broadcastIntentLocked(null, null, intent,
16749                        null, null, 0, null, null,
16750                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16751                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16752            }
16753        }
16754    }
16755
16756    void finishUserSwitch(UserStartedState uss) {
16757        synchronized (this) {
16758            finishUserBoot(uss);
16759
16760            startProfilesLocked();
16761
16762            int num = mUserLru.size();
16763            int i = 0;
16764            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16765                Integer oldUserId = mUserLru.get(i);
16766                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16767                if (oldUss == null) {
16768                    // Shouldn't happen, but be sane if it does.
16769                    mUserLru.remove(i);
16770                    num--;
16771                    continue;
16772                }
16773                if (oldUss.mState == UserStartedState.STATE_STOPPING
16774                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16775                    // This user is already stopping, doesn't count.
16776                    num--;
16777                    i++;
16778                    continue;
16779                }
16780                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16781                    // Owner and current can't be stopped, but count as running.
16782                    i++;
16783                    continue;
16784                }
16785                // This is a user to be stopped.
16786                stopUserLocked(oldUserId, null);
16787                num--;
16788                i++;
16789            }
16790        }
16791    }
16792
16793    @Override
16794    public int stopUser(final int userId, final IStopUserCallback callback) {
16795        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16796                != PackageManager.PERMISSION_GRANTED) {
16797            String msg = "Permission Denial: switchUser() from pid="
16798                    + Binder.getCallingPid()
16799                    + ", uid=" + Binder.getCallingUid()
16800                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16801            Slog.w(TAG, msg);
16802            throw new SecurityException(msg);
16803        }
16804        if (userId <= 0) {
16805            throw new IllegalArgumentException("Can't stop primary user " + userId);
16806        }
16807        synchronized (this) {
16808            return stopUserLocked(userId, callback);
16809        }
16810    }
16811
16812    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16813        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
16814        if (mCurrentUserId == userId) {
16815            return ActivityManager.USER_OP_IS_CURRENT;
16816        }
16817
16818        final UserStartedState uss = mStartedUsers.get(userId);
16819        if (uss == null) {
16820            // User is not started, nothing to do...  but we do need to
16821            // callback if requested.
16822            if (callback != null) {
16823                mHandler.post(new Runnable() {
16824                    @Override
16825                    public void run() {
16826                        try {
16827                            callback.userStopped(userId);
16828                        } catch (RemoteException e) {
16829                        }
16830                    }
16831                });
16832            }
16833            return ActivityManager.USER_OP_SUCCESS;
16834        }
16835
16836        if (callback != null) {
16837            uss.mStopCallbacks.add(callback);
16838        }
16839
16840        if (uss.mState != UserStartedState.STATE_STOPPING
16841                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16842            uss.mState = UserStartedState.STATE_STOPPING;
16843            updateStartedUserArrayLocked();
16844
16845            long ident = Binder.clearCallingIdentity();
16846            try {
16847                // We are going to broadcast ACTION_USER_STOPPING and then
16848                // once that is done send a final ACTION_SHUTDOWN and then
16849                // stop the user.
16850                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16851                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16852                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16853                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16854                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16855                // This is the result receiver for the final shutdown broadcast.
16856                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16857                    @Override
16858                    public void performReceive(Intent intent, int resultCode, String data,
16859                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16860                        finishUserStop(uss);
16861                    }
16862                };
16863                // This is the result receiver for the initial stopping broadcast.
16864                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16865                    @Override
16866                    public void performReceive(Intent intent, int resultCode, String data,
16867                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16868                        // On to the next.
16869                        synchronized (ActivityManagerService.this) {
16870                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16871                                // Whoops, we are being started back up.  Abort, abort!
16872                                return;
16873                            }
16874                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16875                        }
16876                        mSystemServiceManager.stopUser(userId);
16877                        broadcastIntentLocked(null, null, shutdownIntent,
16878                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16879                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16880                    }
16881                };
16882                // Kick things off.
16883                broadcastIntentLocked(null, null, stoppingIntent,
16884                        null, stoppingReceiver, 0, null, null,
16885                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16886                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16887            } finally {
16888                Binder.restoreCallingIdentity(ident);
16889            }
16890        }
16891
16892        return ActivityManager.USER_OP_SUCCESS;
16893    }
16894
16895    void finishUserStop(UserStartedState uss) {
16896        final int userId = uss.mHandle.getIdentifier();
16897        boolean stopped;
16898        ArrayList<IStopUserCallback> callbacks;
16899        synchronized (this) {
16900            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16901            if (mStartedUsers.get(userId) != uss) {
16902                stopped = false;
16903            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16904                stopped = false;
16905            } else {
16906                stopped = true;
16907                // User can no longer run.
16908                mStartedUsers.remove(userId);
16909                mUserLru.remove(Integer.valueOf(userId));
16910                updateStartedUserArrayLocked();
16911
16912                // Clean up all state and processes associated with the user.
16913                // Kill all the processes for the user.
16914                forceStopUserLocked(userId, "finish user");
16915            }
16916        }
16917
16918        for (int i=0; i<callbacks.size(); i++) {
16919            try {
16920                if (stopped) callbacks.get(i).userStopped(userId);
16921                else callbacks.get(i).userStopAborted(userId);
16922            } catch (RemoteException e) {
16923            }
16924        }
16925
16926        if (stopped) {
16927            mSystemServiceManager.cleanupUser(userId);
16928            synchronized (this) {
16929                mStackSupervisor.removeUserLocked(userId);
16930            }
16931        }
16932    }
16933
16934    @Override
16935    public UserInfo getCurrentUser() {
16936        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16937                != PackageManager.PERMISSION_GRANTED) && (
16938                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16939                != PackageManager.PERMISSION_GRANTED)) {
16940            String msg = "Permission Denial: getCurrentUser() from pid="
16941                    + Binder.getCallingPid()
16942                    + ", uid=" + Binder.getCallingUid()
16943                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16944            Slog.w(TAG, msg);
16945            throw new SecurityException(msg);
16946        }
16947        synchronized (this) {
16948            return getUserManagerLocked().getUserInfo(mCurrentUserId);
16949        }
16950    }
16951
16952    int getCurrentUserIdLocked() {
16953        return mCurrentUserId;
16954    }
16955
16956    @Override
16957    public boolean isUserRunning(int userId, boolean orStopped) {
16958        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16959                != PackageManager.PERMISSION_GRANTED) {
16960            String msg = "Permission Denial: isUserRunning() from pid="
16961                    + Binder.getCallingPid()
16962                    + ", uid=" + Binder.getCallingUid()
16963                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16964            Slog.w(TAG, msg);
16965            throw new SecurityException(msg);
16966        }
16967        synchronized (this) {
16968            return isUserRunningLocked(userId, orStopped);
16969        }
16970    }
16971
16972    boolean isUserRunningLocked(int userId, boolean orStopped) {
16973        UserStartedState state = mStartedUsers.get(userId);
16974        if (state == null) {
16975            return false;
16976        }
16977        if (orStopped) {
16978            return true;
16979        }
16980        return state.mState != UserStartedState.STATE_STOPPING
16981                && state.mState != UserStartedState.STATE_SHUTDOWN;
16982    }
16983
16984    @Override
16985    public int[] getRunningUserIds() {
16986        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16987                != PackageManager.PERMISSION_GRANTED) {
16988            String msg = "Permission Denial: isUserRunning() from pid="
16989                    + Binder.getCallingPid()
16990                    + ", uid=" + Binder.getCallingUid()
16991                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16992            Slog.w(TAG, msg);
16993            throw new SecurityException(msg);
16994        }
16995        synchronized (this) {
16996            return mStartedUserArray;
16997        }
16998    }
16999
17000    private void updateStartedUserArrayLocked() {
17001        int num = 0;
17002        for (int i=0; i<mStartedUsers.size();  i++) {
17003            UserStartedState uss = mStartedUsers.valueAt(i);
17004            // This list does not include stopping users.
17005            if (uss.mState != UserStartedState.STATE_STOPPING
17006                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17007                num++;
17008            }
17009        }
17010        mStartedUserArray = new int[num];
17011        num = 0;
17012        for (int i=0; i<mStartedUsers.size();  i++) {
17013            UserStartedState uss = mStartedUsers.valueAt(i);
17014            if (uss.mState != UserStartedState.STATE_STOPPING
17015                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17016                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17017                num++;
17018            }
17019        }
17020    }
17021
17022    @Override
17023    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17024        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
17025                != PackageManager.PERMISSION_GRANTED) {
17026            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17027                    + Binder.getCallingPid()
17028                    + ", uid=" + Binder.getCallingUid()
17029                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
17030            Slog.w(TAG, msg);
17031            throw new SecurityException(msg);
17032        }
17033
17034        mUserSwitchObservers.register(observer);
17035    }
17036
17037    @Override
17038    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17039        mUserSwitchObservers.unregister(observer);
17040    }
17041
17042    private boolean userExists(int userId) {
17043        if (userId == 0) {
17044            return true;
17045        }
17046        UserManagerService ums = getUserManagerLocked();
17047        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17048    }
17049
17050    int[] getUsersLocked() {
17051        UserManagerService ums = getUserManagerLocked();
17052        return ums != null ? ums.getUserIds() : new int[] { 0 };
17053    }
17054
17055    UserManagerService getUserManagerLocked() {
17056        if (mUserManager == null) {
17057            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17058            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17059        }
17060        return mUserManager;
17061    }
17062
17063    private int applyUserId(int uid, int userId) {
17064        return UserHandle.getUid(userId, uid);
17065    }
17066
17067    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17068        if (info == null) return null;
17069        ApplicationInfo newInfo = new ApplicationInfo(info);
17070        newInfo.uid = applyUserId(info.uid, userId);
17071        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17072                + info.packageName;
17073        return newInfo;
17074    }
17075
17076    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17077        if (aInfo == null
17078                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17079            return aInfo;
17080        }
17081
17082        ActivityInfo info = new ActivityInfo(aInfo);
17083        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17084        return info;
17085    }
17086
17087    private final class LocalService extends ActivityManagerInternal {
17088        @Override
17089        public void goingToSleep() {
17090            ActivityManagerService.this.goingToSleep();
17091        }
17092
17093        @Override
17094        public void wakingUp() {
17095            ActivityManagerService.this.wakingUp();
17096        }
17097    }
17098}
17099