ActivityManagerService.java revision 34f6084bc21b07ae9112be6e7a8f50c49828ac9c
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                String pacFileUrl = "";
1332                if (proxy != null) {
1333                    host = proxy.getHost();
1334                    port = Integer.toString(proxy.getPort());
1335                    exclList = proxy.getExclusionListAsString();
1336                    if (proxy.getPacFileUrl() != null) {
1337                        pacFileUrl = proxy.getPacFileUrl().toString();
1338                    }
1339                }
1340                synchronized (ActivityManagerService.this) {
1341                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1342                        ProcessRecord r = mLruProcesses.get(i);
1343                        if (r.thread != null) {
1344                            try {
1345                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1346                            } catch (RemoteException ex) {
1347                                Slog.w(TAG, "Failed to update http proxy for: " +
1348                                        r.info.processName);
1349                            }
1350                        }
1351                    }
1352                }
1353            } break;
1354            case SHOW_UID_ERROR_MSG: {
1355                String title = "System UIDs Inconsistent";
1356                String text = "UIDs on the system are inconsistent, you need to wipe your"
1357                        + " data partition or your device will be unstable.";
1358                Log.e(TAG, title + ": " + text);
1359                if (mShowDialogs) {
1360                    // XXX This is a temporary dialog, no need to localize.
1361                    AlertDialog d = new BaseErrorDialog(mContext);
1362                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1363                    d.setCancelable(false);
1364                    d.setTitle(title);
1365                    d.setMessage(text);
1366                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1367                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1368                    mUidAlert = d;
1369                    d.show();
1370                }
1371            } break;
1372            case IM_FEELING_LUCKY_MSG: {
1373                if (mUidAlert != null) {
1374                    mUidAlert.dismiss();
1375                    mUidAlert = null;
1376                }
1377            } break;
1378            case PROC_START_TIMEOUT_MSG: {
1379                if (mDidDexOpt) {
1380                    mDidDexOpt = false;
1381                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1382                    nmsg.obj = msg.obj;
1383                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1384                    return;
1385                }
1386                ProcessRecord app = (ProcessRecord)msg.obj;
1387                synchronized (ActivityManagerService.this) {
1388                    processStartTimedOutLocked(app);
1389                }
1390            } break;
1391            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1392                synchronized (ActivityManagerService.this) {
1393                    doPendingActivityLaunchesLocked(true);
1394                }
1395            } break;
1396            case KILL_APPLICATION_MSG: {
1397                synchronized (ActivityManagerService.this) {
1398                    int appid = msg.arg1;
1399                    boolean restart = (msg.arg2 == 1);
1400                    Bundle bundle = (Bundle)msg.obj;
1401                    String pkg = bundle.getString("pkg");
1402                    String reason = bundle.getString("reason");
1403                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1404                            false, UserHandle.USER_ALL, reason);
1405                }
1406            } break;
1407            case FINALIZE_PENDING_INTENT_MSG: {
1408                ((PendingIntentRecord)msg.obj).completeFinalize();
1409            } break;
1410            case POST_HEAVY_NOTIFICATION_MSG: {
1411                INotificationManager inm = NotificationManager.getService();
1412                if (inm == null) {
1413                    return;
1414                }
1415
1416                ActivityRecord root = (ActivityRecord)msg.obj;
1417                ProcessRecord process = root.app;
1418                if (process == null) {
1419                    return;
1420                }
1421
1422                try {
1423                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1424                    String text = mContext.getString(R.string.heavy_weight_notification,
1425                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1426                    Notification notification = new Notification();
1427                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1428                    notification.when = 0;
1429                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1430                    notification.tickerText = text;
1431                    notification.defaults = 0; // please be quiet
1432                    notification.sound = null;
1433                    notification.vibrate = null;
1434                    notification.setLatestEventInfo(context, text,
1435                            mContext.getText(R.string.heavy_weight_notification_detail),
1436                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1437                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1438                                    new UserHandle(root.userId)));
1439
1440                    try {
1441                        int[] outId = new int[1];
1442                        inm.enqueueNotificationWithTag("android", "android", null,
1443                                R.string.heavy_weight_notification,
1444                                notification, outId, root.userId);
1445                    } catch (RuntimeException e) {
1446                        Slog.w(ActivityManagerService.TAG,
1447                                "Error showing notification for heavy-weight app", e);
1448                    } catch (RemoteException e) {
1449                    }
1450                } catch (NameNotFoundException e) {
1451                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1452                }
1453            } break;
1454            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1455                INotificationManager inm = NotificationManager.getService();
1456                if (inm == null) {
1457                    return;
1458                }
1459                try {
1460                    inm.cancelNotificationWithTag("android", null,
1461                            R.string.heavy_weight_notification,  msg.arg1);
1462                } catch (RuntimeException e) {
1463                    Slog.w(ActivityManagerService.TAG,
1464                            "Error canceling notification for service", e);
1465                } catch (RemoteException e) {
1466                }
1467            } break;
1468            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1469                synchronized (ActivityManagerService.this) {
1470                    checkExcessivePowerUsageLocked(true);
1471                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1472                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1473                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1474                }
1475            } break;
1476            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1477                synchronized (ActivityManagerService.this) {
1478                    ActivityRecord ar = (ActivityRecord)msg.obj;
1479                    if (mCompatModeDialog != null) {
1480                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1481                                ar.info.applicationInfo.packageName)) {
1482                            return;
1483                        }
1484                        mCompatModeDialog.dismiss();
1485                        mCompatModeDialog = null;
1486                    }
1487                    if (ar != null && false) {
1488                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1489                                ar.packageName)) {
1490                            int mode = mCompatModePackages.computeCompatModeLocked(
1491                                    ar.info.applicationInfo);
1492                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1493                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1494                                mCompatModeDialog = new CompatModeDialog(
1495                                        ActivityManagerService.this, mContext,
1496                                        ar.info.applicationInfo);
1497                                mCompatModeDialog.show();
1498                            }
1499                        }
1500                    }
1501                }
1502                break;
1503            }
1504            case DISPATCH_PROCESSES_CHANGED: {
1505                dispatchProcessesChanged();
1506                break;
1507            }
1508            case DISPATCH_PROCESS_DIED: {
1509                final int pid = msg.arg1;
1510                final int uid = msg.arg2;
1511                dispatchProcessDied(pid, uid);
1512                break;
1513            }
1514            case REPORT_MEM_USAGE_MSG: {
1515                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1516                Thread thread = new Thread() {
1517                    @Override public void run() {
1518                        final SparseArray<ProcessMemInfo> infoMap
1519                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1520                        for (int i=0, N=memInfos.size(); i<N; i++) {
1521                            ProcessMemInfo mi = memInfos.get(i);
1522                            infoMap.put(mi.pid, mi);
1523                        }
1524                        updateCpuStatsNow();
1525                        synchronized (mProcessCpuThread) {
1526                            final int N = mProcessCpuTracker.countStats();
1527                            for (int i=0; i<N; i++) {
1528                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1529                                if (st.vsize > 0) {
1530                                    long pss = Debug.getPss(st.pid, null);
1531                                    if (pss > 0) {
1532                                        if (infoMap.indexOfKey(st.pid) < 0) {
1533                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1534                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1535                                            mi.pss = pss;
1536                                            memInfos.add(mi);
1537                                        }
1538                                    }
1539                                }
1540                            }
1541                        }
1542
1543                        long totalPss = 0;
1544                        for (int i=0, N=memInfos.size(); i<N; i++) {
1545                            ProcessMemInfo mi = memInfos.get(i);
1546                            if (mi.pss == 0) {
1547                                mi.pss = Debug.getPss(mi.pid, null);
1548                            }
1549                            totalPss += mi.pss;
1550                        }
1551                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1552                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1553                                if (lhs.oomAdj != rhs.oomAdj) {
1554                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1555                                }
1556                                if (lhs.pss != rhs.pss) {
1557                                    return lhs.pss < rhs.pss ? 1 : -1;
1558                                }
1559                                return 0;
1560                            }
1561                        });
1562
1563                        StringBuilder tag = new StringBuilder(128);
1564                        StringBuilder stack = new StringBuilder(128);
1565                        tag.append("Low on memory -- ");
1566                        appendMemBucket(tag, totalPss, "total", false);
1567                        appendMemBucket(stack, totalPss, "total", true);
1568
1569                        StringBuilder logBuilder = new StringBuilder(1024);
1570                        logBuilder.append("Low on memory:\n");
1571
1572                        boolean firstLine = true;
1573                        int lastOomAdj = Integer.MIN_VALUE;
1574                        for (int i=0, N=memInfos.size(); i<N; i++) {
1575                            ProcessMemInfo mi = memInfos.get(i);
1576
1577                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1578                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1579                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1580                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1581                                if (lastOomAdj != mi.oomAdj) {
1582                                    lastOomAdj = mi.oomAdj;
1583                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1584                                        tag.append(" / ");
1585                                    }
1586                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1587                                        if (firstLine) {
1588                                            stack.append(":");
1589                                            firstLine = false;
1590                                        }
1591                                        stack.append("\n\t at ");
1592                                    } else {
1593                                        stack.append("$");
1594                                    }
1595                                } else {
1596                                    tag.append(" ");
1597                                    stack.append("$");
1598                                }
1599                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1600                                    appendMemBucket(tag, mi.pss, mi.name, false);
1601                                }
1602                                appendMemBucket(stack, mi.pss, mi.name, true);
1603                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1604                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1605                                    stack.append("(");
1606                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1607                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1608                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1609                                            stack.append(":");
1610                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1611                                        }
1612                                    }
1613                                    stack.append(")");
1614                                }
1615                            }
1616
1617                            logBuilder.append("  ");
1618                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1619                            logBuilder.append(' ');
1620                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1621                            logBuilder.append(' ');
1622                            ProcessList.appendRamKb(logBuilder, mi.pss);
1623                            logBuilder.append(" kB: ");
1624                            logBuilder.append(mi.name);
1625                            logBuilder.append(" (");
1626                            logBuilder.append(mi.pid);
1627                            logBuilder.append(") ");
1628                            logBuilder.append(mi.adjType);
1629                            logBuilder.append('\n');
1630                            if (mi.adjReason != null) {
1631                                logBuilder.append("                      ");
1632                                logBuilder.append(mi.adjReason);
1633                                logBuilder.append('\n');
1634                            }
1635                        }
1636
1637                        logBuilder.append("           ");
1638                        ProcessList.appendRamKb(logBuilder, totalPss);
1639                        logBuilder.append(" kB: TOTAL\n");
1640
1641                        long[] infos = new long[Debug.MEMINFO_COUNT];
1642                        Debug.getMemInfo(infos);
1643                        logBuilder.append("  MemInfo: ");
1644                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1645                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1646                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1647                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1648                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1649                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1650                            logBuilder.append("  ZRAM: ");
1651                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1652                            logBuilder.append(" kB RAM, ");
1653                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1654                            logBuilder.append(" kB swap total, ");
1655                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1656                            logBuilder.append(" kB swap free\n");
1657                        }
1658                        Slog.i(TAG, logBuilder.toString());
1659
1660                        StringBuilder dropBuilder = new StringBuilder(1024);
1661                        /*
1662                        StringWriter oomSw = new StringWriter();
1663                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1664                        StringWriter catSw = new StringWriter();
1665                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1666                        String[] emptyArgs = new String[] { };
1667                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1668                        oomPw.flush();
1669                        String oomString = oomSw.toString();
1670                        */
1671                        dropBuilder.append(stack);
1672                        dropBuilder.append('\n');
1673                        dropBuilder.append('\n');
1674                        dropBuilder.append(logBuilder);
1675                        dropBuilder.append('\n');
1676                        /*
1677                        dropBuilder.append(oomString);
1678                        dropBuilder.append('\n');
1679                        */
1680                        StringWriter catSw = new StringWriter();
1681                        synchronized (ActivityManagerService.this) {
1682                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1683                            String[] emptyArgs = new String[] { };
1684                            catPw.println();
1685                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1686                            catPw.println();
1687                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1688                                    false, false, null);
1689                            catPw.println();
1690                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1691                            catPw.flush();
1692                        }
1693                        dropBuilder.append(catSw.toString());
1694                        addErrorToDropBox("lowmem", null, "system_server", null,
1695                                null, tag.toString(), dropBuilder.toString(), null, null);
1696                        //Slog.i(TAG, "Sent to dropbox:");
1697                        //Slog.i(TAG, dropBuilder.toString());
1698                        synchronized (ActivityManagerService.this) {
1699                            long now = SystemClock.uptimeMillis();
1700                            if (mLastMemUsageReportTime < now) {
1701                                mLastMemUsageReportTime = now;
1702                            }
1703                        }
1704                    }
1705                };
1706                thread.start();
1707                break;
1708            }
1709            case REPORT_USER_SWITCH_MSG: {
1710                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1711                break;
1712            }
1713            case CONTINUE_USER_SWITCH_MSG: {
1714                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1715                break;
1716            }
1717            case USER_SWITCH_TIMEOUT_MSG: {
1718                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1719                break;
1720            }
1721            case IMMERSIVE_MODE_LOCK_MSG: {
1722                final boolean nextState = (msg.arg1 != 0);
1723                if (mUpdateLock.isHeld() != nextState) {
1724                    if (DEBUG_IMMERSIVE) {
1725                        final ActivityRecord r = (ActivityRecord) msg.obj;
1726                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1727                    }
1728                    if (nextState) {
1729                        mUpdateLock.acquire();
1730                    } else {
1731                        mUpdateLock.release();
1732                    }
1733                }
1734                break;
1735            }
1736            case PERSIST_URI_GRANTS_MSG: {
1737                writeGrantedUriPermissions();
1738                break;
1739            }
1740            case REQUEST_ALL_PSS_MSG: {
1741                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1742                break;
1743            }
1744            case START_PROFILES_MSG: {
1745                synchronized (ActivityManagerService.this) {
1746                    startProfilesLocked();
1747                }
1748                break;
1749            }
1750            case UPDATE_TIME: {
1751                synchronized (ActivityManagerService.this) {
1752                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1753                        ProcessRecord r = mLruProcesses.get(i);
1754                        if (r.thread != null) {
1755                            try {
1756                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1757                            } catch (RemoteException ex) {
1758                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1759                            }
1760                        }
1761                    }
1762                }
1763                break;
1764            }
1765            case SYSTEM_USER_START_MSG: {
1766                mSystemServiceManager.startUser(msg.arg1);
1767                break;
1768            }
1769            case SYSTEM_USER_CURRENT_MSG: {
1770                mSystemServiceManager.switchUser(msg.arg1);
1771                break;
1772            }
1773            }
1774        }
1775    };
1776
1777    static final int COLLECT_PSS_BG_MSG = 1;
1778
1779    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1780        @Override
1781        public void handleMessage(Message msg) {
1782            switch (msg.what) {
1783            case COLLECT_PSS_BG_MSG: {
1784                int i=0, num=0;
1785                long start = SystemClock.uptimeMillis();
1786                long[] tmp = new long[1];
1787                do {
1788                    ProcessRecord proc;
1789                    int procState;
1790                    int pid;
1791                    synchronized (ActivityManagerService.this) {
1792                        if (i >= mPendingPssProcesses.size()) {
1793                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1794                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1795                            mPendingPssProcesses.clear();
1796                            return;
1797                        }
1798                        proc = mPendingPssProcesses.get(i);
1799                        procState = proc.pssProcState;
1800                        if (proc.thread != null && procState == proc.setProcState) {
1801                            pid = proc.pid;
1802                        } else {
1803                            proc = null;
1804                            pid = 0;
1805                        }
1806                        i++;
1807                    }
1808                    if (proc != null) {
1809                        long pss = Debug.getPss(pid, tmp);
1810                        synchronized (ActivityManagerService.this) {
1811                            if (proc.thread != null && proc.setProcState == procState
1812                                    && proc.pid == pid) {
1813                                num++;
1814                                proc.lastPssTime = SystemClock.uptimeMillis();
1815                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1816                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1817                                        + ": " + pss + " lastPss=" + proc.lastPss
1818                                        + " state=" + ProcessList.makeProcStateString(procState));
1819                                if (proc.initialIdlePss == 0) {
1820                                    proc.initialIdlePss = pss;
1821                                }
1822                                proc.lastPss = pss;
1823                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1824                                    proc.lastCachedPss = pss;
1825                                }
1826                            }
1827                        }
1828                    }
1829                } while (true);
1830            }
1831            }
1832        }
1833    };
1834
1835    /**
1836     * Monitor for package changes and update our internal state.
1837     */
1838    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1839        @Override
1840        public void onPackageRemoved(String packageName, int uid) {
1841            // Remove all tasks with activities in the specified package from the list of recent tasks
1842            synchronized (ActivityManagerService.this) {
1843                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1844                    TaskRecord tr = mRecentTasks.get(i);
1845                    ComponentName cn = tr.intent.getComponent();
1846                    if (cn != null && cn.getPackageName().equals(packageName)) {
1847                        // If the package name matches, remove the task and kill the process
1848                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1849                    }
1850                }
1851            }
1852        }
1853
1854        @Override
1855        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1856            onPackageModified(packageName);
1857            return true;
1858        }
1859
1860        @Override
1861        public void onPackageModified(String packageName) {
1862            final PackageManager pm = mContext.getPackageManager();
1863            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1864                    new ArrayList<Pair<Intent, Integer>>();
1865            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1866            // Copy the list of recent tasks so that we don't hold onto the lock on
1867            // ActivityManagerService for long periods while checking if components exist.
1868            synchronized (ActivityManagerService.this) {
1869                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1870                    TaskRecord tr = mRecentTasks.get(i);
1871                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1872                }
1873            }
1874            // Check the recent tasks and filter out all tasks with components that no longer exist.
1875            Intent tmpI = new Intent();
1876            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1877                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1878                ComponentName cn = p.first.getComponent();
1879                if (cn != null && cn.getPackageName().equals(packageName)) {
1880                    try {
1881                        // Add the task to the list to remove if the component no longer exists
1882                        tmpI.setComponent(cn);
1883                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1884                            tasksToRemove.add(p.second);
1885                        }
1886                    } catch (Exception e) {}
1887                }
1888            }
1889            // Prune all the tasks with removed components from the list of recent tasks
1890            synchronized (ActivityManagerService.this) {
1891                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1892                    // Remove the task but don't kill the process (since other components in that
1893                    // package may still be running and in the background)
1894                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1895                }
1896            }
1897        }
1898
1899        @Override
1900        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1901            // Force stop the specified packages
1902            if (packages != null) {
1903                for (String pkg : packages) {
1904                    synchronized (ActivityManagerService.this) {
1905                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
1906                                "finished booting")) {
1907                            return true;
1908                        }
1909                    }
1910                }
1911            }
1912            return false;
1913        }
1914    };
1915
1916    public void setSystemProcess() {
1917        try {
1918            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1919            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1920            ServiceManager.addService("meminfo", new MemBinder(this));
1921            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1922            ServiceManager.addService("dbinfo", new DbBinder(this));
1923            if (MONITOR_CPU_USAGE) {
1924                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1925            }
1926            ServiceManager.addService("permission", new PermissionController(this));
1927
1928            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1929                    "android", STOCK_PM_FLAGS);
1930            mSystemThread.installSystemApplicationInfo(info);
1931
1932            synchronized (this) {
1933                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
1934                app.persistent = true;
1935                app.pid = MY_PID;
1936                app.maxAdj = ProcessList.SYSTEM_ADJ;
1937                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1938                mProcessNames.put(app.processName, app.uid, app);
1939                synchronized (mPidsSelfLocked) {
1940                    mPidsSelfLocked.put(app.pid, app);
1941                }
1942                updateLruProcessLocked(app, false, null);
1943                updateOomAdjLocked();
1944            }
1945        } catch (PackageManager.NameNotFoundException e) {
1946            throw new RuntimeException(
1947                    "Unable to find android system package", e);
1948        }
1949    }
1950
1951    public void setWindowManager(WindowManagerService wm) {
1952        mWindowManager = wm;
1953        mStackSupervisor.setWindowManager(wm);
1954    }
1955
1956    public void startObservingNativeCrashes() {
1957        final NativeCrashListener ncl = new NativeCrashListener(this);
1958        ncl.start();
1959    }
1960
1961    public IAppOpsService getAppOpsService() {
1962        return mAppOpsService;
1963    }
1964
1965    static class MemBinder extends Binder {
1966        ActivityManagerService mActivityManagerService;
1967        MemBinder(ActivityManagerService activityManagerService) {
1968            mActivityManagerService = activityManagerService;
1969        }
1970
1971        @Override
1972        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1973            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1974                    != PackageManager.PERMISSION_GRANTED) {
1975                pw.println("Permission Denial: can't dump meminfo from from pid="
1976                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1977                        + " without permission " + android.Manifest.permission.DUMP);
1978                return;
1979            }
1980
1981            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1982        }
1983    }
1984
1985    static class GraphicsBinder extends Binder {
1986        ActivityManagerService mActivityManagerService;
1987        GraphicsBinder(ActivityManagerService activityManagerService) {
1988            mActivityManagerService = activityManagerService;
1989        }
1990
1991        @Override
1992        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1993            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1994                    != PackageManager.PERMISSION_GRANTED) {
1995                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1996                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1997                        + " without permission " + android.Manifest.permission.DUMP);
1998                return;
1999            }
2000
2001            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2002        }
2003    }
2004
2005    static class DbBinder extends Binder {
2006        ActivityManagerService mActivityManagerService;
2007        DbBinder(ActivityManagerService activityManagerService) {
2008            mActivityManagerService = activityManagerService;
2009        }
2010
2011        @Override
2012        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2013            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2014                    != PackageManager.PERMISSION_GRANTED) {
2015                pw.println("Permission Denial: can't dump dbinfo from from pid="
2016                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2017                        + " without permission " + android.Manifest.permission.DUMP);
2018                return;
2019            }
2020
2021            mActivityManagerService.dumpDbInfo(fd, pw, args);
2022        }
2023    }
2024
2025    static class CpuBinder extends Binder {
2026        ActivityManagerService mActivityManagerService;
2027        CpuBinder(ActivityManagerService activityManagerService) {
2028            mActivityManagerService = activityManagerService;
2029        }
2030
2031        @Override
2032        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2033            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2034                    != PackageManager.PERMISSION_GRANTED) {
2035                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2036                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2037                        + " without permission " + android.Manifest.permission.DUMP);
2038                return;
2039            }
2040
2041            synchronized (mActivityManagerService.mProcessCpuThread) {
2042                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2043                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2044                        SystemClock.uptimeMillis()));
2045            }
2046        }
2047    }
2048
2049    public static final class Lifecycle extends SystemService {
2050        private final ActivityManagerService mService;
2051
2052        public Lifecycle(Context context) {
2053            super(context);
2054            mService = new ActivityManagerService(context);
2055        }
2056
2057        @Override
2058        public void onStart() {
2059            mService.start();
2060        }
2061
2062        public ActivityManagerService getService() {
2063            return mService;
2064        }
2065    }
2066
2067    // Note: This method is invoked on the main thread but may need to attach various
2068    // handlers to other threads.  So take care to be explicit about the looper.
2069    public ActivityManagerService(Context systemContext) {
2070        mContext = systemContext;
2071        mFactoryTest = FactoryTest.getMode();
2072        mSystemThread = ActivityThread.currentActivityThread();
2073
2074        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2075
2076        mHandlerThread = new ServiceThread(TAG,
2077                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2078        mHandlerThread.start();
2079        mHandler = new MainHandler(mHandlerThread.getLooper());
2080
2081        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2082                "foreground", BROADCAST_FG_TIMEOUT, false);
2083        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2084                "background", BROADCAST_BG_TIMEOUT, true);
2085        mBroadcastQueues[0] = mFgBroadcastQueue;
2086        mBroadcastQueues[1] = mBgBroadcastQueue;
2087
2088        mServices = new ActiveServices(this);
2089        mProviderMap = new ProviderMap(this);
2090
2091        // TODO: Move creation of battery stats service outside of activity manager service.
2092        File dataDir = Environment.getDataDirectory();
2093        File systemDir = new File(dataDir, "system");
2094        systemDir.mkdirs();
2095        mBatteryStatsService = new BatteryStatsService(new File(
2096                systemDir, "batterystats.bin").toString(), mHandler);
2097        mBatteryStatsService.getActiveStatistics().readLocked();
2098        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2099        mOnBattery = DEBUG_POWER ? true
2100                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2101        mBatteryStatsService.getActiveStatistics().setCallback(this);
2102
2103        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2104
2105        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
2106        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2107
2108        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2109
2110        // User 0 is the first and only user that runs at boot.
2111        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2112        mUserLru.add(Integer.valueOf(0));
2113        updateStartedUserArrayLocked();
2114
2115        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2116            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2117
2118        mConfiguration.setToDefaults();
2119        mConfiguration.setLocale(Locale.getDefault());
2120
2121        mConfigurationSeq = mConfiguration.seq = 1;
2122        mProcessCpuTracker.init();
2123
2124        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2125        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2126        mStackSupervisor = new ActivityStackSupervisor(this);
2127
2128        mProcessCpuThread = new Thread("CpuTracker") {
2129            @Override
2130            public void run() {
2131                while (true) {
2132                    try {
2133                        try {
2134                            synchronized(this) {
2135                                final long now = SystemClock.uptimeMillis();
2136                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2137                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2138                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2139                                //        + ", write delay=" + nextWriteDelay);
2140                                if (nextWriteDelay < nextCpuDelay) {
2141                                    nextCpuDelay = nextWriteDelay;
2142                                }
2143                                if (nextCpuDelay > 0) {
2144                                    mProcessCpuMutexFree.set(true);
2145                                    this.wait(nextCpuDelay);
2146                                }
2147                            }
2148                        } catch (InterruptedException e) {
2149                        }
2150                        updateCpuStatsNow();
2151                    } catch (Exception e) {
2152                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2153                    }
2154                }
2155            }
2156        };
2157
2158        Watchdog.getInstance().addMonitor(this);
2159        Watchdog.getInstance().addThread(mHandler);
2160    }
2161
2162    public void setSystemServiceManager(SystemServiceManager mgr) {
2163        mSystemServiceManager = mgr;
2164    }
2165
2166    private void start() {
2167        mProcessCpuThread.start();
2168
2169        mBatteryStatsService.publish(mContext);
2170        mUsageStatsService.publish(mContext);
2171        mAppOpsService.publish(mContext);
2172
2173        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2174    }
2175
2176    @Override
2177    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2178            throws RemoteException {
2179        if (code == SYSPROPS_TRANSACTION) {
2180            // We need to tell all apps about the system property change.
2181            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2182            synchronized(this) {
2183                final int NP = mProcessNames.getMap().size();
2184                for (int ip=0; ip<NP; ip++) {
2185                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2186                    final int NA = apps.size();
2187                    for (int ia=0; ia<NA; ia++) {
2188                        ProcessRecord app = apps.valueAt(ia);
2189                        if (app.thread != null) {
2190                            procs.add(app.thread.asBinder());
2191                        }
2192                    }
2193                }
2194            }
2195
2196            int N = procs.size();
2197            for (int i=0; i<N; i++) {
2198                Parcel data2 = Parcel.obtain();
2199                try {
2200                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2201                } catch (RemoteException e) {
2202                }
2203                data2.recycle();
2204            }
2205        }
2206        try {
2207            return super.onTransact(code, data, reply, flags);
2208        } catch (RuntimeException e) {
2209            // The activity manager only throws security exceptions, so let's
2210            // log all others.
2211            if (!(e instanceof SecurityException)) {
2212                Slog.wtf(TAG, "Activity Manager Crash", e);
2213            }
2214            throw e;
2215        }
2216    }
2217
2218    void updateCpuStats() {
2219        final long now = SystemClock.uptimeMillis();
2220        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2221            return;
2222        }
2223        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2224            synchronized (mProcessCpuThread) {
2225                mProcessCpuThread.notify();
2226            }
2227        }
2228    }
2229
2230    void updateCpuStatsNow() {
2231        synchronized (mProcessCpuThread) {
2232            mProcessCpuMutexFree.set(false);
2233            final long now = SystemClock.uptimeMillis();
2234            boolean haveNewCpuStats = false;
2235
2236            if (MONITOR_CPU_USAGE &&
2237                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2238                mLastCpuTime.set(now);
2239                haveNewCpuStats = true;
2240                mProcessCpuTracker.update();
2241                //Slog.i(TAG, mProcessCpu.printCurrentState());
2242                //Slog.i(TAG, "Total CPU usage: "
2243                //        + mProcessCpu.getTotalCpuPercent() + "%");
2244
2245                // Slog the cpu usage if the property is set.
2246                if ("true".equals(SystemProperties.get("events.cpu"))) {
2247                    int user = mProcessCpuTracker.getLastUserTime();
2248                    int system = mProcessCpuTracker.getLastSystemTime();
2249                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2250                    int irq = mProcessCpuTracker.getLastIrqTime();
2251                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2252                    int idle = mProcessCpuTracker.getLastIdleTime();
2253
2254                    int total = user + system + iowait + irq + softIrq + idle;
2255                    if (total == 0) total = 1;
2256
2257                    EventLog.writeEvent(EventLogTags.CPU,
2258                            ((user+system+iowait+irq+softIrq) * 100) / total,
2259                            (user * 100) / total,
2260                            (system * 100) / total,
2261                            (iowait * 100) / total,
2262                            (irq * 100) / total,
2263                            (softIrq * 100) / total);
2264                }
2265            }
2266
2267            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2268            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2269            synchronized(bstats) {
2270                synchronized(mPidsSelfLocked) {
2271                    if (haveNewCpuStats) {
2272                        if (mOnBattery) {
2273                            int perc = bstats.startAddingCpuLocked();
2274                            int totalUTime = 0;
2275                            int totalSTime = 0;
2276                            final int N = mProcessCpuTracker.countStats();
2277                            for (int i=0; i<N; i++) {
2278                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2279                                if (!st.working) {
2280                                    continue;
2281                                }
2282                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2283                                int otherUTime = (st.rel_utime*perc)/100;
2284                                int otherSTime = (st.rel_stime*perc)/100;
2285                                totalUTime += otherUTime;
2286                                totalSTime += otherSTime;
2287                                if (pr != null) {
2288                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2289                                    if (ps == null || !ps.isActive()) {
2290                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2291                                                pr.info.uid, pr.processName);
2292                                    }
2293                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2294                                            st.rel_stime-otherSTime);
2295                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2296                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2297                                } else {
2298                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2299                                    if (ps == null || !ps.isActive()) {
2300                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2301                                                bstats.mapUid(st.uid), st.name);
2302                                    }
2303                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2304                                            st.rel_stime-otherSTime);
2305                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2306                                }
2307                            }
2308                            bstats.finishAddingCpuLocked(perc, totalUTime,
2309                                    totalSTime, cpuSpeedTimes);
2310                        }
2311                    }
2312                }
2313
2314                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2315                    mLastWriteTime = now;
2316                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2317                }
2318            }
2319        }
2320    }
2321
2322    @Override
2323    public void batteryNeedsCpuUpdate() {
2324        updateCpuStatsNow();
2325    }
2326
2327    @Override
2328    public void batteryPowerChanged(boolean onBattery) {
2329        // When plugging in, update the CPU stats first before changing
2330        // the plug state.
2331        updateCpuStatsNow();
2332        synchronized (this) {
2333            synchronized(mPidsSelfLocked) {
2334                mOnBattery = DEBUG_POWER ? true : onBattery;
2335            }
2336        }
2337    }
2338
2339    /**
2340     * Initialize the application bind args. These are passed to each
2341     * process when the bindApplication() IPC is sent to the process. They're
2342     * lazily setup to make sure the services are running when they're asked for.
2343     */
2344    private HashMap<String, IBinder> getCommonServicesLocked() {
2345        if (mAppBindArgs == null) {
2346            mAppBindArgs = new HashMap<String, IBinder>();
2347
2348            // Setup the application init args
2349            mAppBindArgs.put("package", ServiceManager.getService("package"));
2350            mAppBindArgs.put("window", ServiceManager.getService("window"));
2351            mAppBindArgs.put(Context.ALARM_SERVICE,
2352                    ServiceManager.getService(Context.ALARM_SERVICE));
2353        }
2354        return mAppBindArgs;
2355    }
2356
2357    final void setFocusedActivityLocked(ActivityRecord r) {
2358        if (mFocusedActivity != r) {
2359            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2360            mFocusedActivity = r;
2361            if (r.task != null && r.task.voiceInteractor != null) {
2362                startRunningVoiceLocked();
2363            } else {
2364                finishRunningVoiceLocked();
2365            }
2366            mStackSupervisor.setFocusedStack(r);
2367            if (r != null) {
2368                mWindowManager.setFocusedApp(r.appToken, true);
2369            }
2370            applyUpdateLockStateLocked(r);
2371        }
2372    }
2373
2374    final void clearFocusedActivity(ActivityRecord r) {
2375        if (mFocusedActivity == r) {
2376            mFocusedActivity = null;
2377        }
2378    }
2379
2380    @Override
2381    public void setFocusedStack(int stackId) {
2382        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2383        synchronized (ActivityManagerService.this) {
2384            ActivityStack stack = mStackSupervisor.getStack(stackId);
2385            if (stack != null) {
2386                ActivityRecord r = stack.topRunningActivityLocked(null);
2387                if (r != null) {
2388                    setFocusedActivityLocked(r);
2389                }
2390            }
2391        }
2392    }
2393
2394    @Override
2395    public void notifyActivityDrawn(IBinder token) {
2396        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2397        synchronized (this) {
2398            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2399            if (r != null) {
2400                r.task.stack.notifyActivityDrawnLocked(r);
2401            }
2402        }
2403    }
2404
2405    final void applyUpdateLockStateLocked(ActivityRecord r) {
2406        // Modifications to the UpdateLock state are done on our handler, outside
2407        // the activity manager's locks.  The new state is determined based on the
2408        // state *now* of the relevant activity record.  The object is passed to
2409        // the handler solely for logging detail, not to be consulted/modified.
2410        final boolean nextState = r != null && r.immersive;
2411        mHandler.sendMessage(
2412                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2413    }
2414
2415    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2416        Message msg = Message.obtain();
2417        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2418        msg.obj = r.task.askedCompatMode ? null : r;
2419        mHandler.sendMessage(msg);
2420    }
2421
2422    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2423            String what, Object obj, ProcessRecord srcApp) {
2424        app.lastActivityTime = now;
2425
2426        if (app.activities.size() > 0) {
2427            // Don't want to touch dependent processes that are hosting activities.
2428            return index;
2429        }
2430
2431        int lrui = mLruProcesses.lastIndexOf(app);
2432        if (lrui < 0) {
2433            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2434                    + what + " " + obj + " from " + srcApp);
2435            return index;
2436        }
2437
2438        if (lrui >= index) {
2439            // Don't want to cause this to move dependent processes *back* in the
2440            // list as if they were less frequently used.
2441            return index;
2442        }
2443
2444        if (lrui >= mLruProcessActivityStart) {
2445            // Don't want to touch dependent processes that are hosting activities.
2446            return index;
2447        }
2448
2449        mLruProcesses.remove(lrui);
2450        if (index > 0) {
2451            index--;
2452        }
2453        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2454                + " in LRU list: " + app);
2455        mLruProcesses.add(index, app);
2456        return index;
2457    }
2458
2459    final void removeLruProcessLocked(ProcessRecord app) {
2460        int lrui = mLruProcesses.lastIndexOf(app);
2461        if (lrui >= 0) {
2462            if (lrui <= mLruProcessActivityStart) {
2463                mLruProcessActivityStart--;
2464            }
2465            if (lrui <= mLruProcessServiceStart) {
2466                mLruProcessServiceStart--;
2467            }
2468            mLruProcesses.remove(lrui);
2469        }
2470    }
2471
2472    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2473            ProcessRecord client) {
2474        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2475                || app.treatLikeActivity;
2476        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2477        if (!activityChange && hasActivity) {
2478            // The process has activities, so we are only allowing activity-based adjustments
2479            // to move it.  It should be kept in the front of the list with other
2480            // processes that have activities, and we don't want those to change their
2481            // order except due to activity operations.
2482            return;
2483        }
2484
2485        mLruSeq++;
2486        final long now = SystemClock.uptimeMillis();
2487        app.lastActivityTime = now;
2488
2489        // First a quick reject: if the app is already at the position we will
2490        // put it, then there is nothing to do.
2491        if (hasActivity) {
2492            final int N = mLruProcesses.size();
2493            if (N > 0 && mLruProcesses.get(N-1) == app) {
2494                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2495                return;
2496            }
2497        } else {
2498            if (mLruProcessServiceStart > 0
2499                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2500                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2501                return;
2502            }
2503        }
2504
2505        int lrui = mLruProcesses.lastIndexOf(app);
2506
2507        if (app.persistent && lrui >= 0) {
2508            // We don't care about the position of persistent processes, as long as
2509            // they are in the list.
2510            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2511            return;
2512        }
2513
2514        /* In progress: compute new position first, so we can avoid doing work
2515           if the process is not actually going to move.  Not yet working.
2516        int addIndex;
2517        int nextIndex;
2518        boolean inActivity = false, inService = false;
2519        if (hasActivity) {
2520            // Process has activities, put it at the very tipsy-top.
2521            addIndex = mLruProcesses.size();
2522            nextIndex = mLruProcessServiceStart;
2523            inActivity = true;
2524        } else if (hasService) {
2525            // Process has services, put it at the top of the service list.
2526            addIndex = mLruProcessActivityStart;
2527            nextIndex = mLruProcessServiceStart;
2528            inActivity = true;
2529            inService = true;
2530        } else  {
2531            // Process not otherwise of interest, it goes to the top of the non-service area.
2532            addIndex = mLruProcessServiceStart;
2533            if (client != null) {
2534                int clientIndex = mLruProcesses.lastIndexOf(client);
2535                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2536                        + app);
2537                if (clientIndex >= 0 && addIndex > clientIndex) {
2538                    addIndex = clientIndex;
2539                }
2540            }
2541            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2542        }
2543
2544        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2545                + mLruProcessActivityStart + "): " + app);
2546        */
2547
2548        if (lrui >= 0) {
2549            if (lrui < mLruProcessActivityStart) {
2550                mLruProcessActivityStart--;
2551            }
2552            if (lrui < mLruProcessServiceStart) {
2553                mLruProcessServiceStart--;
2554            }
2555            /*
2556            if (addIndex > lrui) {
2557                addIndex--;
2558            }
2559            if (nextIndex > lrui) {
2560                nextIndex--;
2561            }
2562            */
2563            mLruProcesses.remove(lrui);
2564        }
2565
2566        /*
2567        mLruProcesses.add(addIndex, app);
2568        if (inActivity) {
2569            mLruProcessActivityStart++;
2570        }
2571        if (inService) {
2572            mLruProcessActivityStart++;
2573        }
2574        */
2575
2576        int nextIndex;
2577        if (hasActivity) {
2578            final int N = mLruProcesses.size();
2579            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2580                // Process doesn't have activities, but has clients with
2581                // activities...  move it up, but one below the top (the top
2582                // should always have a real activity).
2583                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2584                mLruProcesses.add(N-1, app);
2585                // To keep it from spamming the LRU list (by making a bunch of clients),
2586                // we will push down any other entries owned by the app.
2587                final int uid = app.info.uid;
2588                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2589                    ProcessRecord subProc = mLruProcesses.get(i);
2590                    if (subProc.info.uid == uid) {
2591                        // We want to push this one down the list.  If the process after
2592                        // it is for the same uid, however, don't do so, because we don't
2593                        // want them internally to be re-ordered.
2594                        if (mLruProcesses.get(i-1).info.uid != uid) {
2595                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2596                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2597                            ProcessRecord tmp = mLruProcesses.get(i);
2598                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2599                            mLruProcesses.set(i-1, tmp);
2600                            i--;
2601                        }
2602                    } else {
2603                        // A gap, we can stop here.
2604                        break;
2605                    }
2606                }
2607            } else {
2608                // Process has activities, put it at the very tipsy-top.
2609                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2610                mLruProcesses.add(app);
2611            }
2612            nextIndex = mLruProcessServiceStart;
2613        } else if (hasService) {
2614            // Process has services, put it at the top of the service list.
2615            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2616            mLruProcesses.add(mLruProcessActivityStart, app);
2617            nextIndex = mLruProcessServiceStart;
2618            mLruProcessActivityStart++;
2619        } else  {
2620            // Process not otherwise of interest, it goes to the top of the non-service area.
2621            int index = mLruProcessServiceStart;
2622            if (client != null) {
2623                // If there is a client, don't allow the process to be moved up higher
2624                // in the list than that client.
2625                int clientIndex = mLruProcesses.lastIndexOf(client);
2626                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2627                        + " when updating " + app);
2628                if (clientIndex <= lrui) {
2629                    // Don't allow the client index restriction to push it down farther in the
2630                    // list than it already is.
2631                    clientIndex = lrui;
2632                }
2633                if (clientIndex >= 0 && index > clientIndex) {
2634                    index = clientIndex;
2635                }
2636            }
2637            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2638            mLruProcesses.add(index, app);
2639            nextIndex = index-1;
2640            mLruProcessActivityStart++;
2641            mLruProcessServiceStart++;
2642        }
2643
2644        // If the app is currently using a content provider or service,
2645        // bump those processes as well.
2646        for (int j=app.connections.size()-1; j>=0; j--) {
2647            ConnectionRecord cr = app.connections.valueAt(j);
2648            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2649                    && cr.binding.service.app != null
2650                    && cr.binding.service.app.lruSeq != mLruSeq
2651                    && !cr.binding.service.app.persistent) {
2652                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2653                        "service connection", cr, app);
2654            }
2655        }
2656        for (int j=app.conProviders.size()-1; j>=0; j--) {
2657            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2658            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2659                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2660                        "provider reference", cpr, app);
2661            }
2662        }
2663    }
2664
2665    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2666        if (uid == Process.SYSTEM_UID) {
2667            // The system gets to run in any process.  If there are multiple
2668            // processes with the same uid, just pick the first (this
2669            // should never happen).
2670            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2671            if (procs == null) return null;
2672            final int N = procs.size();
2673            for (int i = 0; i < N; i++) {
2674                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2675            }
2676        }
2677        ProcessRecord proc = mProcessNames.get(processName, uid);
2678        if (false && proc != null && !keepIfLarge
2679                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2680                && proc.lastCachedPss >= 4000) {
2681            // Turn this condition on to cause killing to happen regularly, for testing.
2682            if (proc.baseProcessTracker != null) {
2683                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2684            }
2685            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2686                    + "k from cached");
2687        } else if (proc != null && !keepIfLarge
2688                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2689                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2690            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2691            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2692                if (proc.baseProcessTracker != null) {
2693                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2694                }
2695                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2696                        + "k from cached");
2697            }
2698        }
2699        return proc;
2700    }
2701
2702    void ensurePackageDexOpt(String packageName) {
2703        IPackageManager pm = AppGlobals.getPackageManager();
2704        try {
2705            if (pm.performDexOpt(packageName)) {
2706                mDidDexOpt = true;
2707            }
2708        } catch (RemoteException e) {
2709        }
2710    }
2711
2712    boolean isNextTransitionForward() {
2713        int transit = mWindowManager.getPendingAppTransition();
2714        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2715                || transit == AppTransition.TRANSIT_TASK_OPEN
2716                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2717    }
2718
2719    final ProcessRecord startProcessLocked(String processName,
2720            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2721            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2722            boolean isolated, boolean keepIfLarge) {
2723        ProcessRecord app;
2724        if (!isolated) {
2725            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2726        } else {
2727            // If this is an isolated process, it can't re-use an existing process.
2728            app = null;
2729        }
2730        // We don't have to do anything more if:
2731        // (1) There is an existing application record; and
2732        // (2) The caller doesn't think it is dead, OR there is no thread
2733        //     object attached to it so we know it couldn't have crashed; and
2734        // (3) There is a pid assigned to it, so it is either starting or
2735        //     already running.
2736        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2737                + " app=" + app + " knownToBeDead=" + knownToBeDead
2738                + " thread=" + (app != null ? app.thread : null)
2739                + " pid=" + (app != null ? app.pid : -1));
2740        if (app != null && app.pid > 0) {
2741            if (!knownToBeDead || app.thread == null) {
2742                // We already have the app running, or are waiting for it to
2743                // come up (we have a pid but not yet its thread), so keep it.
2744                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2745                // If this is a new package in the process, add the package to the list
2746                app.addPackage(info.packageName, mProcessStats);
2747                return app;
2748            }
2749
2750            // An application record is attached to a previous process,
2751            // clean it up now.
2752            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2753            handleAppDiedLocked(app, true, true);
2754        }
2755
2756        String hostingNameStr = hostingName != null
2757                ? hostingName.flattenToShortString() : null;
2758
2759        if (!isolated) {
2760            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2761                // If we are in the background, then check to see if this process
2762                // is bad.  If so, we will just silently fail.
2763                if (mBadProcesses.get(info.processName, info.uid) != null) {
2764                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2765                            + "/" + info.processName);
2766                    return null;
2767                }
2768            } else {
2769                // When the user is explicitly starting a process, then clear its
2770                // crash count so that we won't make it bad until they see at
2771                // least one crash dialog again, and make the process good again
2772                // if it had been bad.
2773                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2774                        + "/" + info.processName);
2775                mProcessCrashTimes.remove(info.processName, info.uid);
2776                if (mBadProcesses.get(info.processName, info.uid) != null) {
2777                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2778                            UserHandle.getUserId(info.uid), info.uid,
2779                            info.processName);
2780                    mBadProcesses.remove(info.processName, info.uid);
2781                    if (app != null) {
2782                        app.bad = false;
2783                    }
2784                }
2785            }
2786        }
2787
2788        if (app == null) {
2789            app = newProcessRecordLocked(info, processName, isolated);
2790            if (app == null) {
2791                Slog.w(TAG, "Failed making new process record for "
2792                        + processName + "/" + info.uid + " isolated=" + isolated);
2793                return null;
2794            }
2795            mProcessNames.put(processName, app.uid, app);
2796            if (isolated) {
2797                mIsolatedProcesses.put(app.uid, app);
2798            }
2799        } else {
2800            // If this is a new package in the process, add the package to the list
2801            app.addPackage(info.packageName, mProcessStats);
2802        }
2803
2804        // If the system is not ready yet, then hold off on starting this
2805        // process until it is.
2806        if (!mProcessesReady
2807                && !isAllowedWhileBooting(info)
2808                && !allowWhileBooting) {
2809            if (!mProcessesOnHold.contains(app)) {
2810                mProcessesOnHold.add(app);
2811            }
2812            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2813            return app;
2814        }
2815
2816        startProcessLocked(app, hostingType, hostingNameStr);
2817        return (app.pid != 0) ? app : null;
2818    }
2819
2820    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2821        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2822    }
2823
2824    private final void startProcessLocked(ProcessRecord app,
2825            String hostingType, String hostingNameStr) {
2826        if (app.pid > 0 && app.pid != MY_PID) {
2827            synchronized (mPidsSelfLocked) {
2828                mPidsSelfLocked.remove(app.pid);
2829                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2830            }
2831            app.setPid(0);
2832        }
2833
2834        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2835                "startProcessLocked removing on hold: " + app);
2836        mProcessesOnHold.remove(app);
2837
2838        updateCpuStats();
2839
2840        try {
2841            int uid = app.uid;
2842
2843            int[] gids = null;
2844            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2845            if (!app.isolated) {
2846                int[] permGids = null;
2847                try {
2848                    final PackageManager pm = mContext.getPackageManager();
2849                    permGids = pm.getPackageGids(app.info.packageName);
2850
2851                    if (Environment.isExternalStorageEmulated()) {
2852                        if (pm.checkPermission(
2853                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2854                                app.info.packageName) == PERMISSION_GRANTED) {
2855                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2856                        } else {
2857                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2858                        }
2859                    }
2860                } catch (PackageManager.NameNotFoundException e) {
2861                    Slog.w(TAG, "Unable to retrieve gids", e);
2862                }
2863
2864                /*
2865                 * Add shared application GID so applications can share some
2866                 * resources like shared libraries
2867                 */
2868                if (permGids == null) {
2869                    gids = new int[1];
2870                } else {
2871                    gids = new int[permGids.length + 1];
2872                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2873                }
2874                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2875            }
2876            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2877                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2878                        && mTopComponent != null
2879                        && app.processName.equals(mTopComponent.getPackageName())) {
2880                    uid = 0;
2881                }
2882                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2883                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2884                    uid = 0;
2885                }
2886            }
2887            int debugFlags = 0;
2888            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2889                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2890                // Also turn on CheckJNI for debuggable apps. It's quite
2891                // awkward to turn on otherwise.
2892                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2893            }
2894            // Run the app in safe mode if its manifest requests so or the
2895            // system is booted in safe mode.
2896            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2897                mSafeMode == true) {
2898                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2899            }
2900            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2901                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2902            }
2903            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2904                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2905            }
2906            if ("1".equals(SystemProperties.get("debug.assert"))) {
2907                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2908            }
2909
2910            String requiredAbi = app.info.cpuAbi;
2911            if (requiredAbi == null) {
2912                requiredAbi = Build.SUPPORTED_ABIS[0];
2913            }
2914
2915            // Start the process.  It will either succeed and return a result containing
2916            // the PID of the new process, or else throw a RuntimeException.
2917            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2918                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2919                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
2920
2921            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2922            synchronized (bs) {
2923                if (bs.isOnBattery()) {
2924                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2925                }
2926            }
2927
2928            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2929                    UserHandle.getUserId(uid), startResult.pid, uid,
2930                    app.processName, hostingType,
2931                    hostingNameStr != null ? hostingNameStr : "");
2932
2933            if (app.persistent) {
2934                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2935            }
2936
2937            StringBuilder buf = mStringBuilder;
2938            buf.setLength(0);
2939            buf.append("Start proc ");
2940            buf.append(app.processName);
2941            buf.append(" for ");
2942            buf.append(hostingType);
2943            if (hostingNameStr != null) {
2944                buf.append(" ");
2945                buf.append(hostingNameStr);
2946            }
2947            buf.append(": pid=");
2948            buf.append(startResult.pid);
2949            buf.append(" uid=");
2950            buf.append(uid);
2951            buf.append(" gids={");
2952            if (gids != null) {
2953                for (int gi=0; gi<gids.length; gi++) {
2954                    if (gi != 0) buf.append(", ");
2955                    buf.append(gids[gi]);
2956
2957                }
2958            }
2959            buf.append("}");
2960            Slog.i(TAG, buf.toString());
2961            app.setPid(startResult.pid);
2962            app.usingWrapper = startResult.usingWrapper;
2963            app.removed = false;
2964            synchronized (mPidsSelfLocked) {
2965                this.mPidsSelfLocked.put(startResult.pid, app);
2966                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2967                msg.obj = app;
2968                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2969                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2970            }
2971            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
2972                    app.processName, app.info.uid);
2973            if (app.isolated) {
2974                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2975            }
2976        } catch (RuntimeException e) {
2977            // XXX do better error recovery.
2978            app.setPid(0);
2979            Slog.e(TAG, "Failure starting process " + app.processName, e);
2980        }
2981    }
2982
2983    void updateUsageStats(ActivityRecord component, boolean resumed) {
2984        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
2985        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2986        if (resumed) {
2987            mUsageStatsService.noteResumeComponent(component.realActivity);
2988            synchronized (stats) {
2989                stats.noteActivityResumedLocked(component.app.uid);
2990            }
2991        } else {
2992            mUsageStatsService.notePauseComponent(component.realActivity);
2993            synchronized (stats) {
2994                stats.noteActivityPausedLocked(component.app.uid);
2995            }
2996        }
2997    }
2998
2999    Intent getHomeIntent() {
3000        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3001        intent.setComponent(mTopComponent);
3002        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3003            intent.addCategory(Intent.CATEGORY_HOME);
3004        }
3005        return intent;
3006    }
3007
3008    boolean startHomeActivityLocked(int userId) {
3009        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3010                && mTopAction == null) {
3011            // We are running in factory test mode, but unable to find
3012            // the factory test app, so just sit around displaying the
3013            // error message and don't try to start anything.
3014            return false;
3015        }
3016        Intent intent = getHomeIntent();
3017        ActivityInfo aInfo =
3018            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3019        if (aInfo != null) {
3020            intent.setComponent(new ComponentName(
3021                    aInfo.applicationInfo.packageName, aInfo.name));
3022            // Don't do this if the home app is currently being
3023            // instrumented.
3024            aInfo = new ActivityInfo(aInfo);
3025            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3026            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3027                    aInfo.applicationInfo.uid, true);
3028            if (app == null || app.instrumentationClass == null) {
3029                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3030                mStackSupervisor.startHomeActivity(intent, aInfo);
3031            }
3032        }
3033
3034        return true;
3035    }
3036
3037    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3038        ActivityInfo ai = null;
3039        ComponentName comp = intent.getComponent();
3040        try {
3041            if (comp != null) {
3042                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3043            } else {
3044                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3045                        intent,
3046                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3047                            flags, userId);
3048
3049                if (info != null) {
3050                    ai = info.activityInfo;
3051                }
3052            }
3053        } catch (RemoteException e) {
3054            // ignore
3055        }
3056
3057        return ai;
3058    }
3059
3060    /**
3061     * Starts the "new version setup screen" if appropriate.
3062     */
3063    void startSetupActivityLocked() {
3064        // Only do this once per boot.
3065        if (mCheckedForSetup) {
3066            return;
3067        }
3068
3069        // We will show this screen if the current one is a different
3070        // version than the last one shown, and we are not running in
3071        // low-level factory test mode.
3072        final ContentResolver resolver = mContext.getContentResolver();
3073        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3074                Settings.Global.getInt(resolver,
3075                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3076            mCheckedForSetup = true;
3077
3078            // See if we should be showing the platform update setup UI.
3079            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3080            List<ResolveInfo> ris = mContext.getPackageManager()
3081                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3082
3083            // We don't allow third party apps to replace this.
3084            ResolveInfo ri = null;
3085            for (int i=0; ris != null && i<ris.size(); i++) {
3086                if ((ris.get(i).activityInfo.applicationInfo.flags
3087                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3088                    ri = ris.get(i);
3089                    break;
3090                }
3091            }
3092
3093            if (ri != null) {
3094                String vers = ri.activityInfo.metaData != null
3095                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3096                        : null;
3097                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3098                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3099                            Intent.METADATA_SETUP_VERSION);
3100                }
3101                String lastVers = Settings.Secure.getString(
3102                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3103                if (vers != null && !vers.equals(lastVers)) {
3104                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3105                    intent.setComponent(new ComponentName(
3106                            ri.activityInfo.packageName, ri.activityInfo.name));
3107                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3108                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3109                }
3110            }
3111        }
3112    }
3113
3114    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3115        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3116    }
3117
3118    void enforceNotIsolatedCaller(String caller) {
3119        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3120            throw new SecurityException("Isolated process not allowed to call " + caller);
3121        }
3122    }
3123
3124    @Override
3125    public int getFrontActivityScreenCompatMode() {
3126        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3127        synchronized (this) {
3128            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3129        }
3130    }
3131
3132    @Override
3133    public void setFrontActivityScreenCompatMode(int mode) {
3134        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3135                "setFrontActivityScreenCompatMode");
3136        synchronized (this) {
3137            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3138        }
3139    }
3140
3141    @Override
3142    public int getPackageScreenCompatMode(String packageName) {
3143        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3144        synchronized (this) {
3145            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3146        }
3147    }
3148
3149    @Override
3150    public void setPackageScreenCompatMode(String packageName, int mode) {
3151        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3152                "setPackageScreenCompatMode");
3153        synchronized (this) {
3154            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3155        }
3156    }
3157
3158    @Override
3159    public boolean getPackageAskScreenCompat(String packageName) {
3160        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3161        synchronized (this) {
3162            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3163        }
3164    }
3165
3166    @Override
3167    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3168        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3169                "setPackageAskScreenCompat");
3170        synchronized (this) {
3171            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3172        }
3173    }
3174
3175    private void dispatchProcessesChanged() {
3176        int N;
3177        synchronized (this) {
3178            N = mPendingProcessChanges.size();
3179            if (mActiveProcessChanges.length < N) {
3180                mActiveProcessChanges = new ProcessChangeItem[N];
3181            }
3182            mPendingProcessChanges.toArray(mActiveProcessChanges);
3183            mAvailProcessChanges.addAll(mPendingProcessChanges);
3184            mPendingProcessChanges.clear();
3185            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3186        }
3187
3188        int i = mProcessObservers.beginBroadcast();
3189        while (i > 0) {
3190            i--;
3191            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3192            if (observer != null) {
3193                try {
3194                    for (int j=0; j<N; j++) {
3195                        ProcessChangeItem item = mActiveProcessChanges[j];
3196                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3197                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3198                                    + item.pid + " uid=" + item.uid + ": "
3199                                    + item.foregroundActivities);
3200                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3201                                    item.foregroundActivities);
3202                        }
3203                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3204                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3205                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3206                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3207                        }
3208                    }
3209                } catch (RemoteException e) {
3210                }
3211            }
3212        }
3213        mProcessObservers.finishBroadcast();
3214    }
3215
3216    private void dispatchProcessDied(int pid, int uid) {
3217        int i = mProcessObservers.beginBroadcast();
3218        while (i > 0) {
3219            i--;
3220            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3221            if (observer != null) {
3222                try {
3223                    observer.onProcessDied(pid, uid);
3224                } catch (RemoteException e) {
3225                }
3226            }
3227        }
3228        mProcessObservers.finishBroadcast();
3229    }
3230
3231    final void doPendingActivityLaunchesLocked(boolean doResume) {
3232        final int N = mPendingActivityLaunches.size();
3233        if (N <= 0) {
3234            return;
3235        }
3236        for (int i=0; i<N; i++) {
3237            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3238            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
3239                    doResume && i == (N-1), null);
3240        }
3241        mPendingActivityLaunches.clear();
3242    }
3243
3244    @Override
3245    public final int startActivity(IApplicationThread caller, String callingPackage,
3246            Intent intent, String resolvedType, IBinder resultTo,
3247            String resultWho, int requestCode, int startFlags,
3248            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3249        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3250                resultWho, requestCode,
3251                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3252    }
3253
3254    @Override
3255    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3256            Intent intent, String resolvedType, IBinder resultTo,
3257            String resultWho, int requestCode, int startFlags,
3258            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3259        enforceNotIsolatedCaller("startActivity");
3260        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3261                false, true, "startActivity", null);
3262        // TODO: Switch to user app stacks here.
3263        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3264                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3265                null, null, options, userId, null);
3266    }
3267
3268    @Override
3269    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3270            Intent intent, String resolvedType, IBinder resultTo,
3271            String resultWho, int requestCode, int startFlags, String profileFile,
3272            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3273        enforceNotIsolatedCaller("startActivityAndWait");
3274        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3275                false, true, "startActivityAndWait", null);
3276        WaitResult res = new WaitResult();
3277        // TODO: Switch to user app stacks here.
3278        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3279                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3280                res, null, options, UserHandle.getCallingUserId(), null);
3281        return res;
3282    }
3283
3284    @Override
3285    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3286            Intent intent, String resolvedType, IBinder resultTo,
3287            String resultWho, int requestCode, int startFlags, Configuration config,
3288            Bundle options, int userId) {
3289        enforceNotIsolatedCaller("startActivityWithConfig");
3290        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3291                false, true, "startActivityWithConfig", null);
3292        // TODO: Switch to user app stacks here.
3293        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3294                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3295                null, null, null, config, options, userId, null);
3296        return ret;
3297    }
3298
3299    @Override
3300    public int startActivityIntentSender(IApplicationThread caller,
3301            IntentSender intent, Intent fillInIntent, String resolvedType,
3302            IBinder resultTo, String resultWho, int requestCode,
3303            int flagsMask, int flagsValues, Bundle options) {
3304        enforceNotIsolatedCaller("startActivityIntentSender");
3305        // Refuse possible leaked file descriptors
3306        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3307            throw new IllegalArgumentException("File descriptors passed in Intent");
3308        }
3309
3310        IIntentSender sender = intent.getTarget();
3311        if (!(sender instanceof PendingIntentRecord)) {
3312            throw new IllegalArgumentException("Bad PendingIntent object");
3313        }
3314
3315        PendingIntentRecord pir = (PendingIntentRecord)sender;
3316
3317        synchronized (this) {
3318            // If this is coming from the currently resumed activity, it is
3319            // effectively saying that app switches are allowed at this point.
3320            final ActivityStack stack = getFocusedStack();
3321            if (stack.mResumedActivity != null &&
3322                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3323                mAppSwitchesAllowedTime = 0;
3324            }
3325        }
3326        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3327                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3328        return ret;
3329    }
3330
3331    @Override
3332    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3333            Intent intent, String resolvedType, IVoiceInteractionSession session,
3334            IVoiceInteractor interactor, int startFlags, String profileFile,
3335            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3336        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3337                != PackageManager.PERMISSION_GRANTED) {
3338            String msg = "Permission Denial: startVoiceActivity() from pid="
3339                    + Binder.getCallingPid()
3340                    + ", uid=" + Binder.getCallingUid()
3341                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3342            Slog.w(TAG, msg);
3343            throw new SecurityException(msg);
3344        }
3345        if (session == null || interactor == null) {
3346            throw new NullPointerException("null session or interactor");
3347        }
3348        userId = handleIncomingUser(callingPid, callingUid, userId,
3349                false, true, "startVoiceActivity", null);
3350        // TODO: Switch to user app stacks here.
3351        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3352                resolvedType, session, interactor, null, null, 0, startFlags,
3353                profileFile, profileFd, null, null, options, userId, null);
3354    }
3355
3356    @Override
3357    public boolean startNextMatchingActivity(IBinder callingActivity,
3358            Intent intent, Bundle options) {
3359        // Refuse possible leaked file descriptors
3360        if (intent != null && intent.hasFileDescriptors() == true) {
3361            throw new IllegalArgumentException("File descriptors passed in Intent");
3362        }
3363
3364        synchronized (this) {
3365            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3366            if (r == null) {
3367                ActivityOptions.abort(options);
3368                return false;
3369            }
3370            if (r.app == null || r.app.thread == null) {
3371                // The caller is not running...  d'oh!
3372                ActivityOptions.abort(options);
3373                return false;
3374            }
3375            intent = new Intent(intent);
3376            // The caller is not allowed to change the data.
3377            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3378            // And we are resetting to find the next component...
3379            intent.setComponent(null);
3380
3381            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3382
3383            ActivityInfo aInfo = null;
3384            try {
3385                List<ResolveInfo> resolves =
3386                    AppGlobals.getPackageManager().queryIntentActivities(
3387                            intent, r.resolvedType,
3388                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3389                            UserHandle.getCallingUserId());
3390
3391                // Look for the original activity in the list...
3392                final int N = resolves != null ? resolves.size() : 0;
3393                for (int i=0; i<N; i++) {
3394                    ResolveInfo rInfo = resolves.get(i);
3395                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3396                            && rInfo.activityInfo.name.equals(r.info.name)) {
3397                        // We found the current one...  the next matching is
3398                        // after it.
3399                        i++;
3400                        if (i<N) {
3401                            aInfo = resolves.get(i).activityInfo;
3402                        }
3403                        if (debug) {
3404                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3405                                    + "/" + r.info.name);
3406                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3407                                    + "/" + aInfo.name);
3408                        }
3409                        break;
3410                    }
3411                }
3412            } catch (RemoteException e) {
3413            }
3414
3415            if (aInfo == null) {
3416                // Nobody who is next!
3417                ActivityOptions.abort(options);
3418                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3419                return false;
3420            }
3421
3422            intent.setComponent(new ComponentName(
3423                    aInfo.applicationInfo.packageName, aInfo.name));
3424            intent.setFlags(intent.getFlags()&~(
3425                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3426                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3427                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3428                    Intent.FLAG_ACTIVITY_NEW_TASK));
3429
3430            // Okay now we need to start the new activity, replacing the
3431            // currently running activity.  This is a little tricky because
3432            // we want to start the new one as if the current one is finished,
3433            // but not finish the current one first so that there is no flicker.
3434            // And thus...
3435            final boolean wasFinishing = r.finishing;
3436            r.finishing = true;
3437
3438            // Propagate reply information over to the new activity.
3439            final ActivityRecord resultTo = r.resultTo;
3440            final String resultWho = r.resultWho;
3441            final int requestCode = r.requestCode;
3442            r.resultTo = null;
3443            if (resultTo != null) {
3444                resultTo.removeResultsLocked(r, resultWho, requestCode);
3445            }
3446
3447            final long origId = Binder.clearCallingIdentity();
3448            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3449                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3450                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3451                    options, false, null, null);
3452            Binder.restoreCallingIdentity(origId);
3453
3454            r.finishing = wasFinishing;
3455            if (res != ActivityManager.START_SUCCESS) {
3456                return false;
3457            }
3458            return true;
3459        }
3460    }
3461
3462    final int startActivityInPackage(int uid, String callingPackage,
3463            Intent intent, String resolvedType, IBinder resultTo,
3464            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3465                    IActivityContainer container) {
3466
3467        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3468                false, true, "startActivityInPackage", null);
3469
3470        // TODO: Switch to user app stacks here.
3471        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3472                null, null, resultTo, resultWho, requestCode, startFlags,
3473                null, null, null, null, options, userId, container);
3474        return ret;
3475    }
3476
3477    @Override
3478    public final int startActivities(IApplicationThread caller, String callingPackage,
3479            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3480            int userId) {
3481        enforceNotIsolatedCaller("startActivities");
3482        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3483                false, true, "startActivity", null);
3484        // TODO: Switch to user app stacks here.
3485        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3486                resolvedTypes, resultTo, options, userId);
3487        return ret;
3488    }
3489
3490    final int startActivitiesInPackage(int uid, String callingPackage,
3491            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3492            Bundle options, int userId) {
3493
3494        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3495                false, true, "startActivityInPackage", null);
3496        // TODO: Switch to user app stacks here.
3497        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3498                resultTo, options, userId);
3499        return ret;
3500    }
3501
3502    final void addRecentTaskLocked(TaskRecord task) {
3503        int N = mRecentTasks.size();
3504        // Quick case: check if the top-most recent task is the same.
3505        if (N > 0 && mRecentTasks.get(0) == task) {
3506            return;
3507        }
3508        // Another quick case: never add voice sessions.
3509        if (task.voiceSession != null) {
3510            return;
3511        }
3512        // Remove any existing entries that are the same kind of task.
3513        final Intent intent = task.intent;
3514        final boolean document = intent != null && intent.isDocument();
3515        for (int i=0; i<N; i++) {
3516            TaskRecord tr = mRecentTasks.get(i);
3517            if (task != tr) {
3518                if (task.userId != tr.userId) {
3519                    continue;
3520                }
3521                final Intent trIntent = tr.intent;
3522                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3523                    (intent == null || !intent.filterEquals(trIntent))) {
3524                    continue;
3525                }
3526                if (document || trIntent != null && trIntent.isDocument()) {
3527                    // Document tasks do not match other tasks.
3528                    continue;
3529                }
3530            }
3531
3532            // Either task and tr are the same or, their affinities match or their intents match
3533            // and neither of them is a document.
3534            tr.disposeThumbnail();
3535            mRecentTasks.remove(i);
3536            i--;
3537            N--;
3538            if (task.intent == null) {
3539                // If the new recent task we are adding is not fully
3540                // specified, then replace it with the existing recent task.
3541                task = tr;
3542            }
3543        }
3544        if (N >= MAX_RECENT_TASKS) {
3545            mRecentTasks.remove(N-1).disposeThumbnail();
3546        }
3547        mRecentTasks.add(0, task);
3548    }
3549
3550    @Override
3551    public void reportActivityFullyDrawn(IBinder token) {
3552        synchronized (this) {
3553            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3554            if (r == null) {
3555                return;
3556            }
3557            r.reportFullyDrawnLocked();
3558        }
3559    }
3560
3561    @Override
3562    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3563        synchronized (this) {
3564            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3565            if (r == null) {
3566                return;
3567            }
3568            final long origId = Binder.clearCallingIdentity();
3569            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3570            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3571                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3572            if (config != null) {
3573                r.frozenBeforeDestroy = true;
3574                if (!updateConfigurationLocked(config, r, false, false)) {
3575                    mStackSupervisor.resumeTopActivitiesLocked();
3576                }
3577            }
3578            Binder.restoreCallingIdentity(origId);
3579        }
3580    }
3581
3582    @Override
3583    public int getRequestedOrientation(IBinder token) {
3584        synchronized (this) {
3585            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3586            if (r == null) {
3587                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3588            }
3589            return mWindowManager.getAppOrientation(r.appToken);
3590        }
3591    }
3592
3593    /**
3594     * This is the internal entry point for handling Activity.finish().
3595     *
3596     * @param token The Binder token referencing the Activity we want to finish.
3597     * @param resultCode Result code, if any, from this Activity.
3598     * @param resultData Result data (Intent), if any, from this Activity.
3599     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3600     *            the root Activity in the task.
3601     *
3602     * @return Returns true if the activity successfully finished, or false if it is still running.
3603     */
3604    @Override
3605    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3606            boolean finishTask) {
3607        // Refuse possible leaked file descriptors
3608        if (resultData != null && resultData.hasFileDescriptors() == true) {
3609            throw new IllegalArgumentException("File descriptors passed in Intent");
3610        }
3611
3612        synchronized(this) {
3613            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3614            if (r == null) {
3615                return true;
3616            }
3617            // Keep track of the root activity of the task before we finish it
3618            TaskRecord tr = r.task;
3619            ActivityRecord rootR = tr.getRootActivity();
3620            if (mController != null) {
3621                // Find the first activity that is not finishing.
3622                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3623                if (next != null) {
3624                    // ask watcher if this is allowed
3625                    boolean resumeOK = true;
3626                    try {
3627                        resumeOK = mController.activityResuming(next.packageName);
3628                    } catch (RemoteException e) {
3629                        mController = null;
3630                        Watchdog.getInstance().setActivityController(null);
3631                    }
3632
3633                    if (!resumeOK) {
3634                        return false;
3635                    }
3636                }
3637            }
3638            final long origId = Binder.clearCallingIdentity();
3639            try {
3640                boolean res;
3641                if (finishTask && r == rootR) {
3642                    // If requested, remove the task that is associated to this activity only if it
3643                    // was the root activity in the task.  The result code and data is ignored because
3644                    // we don't support returning them across task boundaries.
3645                    res = removeTaskByIdLocked(tr.taskId, 0);
3646                } else {
3647                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3648                            resultData, "app-request", true);
3649                }
3650                return res;
3651            } finally {
3652                Binder.restoreCallingIdentity(origId);
3653            }
3654        }
3655    }
3656
3657    @Override
3658    public final void finishHeavyWeightApp() {
3659        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3660                != PackageManager.PERMISSION_GRANTED) {
3661            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3662                    + Binder.getCallingPid()
3663                    + ", uid=" + Binder.getCallingUid()
3664                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3665            Slog.w(TAG, msg);
3666            throw new SecurityException(msg);
3667        }
3668
3669        synchronized(this) {
3670            if (mHeavyWeightProcess == null) {
3671                return;
3672            }
3673
3674            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3675                    mHeavyWeightProcess.activities);
3676            for (int i=0; i<activities.size(); i++) {
3677                ActivityRecord r = activities.get(i);
3678                if (!r.finishing) {
3679                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3680                            null, "finish-heavy", true);
3681                }
3682            }
3683
3684            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3685                    mHeavyWeightProcess.userId, 0));
3686            mHeavyWeightProcess = null;
3687        }
3688    }
3689
3690    @Override
3691    public void crashApplication(int uid, int initialPid, String packageName,
3692            String message) {
3693        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3694                != PackageManager.PERMISSION_GRANTED) {
3695            String msg = "Permission Denial: crashApplication() from pid="
3696                    + Binder.getCallingPid()
3697                    + ", uid=" + Binder.getCallingUid()
3698                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3699            Slog.w(TAG, msg);
3700            throw new SecurityException(msg);
3701        }
3702
3703        synchronized(this) {
3704            ProcessRecord proc = null;
3705
3706            // Figure out which process to kill.  We don't trust that initialPid
3707            // still has any relation to current pids, so must scan through the
3708            // list.
3709            synchronized (mPidsSelfLocked) {
3710                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3711                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3712                    if (p.uid != uid) {
3713                        continue;
3714                    }
3715                    if (p.pid == initialPid) {
3716                        proc = p;
3717                        break;
3718                    }
3719                    if (p.pkgList.containsKey(packageName)) {
3720                        proc = p;
3721                    }
3722                }
3723            }
3724
3725            if (proc == null) {
3726                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3727                        + " initialPid=" + initialPid
3728                        + " packageName=" + packageName);
3729                return;
3730            }
3731
3732            if (proc.thread != null) {
3733                if (proc.pid == Process.myPid()) {
3734                    Log.w(TAG, "crashApplication: trying to crash self!");
3735                    return;
3736                }
3737                long ident = Binder.clearCallingIdentity();
3738                try {
3739                    proc.thread.scheduleCrash(message);
3740                } catch (RemoteException e) {
3741                }
3742                Binder.restoreCallingIdentity(ident);
3743            }
3744        }
3745    }
3746
3747    @Override
3748    public final void finishSubActivity(IBinder token, String resultWho,
3749            int requestCode) {
3750        synchronized(this) {
3751            final long origId = Binder.clearCallingIdentity();
3752            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3753            if (r != null) {
3754                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3755            }
3756            Binder.restoreCallingIdentity(origId);
3757        }
3758    }
3759
3760    @Override
3761    public boolean finishActivityAffinity(IBinder token) {
3762        synchronized(this) {
3763            final long origId = Binder.clearCallingIdentity();
3764            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3765            boolean res = false;
3766            if (r != null) {
3767                res = r.task.stack.finishActivityAffinityLocked(r);
3768            }
3769            Binder.restoreCallingIdentity(origId);
3770            return res;
3771        }
3772    }
3773
3774    @Override
3775    public boolean willActivityBeVisible(IBinder token) {
3776        synchronized(this) {
3777            ActivityStack stack = ActivityRecord.getStackLocked(token);
3778            if (stack != null) {
3779                return stack.willActivityBeVisibleLocked(token);
3780            }
3781            return false;
3782        }
3783    }
3784
3785    @Override
3786    public void overridePendingTransition(IBinder token, String packageName,
3787            int enterAnim, int exitAnim) {
3788        synchronized(this) {
3789            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3790            if (self == null) {
3791                return;
3792            }
3793
3794            final long origId = Binder.clearCallingIdentity();
3795
3796            if (self.state == ActivityState.RESUMED
3797                    || self.state == ActivityState.PAUSING) {
3798                mWindowManager.overridePendingAppTransition(packageName,
3799                        enterAnim, exitAnim, null);
3800            }
3801
3802            Binder.restoreCallingIdentity(origId);
3803        }
3804    }
3805
3806    /**
3807     * Main function for removing an existing process from the activity manager
3808     * as a result of that process going away.  Clears out all connections
3809     * to the process.
3810     */
3811    private final void handleAppDiedLocked(ProcessRecord app,
3812            boolean restarting, boolean allowRestart) {
3813        int pid = app.pid;
3814        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3815        if (!restarting) {
3816            removeLruProcessLocked(app);
3817            if (pid > 0) {
3818                ProcessList.remove(pid);
3819            }
3820        }
3821
3822        if (mProfileProc == app) {
3823            clearProfilerLocked();
3824        }
3825
3826        // Remove this application's activities from active lists.
3827        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3828
3829        app.activities.clear();
3830
3831        if (app.instrumentationClass != null) {
3832            Slog.w(TAG, "Crash of app " + app.processName
3833                  + " running instrumentation " + app.instrumentationClass);
3834            Bundle info = new Bundle();
3835            info.putString("shortMsg", "Process crashed.");
3836            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3837        }
3838
3839        if (!restarting) {
3840            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3841                // If there was nothing to resume, and we are not already
3842                // restarting this process, but there is a visible activity that
3843                // is hosted by the process...  then make sure all visible
3844                // activities are running, taking care of restarting this
3845                // process.
3846                if (hasVisibleActivities) {
3847                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3848                }
3849            }
3850        }
3851    }
3852
3853    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3854        IBinder threadBinder = thread.asBinder();
3855        // Find the application record.
3856        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3857            ProcessRecord rec = mLruProcesses.get(i);
3858            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3859                return i;
3860            }
3861        }
3862        return -1;
3863    }
3864
3865    final ProcessRecord getRecordForAppLocked(
3866            IApplicationThread thread) {
3867        if (thread == null) {
3868            return null;
3869        }
3870
3871        int appIndex = getLRURecordIndexForAppLocked(thread);
3872        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3873    }
3874
3875    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3876        // If there are no longer any background processes running,
3877        // and the app that died was not running instrumentation,
3878        // then tell everyone we are now low on memory.
3879        boolean haveBg = false;
3880        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3881            ProcessRecord rec = mLruProcesses.get(i);
3882            if (rec.thread != null
3883                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3884                haveBg = true;
3885                break;
3886            }
3887        }
3888
3889        if (!haveBg) {
3890            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3891            if (doReport) {
3892                long now = SystemClock.uptimeMillis();
3893                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3894                    doReport = false;
3895                } else {
3896                    mLastMemUsageReportTime = now;
3897                }
3898            }
3899            final ArrayList<ProcessMemInfo> memInfos
3900                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3901            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3902            long now = SystemClock.uptimeMillis();
3903            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3904                ProcessRecord rec = mLruProcesses.get(i);
3905                if (rec == dyingProc || rec.thread == null) {
3906                    continue;
3907                }
3908                if (doReport) {
3909                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3910                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3911                }
3912                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3913                    // The low memory report is overriding any current
3914                    // state for a GC request.  Make sure to do
3915                    // heavy/important/visible/foreground processes first.
3916                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3917                        rec.lastRequestedGc = 0;
3918                    } else {
3919                        rec.lastRequestedGc = rec.lastLowMemory;
3920                    }
3921                    rec.reportLowMemory = true;
3922                    rec.lastLowMemory = now;
3923                    mProcessesToGc.remove(rec);
3924                    addProcessToGcListLocked(rec);
3925                }
3926            }
3927            if (doReport) {
3928                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3929                mHandler.sendMessage(msg);
3930            }
3931            scheduleAppGcsLocked();
3932        }
3933    }
3934
3935    final void appDiedLocked(ProcessRecord app, int pid,
3936            IApplicationThread thread) {
3937
3938        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3939        synchronized (stats) {
3940            stats.noteProcessDiedLocked(app.info.uid, pid);
3941        }
3942
3943        // Clean up already done if the process has been re-started.
3944        if (app.pid == pid && app.thread != null &&
3945                app.thread.asBinder() == thread.asBinder()) {
3946            boolean doLowMem = app.instrumentationClass == null;
3947            boolean doOomAdj = doLowMem;
3948            if (!app.killedByAm) {
3949                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3950                        + ") has died.");
3951                mAllowLowerMemLevel = true;
3952            } else {
3953                // Note that we always want to do oom adj to update our state with the
3954                // new number of procs.
3955                mAllowLowerMemLevel = false;
3956                doLowMem = false;
3957            }
3958            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3959            if (DEBUG_CLEANUP) Slog.v(
3960                TAG, "Dying app: " + app + ", pid: " + pid
3961                + ", thread: " + thread.asBinder());
3962            handleAppDiedLocked(app, false, true);
3963
3964            if (doOomAdj) {
3965                updateOomAdjLocked();
3966            }
3967            if (doLowMem) {
3968                doLowMemReportIfNeededLocked(app);
3969            }
3970        } else if (app.pid != pid) {
3971            // A new process has already been started.
3972            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3973                    + ") has died and restarted (pid " + app.pid + ").");
3974            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3975        } else if (DEBUG_PROCESSES) {
3976            Slog.d(TAG, "Received spurious death notification for thread "
3977                    + thread.asBinder());
3978        }
3979    }
3980
3981    /**
3982     * If a stack trace dump file is configured, dump process stack traces.
3983     * @param clearTraces causes the dump file to be erased prior to the new
3984     *    traces being written, if true; when false, the new traces will be
3985     *    appended to any existing file content.
3986     * @param firstPids of dalvik VM processes to dump stack traces for first
3987     * @param lastPids of dalvik VM processes to dump stack traces for last
3988     * @param nativeProcs optional list of native process names to dump stack crawls
3989     * @return file containing stack traces, or null if no dump file is configured
3990     */
3991    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3992            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3993        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3994        if (tracesPath == null || tracesPath.length() == 0) {
3995            return null;
3996        }
3997
3998        File tracesFile = new File(tracesPath);
3999        try {
4000            File tracesDir = tracesFile.getParentFile();
4001            if (!tracesDir.exists()) {
4002                tracesFile.mkdirs();
4003                if (!SELinux.restorecon(tracesDir)) {
4004                    return null;
4005                }
4006            }
4007            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4008
4009            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4010            tracesFile.createNewFile();
4011            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4012        } catch (IOException e) {
4013            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4014            return null;
4015        }
4016
4017        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4018        return tracesFile;
4019    }
4020
4021    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4022            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4023        // Use a FileObserver to detect when traces finish writing.
4024        // The order of traces is considered important to maintain for legibility.
4025        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4026            @Override
4027            public synchronized void onEvent(int event, String path) { notify(); }
4028        };
4029
4030        try {
4031            observer.startWatching();
4032
4033            // First collect all of the stacks of the most important pids.
4034            if (firstPids != null) {
4035                try {
4036                    int num = firstPids.size();
4037                    for (int i = 0; i < num; i++) {
4038                        synchronized (observer) {
4039                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4040                            observer.wait(200);  // Wait for write-close, give up after 200msec
4041                        }
4042                    }
4043                } catch (InterruptedException e) {
4044                    Log.wtf(TAG, e);
4045                }
4046            }
4047
4048            // Next collect the stacks of the native pids
4049            if (nativeProcs != null) {
4050                int[] pids = Process.getPidsForCommands(nativeProcs);
4051                if (pids != null) {
4052                    for (int pid : pids) {
4053                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4054                    }
4055                }
4056            }
4057
4058            // Lastly, measure CPU usage.
4059            if (processCpuTracker != null) {
4060                processCpuTracker.init();
4061                System.gc();
4062                processCpuTracker.update();
4063                try {
4064                    synchronized (processCpuTracker) {
4065                        processCpuTracker.wait(500); // measure over 1/2 second.
4066                    }
4067                } catch (InterruptedException e) {
4068                }
4069                processCpuTracker.update();
4070
4071                // We'll take the stack crawls of just the top apps using CPU.
4072                final int N = processCpuTracker.countWorkingStats();
4073                int numProcs = 0;
4074                for (int i=0; i<N && numProcs<5; i++) {
4075                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4076                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4077                        numProcs++;
4078                        try {
4079                            synchronized (observer) {
4080                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4081                                observer.wait(200);  // Wait for write-close, give up after 200msec
4082                            }
4083                        } catch (InterruptedException e) {
4084                            Log.wtf(TAG, e);
4085                        }
4086
4087                    }
4088                }
4089            }
4090        } finally {
4091            observer.stopWatching();
4092        }
4093    }
4094
4095    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4096        if (true || IS_USER_BUILD) {
4097            return;
4098        }
4099        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4100        if (tracesPath == null || tracesPath.length() == 0) {
4101            return;
4102        }
4103
4104        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4105        StrictMode.allowThreadDiskWrites();
4106        try {
4107            final File tracesFile = new File(tracesPath);
4108            final File tracesDir = tracesFile.getParentFile();
4109            final File tracesTmp = new File(tracesDir, "__tmp__");
4110            try {
4111                if (!tracesDir.exists()) {
4112                    tracesFile.mkdirs();
4113                    if (!SELinux.restorecon(tracesDir.getPath())) {
4114                        return;
4115                    }
4116                }
4117                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4118
4119                if (tracesFile.exists()) {
4120                    tracesTmp.delete();
4121                    tracesFile.renameTo(tracesTmp);
4122                }
4123                StringBuilder sb = new StringBuilder();
4124                Time tobj = new Time();
4125                tobj.set(System.currentTimeMillis());
4126                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4127                sb.append(": ");
4128                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4129                sb.append(" since ");
4130                sb.append(msg);
4131                FileOutputStream fos = new FileOutputStream(tracesFile);
4132                fos.write(sb.toString().getBytes());
4133                if (app == null) {
4134                    fos.write("\n*** No application process!".getBytes());
4135                }
4136                fos.close();
4137                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4138            } catch (IOException e) {
4139                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4140                return;
4141            }
4142
4143            if (app != null) {
4144                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4145                firstPids.add(app.pid);
4146                dumpStackTraces(tracesPath, firstPids, null, null, null);
4147            }
4148
4149            File lastTracesFile = null;
4150            File curTracesFile = null;
4151            for (int i=9; i>=0; i--) {
4152                String name = String.format(Locale.US, "slow%02d.txt", i);
4153                curTracesFile = new File(tracesDir, name);
4154                if (curTracesFile.exists()) {
4155                    if (lastTracesFile != null) {
4156                        curTracesFile.renameTo(lastTracesFile);
4157                    } else {
4158                        curTracesFile.delete();
4159                    }
4160                }
4161                lastTracesFile = curTracesFile;
4162            }
4163            tracesFile.renameTo(curTracesFile);
4164            if (tracesTmp.exists()) {
4165                tracesTmp.renameTo(tracesFile);
4166            }
4167        } finally {
4168            StrictMode.setThreadPolicy(oldPolicy);
4169        }
4170    }
4171
4172    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4173            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4174        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4175        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4176
4177        if (mController != null) {
4178            try {
4179                // 0 == continue, -1 = kill process immediately
4180                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4181                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
4182            } catch (RemoteException e) {
4183                mController = null;
4184                Watchdog.getInstance().setActivityController(null);
4185            }
4186        }
4187
4188        long anrTime = SystemClock.uptimeMillis();
4189        if (MONITOR_CPU_USAGE) {
4190            updateCpuStatsNow();
4191        }
4192
4193        synchronized (this) {
4194            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4195            if (mShuttingDown) {
4196                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4197                return;
4198            } else if (app.notResponding) {
4199                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4200                return;
4201            } else if (app.crashing) {
4202                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4203                return;
4204            }
4205
4206            // In case we come through here for the same app before completing
4207            // this one, mark as anring now so we will bail out.
4208            app.notResponding = true;
4209
4210            // Log the ANR to the event log.
4211            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4212                    app.processName, app.info.flags, annotation);
4213
4214            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4215            firstPids.add(app.pid);
4216
4217            int parentPid = app.pid;
4218            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4219            if (parentPid != app.pid) firstPids.add(parentPid);
4220
4221            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4222
4223            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4224                ProcessRecord r = mLruProcesses.get(i);
4225                if (r != null && r.thread != null) {
4226                    int pid = r.pid;
4227                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4228                        if (r.persistent) {
4229                            firstPids.add(pid);
4230                        } else {
4231                            lastPids.put(pid, Boolean.TRUE);
4232                        }
4233                    }
4234                }
4235            }
4236        }
4237
4238        // Log the ANR to the main log.
4239        StringBuilder info = new StringBuilder();
4240        info.setLength(0);
4241        info.append("ANR in ").append(app.processName);
4242        if (activity != null && activity.shortComponentName != null) {
4243            info.append(" (").append(activity.shortComponentName).append(")");
4244        }
4245        info.append("\n");
4246        info.append("PID: ").append(app.pid).append("\n");
4247        if (annotation != null) {
4248            info.append("Reason: ").append(annotation).append("\n");
4249        }
4250        if (parent != null && parent != activity) {
4251            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4252        }
4253
4254        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4255
4256        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4257                NATIVE_STACKS_OF_INTEREST);
4258
4259        String cpuInfo = null;
4260        if (MONITOR_CPU_USAGE) {
4261            updateCpuStatsNow();
4262            synchronized (mProcessCpuThread) {
4263                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4264            }
4265            info.append(processCpuTracker.printCurrentLoad());
4266            info.append(cpuInfo);
4267        }
4268
4269        info.append(processCpuTracker.printCurrentState(anrTime));
4270
4271        Slog.e(TAG, info.toString());
4272        if (tracesFile == null) {
4273            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4274            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4275        }
4276
4277        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4278                cpuInfo, tracesFile, null);
4279
4280        if (mController != null) {
4281            try {
4282                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4283                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4284                if (res != 0) {
4285                    if (res < 0 && app.pid != MY_PID) {
4286                        Process.killProcess(app.pid);
4287                    } else {
4288                        synchronized (this) {
4289                            mServices.scheduleServiceTimeoutLocked(app);
4290                        }
4291                    }
4292                    return;
4293                }
4294            } catch (RemoteException e) {
4295                mController = null;
4296                Watchdog.getInstance().setActivityController(null);
4297            }
4298        }
4299
4300        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4301        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4302                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4303
4304        synchronized (this) {
4305            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4306                killUnneededProcessLocked(app, "background ANR");
4307                return;
4308            }
4309
4310            // Set the app's notResponding state, and look up the errorReportReceiver
4311            makeAppNotRespondingLocked(app,
4312                    activity != null ? activity.shortComponentName : null,
4313                    annotation != null ? "ANR " + annotation : "ANR",
4314                    info.toString());
4315
4316            // Bring up the infamous App Not Responding dialog
4317            Message msg = Message.obtain();
4318            HashMap<String, Object> map = new HashMap<String, Object>();
4319            msg.what = SHOW_NOT_RESPONDING_MSG;
4320            msg.obj = map;
4321            msg.arg1 = aboveSystem ? 1 : 0;
4322            map.put("app", app);
4323            if (activity != null) {
4324                map.put("activity", activity);
4325            }
4326
4327            mHandler.sendMessage(msg);
4328        }
4329    }
4330
4331    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4332        if (!mLaunchWarningShown) {
4333            mLaunchWarningShown = true;
4334            mHandler.post(new Runnable() {
4335                @Override
4336                public void run() {
4337                    synchronized (ActivityManagerService.this) {
4338                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4339                        d.show();
4340                        mHandler.postDelayed(new Runnable() {
4341                            @Override
4342                            public void run() {
4343                                synchronized (ActivityManagerService.this) {
4344                                    d.dismiss();
4345                                    mLaunchWarningShown = false;
4346                                }
4347                            }
4348                        }, 4000);
4349                    }
4350                }
4351            });
4352        }
4353    }
4354
4355    @Override
4356    public boolean clearApplicationUserData(final String packageName,
4357            final IPackageDataObserver observer, int userId) {
4358        enforceNotIsolatedCaller("clearApplicationUserData");
4359        int uid = Binder.getCallingUid();
4360        int pid = Binder.getCallingPid();
4361        userId = handleIncomingUser(pid, uid,
4362                userId, false, true, "clearApplicationUserData", null);
4363        long callingId = Binder.clearCallingIdentity();
4364        try {
4365            IPackageManager pm = AppGlobals.getPackageManager();
4366            int pkgUid = -1;
4367            synchronized(this) {
4368                try {
4369                    pkgUid = pm.getPackageUid(packageName, userId);
4370                } catch (RemoteException e) {
4371                }
4372                if (pkgUid == -1) {
4373                    Slog.w(TAG, "Invalid packageName: " + packageName);
4374                    if (observer != null) {
4375                        try {
4376                            observer.onRemoveCompleted(packageName, false);
4377                        } catch (RemoteException e) {
4378                            Slog.i(TAG, "Observer no longer exists.");
4379                        }
4380                    }
4381                    return false;
4382                }
4383                if (uid == pkgUid || checkComponentPermission(
4384                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4385                        pid, uid, -1, true)
4386                        == PackageManager.PERMISSION_GRANTED) {
4387                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4388                } else {
4389                    throw new SecurityException("PID " + pid + " does not have permission "
4390                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4391                                    + " of package " + packageName);
4392                }
4393            }
4394
4395            try {
4396                // Clear application user data
4397                pm.clearApplicationUserData(packageName, observer, userId);
4398
4399                // Remove all permissions granted from/to this package
4400                removeUriPermissionsForPackageLocked(packageName, userId, true);
4401
4402                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4403                        Uri.fromParts("package", packageName, null));
4404                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4405                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4406                        null, null, 0, null, null, null, false, false, userId);
4407            } catch (RemoteException e) {
4408            }
4409        } finally {
4410            Binder.restoreCallingIdentity(callingId);
4411        }
4412        return true;
4413    }
4414
4415    @Override
4416    public void killBackgroundProcesses(final String packageName, int userId) {
4417        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4418                != PackageManager.PERMISSION_GRANTED &&
4419                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4420                        != PackageManager.PERMISSION_GRANTED) {
4421            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4422                    + Binder.getCallingPid()
4423                    + ", uid=" + Binder.getCallingUid()
4424                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4425            Slog.w(TAG, msg);
4426            throw new SecurityException(msg);
4427        }
4428
4429        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4430                userId, true, true, "killBackgroundProcesses", null);
4431        long callingId = Binder.clearCallingIdentity();
4432        try {
4433            IPackageManager pm = AppGlobals.getPackageManager();
4434            synchronized(this) {
4435                int appId = -1;
4436                try {
4437                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4438                } catch (RemoteException e) {
4439                }
4440                if (appId == -1) {
4441                    Slog.w(TAG, "Invalid packageName: " + packageName);
4442                    return;
4443                }
4444                killPackageProcessesLocked(packageName, appId, userId,
4445                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4446            }
4447        } finally {
4448            Binder.restoreCallingIdentity(callingId);
4449        }
4450    }
4451
4452    @Override
4453    public void killAllBackgroundProcesses() {
4454        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4455                != PackageManager.PERMISSION_GRANTED) {
4456            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4457                    + Binder.getCallingPid()
4458                    + ", uid=" + Binder.getCallingUid()
4459                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4460            Slog.w(TAG, msg);
4461            throw new SecurityException(msg);
4462        }
4463
4464        long callingId = Binder.clearCallingIdentity();
4465        try {
4466            synchronized(this) {
4467                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4468                final int NP = mProcessNames.getMap().size();
4469                for (int ip=0; ip<NP; ip++) {
4470                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4471                    final int NA = apps.size();
4472                    for (int ia=0; ia<NA; ia++) {
4473                        ProcessRecord app = apps.valueAt(ia);
4474                        if (app.persistent) {
4475                            // we don't kill persistent processes
4476                            continue;
4477                        }
4478                        if (app.removed) {
4479                            procs.add(app);
4480                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4481                            app.removed = true;
4482                            procs.add(app);
4483                        }
4484                    }
4485                }
4486
4487                int N = procs.size();
4488                for (int i=0; i<N; i++) {
4489                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4490                }
4491                mAllowLowerMemLevel = true;
4492                updateOomAdjLocked();
4493                doLowMemReportIfNeededLocked(null);
4494            }
4495        } finally {
4496            Binder.restoreCallingIdentity(callingId);
4497        }
4498    }
4499
4500    @Override
4501    public void forceStopPackage(final String packageName, int userId) {
4502        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4503                != PackageManager.PERMISSION_GRANTED) {
4504            String msg = "Permission Denial: forceStopPackage() from pid="
4505                    + Binder.getCallingPid()
4506                    + ", uid=" + Binder.getCallingUid()
4507                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4508            Slog.w(TAG, msg);
4509            throw new SecurityException(msg);
4510        }
4511        final int callingPid = Binder.getCallingPid();
4512        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4513                userId, true, true, "forceStopPackage", null);
4514        long callingId = Binder.clearCallingIdentity();
4515        try {
4516            IPackageManager pm = AppGlobals.getPackageManager();
4517            synchronized(this) {
4518                int[] users = userId == UserHandle.USER_ALL
4519                        ? getUsersLocked() : new int[] { userId };
4520                for (int user : users) {
4521                    int pkgUid = -1;
4522                    try {
4523                        pkgUid = pm.getPackageUid(packageName, user);
4524                    } catch (RemoteException e) {
4525                    }
4526                    if (pkgUid == -1) {
4527                        Slog.w(TAG, "Invalid packageName: " + packageName);
4528                        continue;
4529                    }
4530                    try {
4531                        pm.setPackageStoppedState(packageName, true, user);
4532                    } catch (RemoteException e) {
4533                    } catch (IllegalArgumentException e) {
4534                        Slog.w(TAG, "Failed trying to unstop package "
4535                                + packageName + ": " + e);
4536                    }
4537                    if (isUserRunningLocked(user, false)) {
4538                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4539                    }
4540                }
4541            }
4542        } finally {
4543            Binder.restoreCallingIdentity(callingId);
4544        }
4545    }
4546
4547    /*
4548     * The pkg name and app id have to be specified.
4549     */
4550    @Override
4551    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4552        if (pkg == null) {
4553            return;
4554        }
4555        // Make sure the uid is valid.
4556        if (appid < 0) {
4557            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4558            return;
4559        }
4560        int callerUid = Binder.getCallingUid();
4561        // Only the system server can kill an application
4562        if (callerUid == Process.SYSTEM_UID) {
4563            // Post an aysnc message to kill the application
4564            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4565            msg.arg1 = appid;
4566            msg.arg2 = 0;
4567            Bundle bundle = new Bundle();
4568            bundle.putString("pkg", pkg);
4569            bundle.putString("reason", reason);
4570            msg.obj = bundle;
4571            mHandler.sendMessage(msg);
4572        } else {
4573            throw new SecurityException(callerUid + " cannot kill pkg: " +
4574                    pkg);
4575        }
4576    }
4577
4578    @Override
4579    public void closeSystemDialogs(String reason) {
4580        enforceNotIsolatedCaller("closeSystemDialogs");
4581
4582        final int pid = Binder.getCallingPid();
4583        final int uid = Binder.getCallingUid();
4584        final long origId = Binder.clearCallingIdentity();
4585        try {
4586            synchronized (this) {
4587                // Only allow this from foreground processes, so that background
4588                // applications can't abuse it to prevent system UI from being shown.
4589                if (uid >= Process.FIRST_APPLICATION_UID) {
4590                    ProcessRecord proc;
4591                    synchronized (mPidsSelfLocked) {
4592                        proc = mPidsSelfLocked.get(pid);
4593                    }
4594                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4595                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4596                                + " from background process " + proc);
4597                        return;
4598                    }
4599                }
4600                closeSystemDialogsLocked(reason);
4601            }
4602        } finally {
4603            Binder.restoreCallingIdentity(origId);
4604        }
4605    }
4606
4607    void closeSystemDialogsLocked(String reason) {
4608        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4609        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4610                | Intent.FLAG_RECEIVER_FOREGROUND);
4611        if (reason != null) {
4612            intent.putExtra("reason", reason);
4613        }
4614        mWindowManager.closeSystemDialogs(reason);
4615
4616        mStackSupervisor.closeSystemDialogsLocked();
4617
4618        broadcastIntentLocked(null, null, intent, null,
4619                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4620                Process.SYSTEM_UID, UserHandle.USER_ALL);
4621    }
4622
4623    @Override
4624    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4625        enforceNotIsolatedCaller("getProcessMemoryInfo");
4626        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4627        for (int i=pids.length-1; i>=0; i--) {
4628            ProcessRecord proc;
4629            int oomAdj;
4630            synchronized (this) {
4631                synchronized (mPidsSelfLocked) {
4632                    proc = mPidsSelfLocked.get(pids[i]);
4633                    oomAdj = proc != null ? proc.setAdj : 0;
4634                }
4635            }
4636            infos[i] = new Debug.MemoryInfo();
4637            Debug.getMemoryInfo(pids[i], infos[i]);
4638            if (proc != null) {
4639                synchronized (this) {
4640                    if (proc.thread != null && proc.setAdj == oomAdj) {
4641                        // Record this for posterity if the process has been stable.
4642                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4643                                infos[i].getTotalUss(), false, proc.pkgList);
4644                    }
4645                }
4646            }
4647        }
4648        return infos;
4649    }
4650
4651    @Override
4652    public long[] getProcessPss(int[] pids) {
4653        enforceNotIsolatedCaller("getProcessPss");
4654        long[] pss = new long[pids.length];
4655        for (int i=pids.length-1; i>=0; i--) {
4656            ProcessRecord proc;
4657            int oomAdj;
4658            synchronized (this) {
4659                synchronized (mPidsSelfLocked) {
4660                    proc = mPidsSelfLocked.get(pids[i]);
4661                    oomAdj = proc != null ? proc.setAdj : 0;
4662                }
4663            }
4664            long[] tmpUss = new long[1];
4665            pss[i] = Debug.getPss(pids[i], tmpUss);
4666            if (proc != null) {
4667                synchronized (this) {
4668                    if (proc.thread != null && proc.setAdj == oomAdj) {
4669                        // Record this for posterity if the process has been stable.
4670                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4671                    }
4672                }
4673            }
4674        }
4675        return pss;
4676    }
4677
4678    @Override
4679    public void killApplicationProcess(String processName, int uid) {
4680        if (processName == null) {
4681            return;
4682        }
4683
4684        int callerUid = Binder.getCallingUid();
4685        // Only the system server can kill an application
4686        if (callerUid == Process.SYSTEM_UID) {
4687            synchronized (this) {
4688                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4689                if (app != null && app.thread != null) {
4690                    try {
4691                        app.thread.scheduleSuicide();
4692                    } catch (RemoteException e) {
4693                        // If the other end already died, then our work here is done.
4694                    }
4695                } else {
4696                    Slog.w(TAG, "Process/uid not found attempting kill of "
4697                            + processName + " / " + uid);
4698                }
4699            }
4700        } else {
4701            throw new SecurityException(callerUid + " cannot kill app process: " +
4702                    processName);
4703        }
4704    }
4705
4706    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4707        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4708                false, true, false, false, UserHandle.getUserId(uid), reason);
4709        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4710                Uri.fromParts("package", packageName, null));
4711        if (!mProcessesReady) {
4712            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4713                    | Intent.FLAG_RECEIVER_FOREGROUND);
4714        }
4715        intent.putExtra(Intent.EXTRA_UID, uid);
4716        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4717        broadcastIntentLocked(null, null, intent,
4718                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4719                false, false,
4720                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4721    }
4722
4723    private void forceStopUserLocked(int userId, String reason) {
4724        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4725        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4726        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4727                | Intent.FLAG_RECEIVER_FOREGROUND);
4728        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4729        broadcastIntentLocked(null, null, intent,
4730                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4731                false, false,
4732                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4733    }
4734
4735    private final boolean killPackageProcessesLocked(String packageName, int appId,
4736            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4737            boolean doit, boolean evenPersistent, String reason) {
4738        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4739
4740        // Remove all processes this package may have touched: all with the
4741        // same UID (except for the system or root user), and all whose name
4742        // matches the package name.
4743        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4744        final int NP = mProcessNames.getMap().size();
4745        for (int ip=0; ip<NP; ip++) {
4746            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4747            final int NA = apps.size();
4748            for (int ia=0; ia<NA; ia++) {
4749                ProcessRecord app = apps.valueAt(ia);
4750                if (app.persistent && !evenPersistent) {
4751                    // we don't kill persistent processes
4752                    continue;
4753                }
4754                if (app.removed) {
4755                    if (doit) {
4756                        procs.add(app);
4757                    }
4758                    continue;
4759                }
4760
4761                // Skip process if it doesn't meet our oom adj requirement.
4762                if (app.setAdj < minOomAdj) {
4763                    continue;
4764                }
4765
4766                // If no package is specified, we call all processes under the
4767                // give user id.
4768                if (packageName == null) {
4769                    if (app.userId != userId) {
4770                        continue;
4771                    }
4772                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4773                        continue;
4774                    }
4775                // Package has been specified, we want to hit all processes
4776                // that match it.  We need to qualify this by the processes
4777                // that are running under the specified app and user ID.
4778                } else {
4779                    if (UserHandle.getAppId(app.uid) != appId) {
4780                        continue;
4781                    }
4782                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4783                        continue;
4784                    }
4785                    if (!app.pkgList.containsKey(packageName)) {
4786                        continue;
4787                    }
4788                }
4789
4790                // Process has passed all conditions, kill it!
4791                if (!doit) {
4792                    return true;
4793                }
4794                app.removed = true;
4795                procs.add(app);
4796            }
4797        }
4798
4799        int N = procs.size();
4800        for (int i=0; i<N; i++) {
4801            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4802        }
4803        updateOomAdjLocked();
4804        return N > 0;
4805    }
4806
4807    private final boolean forceStopPackageLocked(String name, int appId,
4808            boolean callerWillRestart, boolean purgeCache, boolean doit,
4809            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4810        int i;
4811        int N;
4812
4813        if (userId == UserHandle.USER_ALL && name == null) {
4814            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4815        }
4816
4817        if (appId < 0 && name != null) {
4818            try {
4819                appId = UserHandle.getAppId(
4820                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4821            } catch (RemoteException e) {
4822            }
4823        }
4824
4825        if (doit) {
4826            if (name != null) {
4827                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4828                        + " user=" + userId + ": " + reason);
4829            } else {
4830                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4831            }
4832
4833            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4834            for (int ip=pmap.size()-1; ip>=0; ip--) {
4835                SparseArray<Long> ba = pmap.valueAt(ip);
4836                for (i=ba.size()-1; i>=0; i--) {
4837                    boolean remove = false;
4838                    final int entUid = ba.keyAt(i);
4839                    if (name != null) {
4840                        if (userId == UserHandle.USER_ALL) {
4841                            if (UserHandle.getAppId(entUid) == appId) {
4842                                remove = true;
4843                            }
4844                        } else {
4845                            if (entUid == UserHandle.getUid(userId, appId)) {
4846                                remove = true;
4847                            }
4848                        }
4849                    } else if (UserHandle.getUserId(entUid) == userId) {
4850                        remove = true;
4851                    }
4852                    if (remove) {
4853                        ba.removeAt(i);
4854                    }
4855                }
4856                if (ba.size() == 0) {
4857                    pmap.removeAt(ip);
4858                }
4859            }
4860        }
4861
4862        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4863                -100, callerWillRestart, true, doit, evenPersistent,
4864                name == null ? ("stop user " + userId) : ("stop " + name));
4865
4866        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4867            if (!doit) {
4868                return true;
4869            }
4870            didSomething = true;
4871        }
4872
4873        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4874            if (!doit) {
4875                return true;
4876            }
4877            didSomething = true;
4878        }
4879
4880        if (name == null) {
4881            // Remove all sticky broadcasts from this user.
4882            mStickyBroadcasts.remove(userId);
4883        }
4884
4885        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4886        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4887                userId, providers)) {
4888            if (!doit) {
4889                return true;
4890            }
4891            didSomething = true;
4892        }
4893        N = providers.size();
4894        for (i=0; i<N; i++) {
4895            removeDyingProviderLocked(null, providers.get(i), true);
4896        }
4897
4898        // Remove transient permissions granted from/to this package/user
4899        removeUriPermissionsForPackageLocked(name, userId, false);
4900
4901        if (name == null || uninstalling) {
4902            // Remove pending intents.  For now we only do this when force
4903            // stopping users, because we have some problems when doing this
4904            // for packages -- app widgets are not currently cleaned up for
4905            // such packages, so they can be left with bad pending intents.
4906            if (mIntentSenderRecords.size() > 0) {
4907                Iterator<WeakReference<PendingIntentRecord>> it
4908                        = mIntentSenderRecords.values().iterator();
4909                while (it.hasNext()) {
4910                    WeakReference<PendingIntentRecord> wpir = it.next();
4911                    if (wpir == null) {
4912                        it.remove();
4913                        continue;
4914                    }
4915                    PendingIntentRecord pir = wpir.get();
4916                    if (pir == null) {
4917                        it.remove();
4918                        continue;
4919                    }
4920                    if (name == null) {
4921                        // Stopping user, remove all objects for the user.
4922                        if (pir.key.userId != userId) {
4923                            // Not the same user, skip it.
4924                            continue;
4925                        }
4926                    } else {
4927                        if (UserHandle.getAppId(pir.uid) != appId) {
4928                            // Different app id, skip it.
4929                            continue;
4930                        }
4931                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4932                            // Different user, skip it.
4933                            continue;
4934                        }
4935                        if (!pir.key.packageName.equals(name)) {
4936                            // Different package, skip it.
4937                            continue;
4938                        }
4939                    }
4940                    if (!doit) {
4941                        return true;
4942                    }
4943                    didSomething = true;
4944                    it.remove();
4945                    pir.canceled = true;
4946                    if (pir.key.activity != null) {
4947                        pir.key.activity.pendingResults.remove(pir.ref);
4948                    }
4949                }
4950            }
4951        }
4952
4953        if (doit) {
4954            if (purgeCache && name != null) {
4955                AttributeCache ac = AttributeCache.instance();
4956                if (ac != null) {
4957                    ac.removePackage(name);
4958                }
4959            }
4960            if (mBooted) {
4961                mStackSupervisor.resumeTopActivitiesLocked();
4962                mStackSupervisor.scheduleIdleLocked();
4963            }
4964        }
4965
4966        return didSomething;
4967    }
4968
4969    private final boolean removeProcessLocked(ProcessRecord app,
4970            boolean callerWillRestart, boolean allowRestart, String reason) {
4971        final String name = app.processName;
4972        final int uid = app.uid;
4973        if (DEBUG_PROCESSES) Slog.d(
4974            TAG, "Force removing proc " + app.toShortString() + " (" + name
4975            + "/" + uid + ")");
4976
4977        mProcessNames.remove(name, uid);
4978        mIsolatedProcesses.remove(app.uid);
4979        if (mHeavyWeightProcess == app) {
4980            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4981                    mHeavyWeightProcess.userId, 0));
4982            mHeavyWeightProcess = null;
4983        }
4984        boolean needRestart = false;
4985        if (app.pid > 0 && app.pid != MY_PID) {
4986            int pid = app.pid;
4987            synchronized (mPidsSelfLocked) {
4988                mPidsSelfLocked.remove(pid);
4989                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4990            }
4991            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
4992                    app.processName, app.info.uid);
4993            if (app.isolated) {
4994                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
4995            }
4996            killUnneededProcessLocked(app, reason);
4997            handleAppDiedLocked(app, true, allowRestart);
4998            removeLruProcessLocked(app);
4999
5000            if (app.persistent && !app.isolated) {
5001                if (!callerWillRestart) {
5002                    addAppLocked(app.info, false);
5003                } else {
5004                    needRestart = true;
5005                }
5006            }
5007        } else {
5008            mRemovedProcesses.add(app);
5009        }
5010
5011        return needRestart;
5012    }
5013
5014    private final void processStartTimedOutLocked(ProcessRecord app) {
5015        final int pid = app.pid;
5016        boolean gone = false;
5017        synchronized (mPidsSelfLocked) {
5018            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5019            if (knownApp != null && knownApp.thread == null) {
5020                mPidsSelfLocked.remove(pid);
5021                gone = true;
5022            }
5023        }
5024
5025        if (gone) {
5026            Slog.w(TAG, "Process " + app + " failed to attach");
5027            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5028                    pid, app.uid, app.processName);
5029            mProcessNames.remove(app.processName, app.uid);
5030            mIsolatedProcesses.remove(app.uid);
5031            if (mHeavyWeightProcess == app) {
5032                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5033                        mHeavyWeightProcess.userId, 0));
5034                mHeavyWeightProcess = null;
5035            }
5036            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5037                    app.processName, app.info.uid);
5038            if (app.isolated) {
5039                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5040            }
5041            // Take care of any launching providers waiting for this process.
5042            checkAppInLaunchingProvidersLocked(app, true);
5043            // Take care of any services that are waiting for the process.
5044            mServices.processStartTimedOutLocked(app);
5045            killUnneededProcessLocked(app, "start timeout");
5046            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5047                Slog.w(TAG, "Unattached app died before backup, skipping");
5048                try {
5049                    IBackupManager bm = IBackupManager.Stub.asInterface(
5050                            ServiceManager.getService(Context.BACKUP_SERVICE));
5051                    bm.agentDisconnected(app.info.packageName);
5052                } catch (RemoteException e) {
5053                    // Can't happen; the backup manager is local
5054                }
5055            }
5056            if (isPendingBroadcastProcessLocked(pid)) {
5057                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5058                skipPendingBroadcastLocked(pid);
5059            }
5060        } else {
5061            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5062        }
5063    }
5064
5065    private final boolean attachApplicationLocked(IApplicationThread thread,
5066            int pid) {
5067
5068        // Find the application record that is being attached...  either via
5069        // the pid if we are running in multiple processes, or just pull the
5070        // next app record if we are emulating process with anonymous threads.
5071        ProcessRecord app;
5072        if (pid != MY_PID && pid >= 0) {
5073            synchronized (mPidsSelfLocked) {
5074                app = mPidsSelfLocked.get(pid);
5075            }
5076        } else {
5077            app = null;
5078        }
5079
5080        if (app == null) {
5081            Slog.w(TAG, "No pending application record for pid " + pid
5082                    + " (IApplicationThread " + thread + "); dropping process");
5083            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5084            if (pid > 0 && pid != MY_PID) {
5085                Process.killProcessQuiet(pid);
5086            } else {
5087                try {
5088                    thread.scheduleExit();
5089                } catch (Exception e) {
5090                    // Ignore exceptions.
5091                }
5092            }
5093            return false;
5094        }
5095
5096        // If this application record is still attached to a previous
5097        // process, clean it up now.
5098        if (app.thread != null) {
5099            handleAppDiedLocked(app, true, true);
5100        }
5101
5102        // Tell the process all about itself.
5103
5104        if (localLOGV) Slog.v(
5105                TAG, "Binding process pid " + pid + " to record " + app);
5106
5107        final String processName = app.processName;
5108        try {
5109            AppDeathRecipient adr = new AppDeathRecipient(
5110                    app, pid, thread);
5111            thread.asBinder().linkToDeath(adr, 0);
5112            app.deathRecipient = adr;
5113        } catch (RemoteException e) {
5114            app.resetPackageList(mProcessStats);
5115            startProcessLocked(app, "link fail", processName);
5116            return false;
5117        }
5118
5119        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5120
5121        app.makeActive(thread, mProcessStats);
5122        app.curAdj = app.setAdj = -100;
5123        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5124        app.forcingToForeground = null;
5125        updateProcessForegroundLocked(app, false, false);
5126        app.hasShownUi = false;
5127        app.debugging = false;
5128        app.cached = false;
5129
5130        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5131
5132        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5133        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5134
5135        if (!normalMode) {
5136            Slog.i(TAG, "Launching preboot mode app: " + app);
5137        }
5138
5139        if (localLOGV) Slog.v(
5140            TAG, "New app record " + app
5141            + " thread=" + thread.asBinder() + " pid=" + pid);
5142        try {
5143            int testMode = IApplicationThread.DEBUG_OFF;
5144            if (mDebugApp != null && mDebugApp.equals(processName)) {
5145                testMode = mWaitForDebugger
5146                    ? IApplicationThread.DEBUG_WAIT
5147                    : IApplicationThread.DEBUG_ON;
5148                app.debugging = true;
5149                if (mDebugTransient) {
5150                    mDebugApp = mOrigDebugApp;
5151                    mWaitForDebugger = mOrigWaitForDebugger;
5152                }
5153            }
5154            String profileFile = app.instrumentationProfileFile;
5155            ParcelFileDescriptor profileFd = null;
5156            boolean profileAutoStop = false;
5157            if (mProfileApp != null && mProfileApp.equals(processName)) {
5158                mProfileProc = app;
5159                profileFile = mProfileFile;
5160                profileFd = mProfileFd;
5161                profileAutoStop = mAutoStopProfiler;
5162            }
5163            boolean enableOpenGlTrace = false;
5164            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5165                enableOpenGlTrace = true;
5166                mOpenGlTraceApp = null;
5167            }
5168
5169            // If the app is being launched for restore or full backup, set it up specially
5170            boolean isRestrictedBackupMode = false;
5171            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5172                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5173                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5174                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5175            }
5176
5177            ensurePackageDexOpt(app.instrumentationInfo != null
5178                    ? app.instrumentationInfo.packageName
5179                    : app.info.packageName);
5180            if (app.instrumentationClass != null) {
5181                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5182            }
5183            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5184                    + processName + " with config " + mConfiguration);
5185            ApplicationInfo appInfo = app.instrumentationInfo != null
5186                    ? app.instrumentationInfo : app.info;
5187            app.compat = compatibilityInfoForPackageLocked(appInfo);
5188            if (profileFd != null) {
5189                profileFd = profileFd.dup();
5190            }
5191            thread.bindApplication(processName, appInfo, providers,
5192                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5193                    app.instrumentationArguments, app.instrumentationWatcher,
5194                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5195                    isRestrictedBackupMode || !normalMode, app.persistent,
5196                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5197                    mCoreSettingsObserver.getCoreSettingsLocked());
5198            updateLruProcessLocked(app, false, null);
5199            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5200        } catch (Exception e) {
5201            // todo: Yikes!  What should we do?  For now we will try to
5202            // start another process, but that could easily get us in
5203            // an infinite loop of restarting processes...
5204            Slog.w(TAG, "Exception thrown during bind!", e);
5205
5206            app.resetPackageList(mProcessStats);
5207            app.unlinkDeathRecipient();
5208            startProcessLocked(app, "bind fail", processName);
5209            return false;
5210        }
5211
5212        // Remove this record from the list of starting applications.
5213        mPersistentStartingProcesses.remove(app);
5214        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5215                "Attach application locked removing on hold: " + app);
5216        mProcessesOnHold.remove(app);
5217
5218        boolean badApp = false;
5219        boolean didSomething = false;
5220
5221        // See if the top visible activity is waiting to run in this process...
5222        if (normalMode) {
5223            try {
5224                if (mStackSupervisor.attachApplicationLocked(app)) {
5225                    didSomething = true;
5226                }
5227            } catch (Exception e) {
5228                badApp = true;
5229            }
5230        }
5231
5232        // Find any services that should be running in this process...
5233        if (!badApp) {
5234            try {
5235                didSomething |= mServices.attachApplicationLocked(app, processName);
5236            } catch (Exception e) {
5237                badApp = true;
5238            }
5239        }
5240
5241        // Check if a next-broadcast receiver is in this process...
5242        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5243            try {
5244                didSomething |= sendPendingBroadcastsLocked(app);
5245            } catch (Exception e) {
5246                // If the app died trying to launch the receiver we declare it 'bad'
5247                badApp = true;
5248            }
5249        }
5250
5251        // Check whether the next backup agent is in this process...
5252        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5253            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5254            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5255            try {
5256                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5257                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5258                        mBackupTarget.backupMode);
5259            } catch (Exception e) {
5260                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5261                e.printStackTrace();
5262            }
5263        }
5264
5265        if (badApp) {
5266            // todo: Also need to kill application to deal with all
5267            // kinds of exceptions.
5268            handleAppDiedLocked(app, false, true);
5269            return false;
5270        }
5271
5272        if (!didSomething) {
5273            updateOomAdjLocked();
5274        }
5275
5276        return true;
5277    }
5278
5279    @Override
5280    public final void attachApplication(IApplicationThread thread) {
5281        synchronized (this) {
5282            int callingPid = Binder.getCallingPid();
5283            final long origId = Binder.clearCallingIdentity();
5284            attachApplicationLocked(thread, callingPid);
5285            Binder.restoreCallingIdentity(origId);
5286        }
5287    }
5288
5289    @Override
5290    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5291        final long origId = Binder.clearCallingIdentity();
5292        synchronized (this) {
5293            ActivityStack stack = ActivityRecord.getStackLocked(token);
5294            if (stack != null) {
5295                ActivityRecord r =
5296                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5297                if (stopProfiling) {
5298                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5299                        try {
5300                            mProfileFd.close();
5301                        } catch (IOException e) {
5302                        }
5303                        clearProfilerLocked();
5304                    }
5305                }
5306            }
5307        }
5308        Binder.restoreCallingIdentity(origId);
5309    }
5310
5311    void enableScreenAfterBoot() {
5312        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5313                SystemClock.uptimeMillis());
5314        mWindowManager.enableScreenAfterBoot();
5315
5316        synchronized (this) {
5317            updateEventDispatchingLocked();
5318        }
5319    }
5320
5321    @Override
5322    public void showBootMessage(final CharSequence msg, final boolean always) {
5323        enforceNotIsolatedCaller("showBootMessage");
5324        mWindowManager.showBootMessage(msg, always);
5325    }
5326
5327    @Override
5328    public void dismissKeyguardOnNextActivity() {
5329        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5330        final long token = Binder.clearCallingIdentity();
5331        try {
5332            synchronized (this) {
5333                if (DEBUG_LOCKSCREEN) logLockScreen("");
5334                if (mLockScreenShown) {
5335                    mLockScreenShown = false;
5336                    comeOutOfSleepIfNeededLocked();
5337                }
5338                mStackSupervisor.setDismissKeyguard(true);
5339            }
5340        } finally {
5341            Binder.restoreCallingIdentity(token);
5342        }
5343    }
5344
5345    final void finishBooting() {
5346        // Register receivers to handle package update events
5347        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5348
5349        synchronized (this) {
5350            // Ensure that any processes we had put on hold are now started
5351            // up.
5352            final int NP = mProcessesOnHold.size();
5353            if (NP > 0) {
5354                ArrayList<ProcessRecord> procs =
5355                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5356                for (int ip=0; ip<NP; ip++) {
5357                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5358                            + procs.get(ip));
5359                    startProcessLocked(procs.get(ip), "on-hold", null);
5360                }
5361            }
5362
5363            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5364                // Start looking for apps that are abusing wake locks.
5365                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5366                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5367                // Tell anyone interested that we are done booting!
5368                SystemProperties.set("sys.boot_completed", "1");
5369                SystemProperties.set("dev.bootcomplete", "1");
5370                for (int i=0; i<mStartedUsers.size(); i++) {
5371                    UserStartedState uss = mStartedUsers.valueAt(i);
5372                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5373                        uss.mState = UserStartedState.STATE_RUNNING;
5374                        final int userId = mStartedUsers.keyAt(i);
5375                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5376                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5377                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5378                        broadcastIntentLocked(null, null, intent, null,
5379                                new IIntentReceiver.Stub() {
5380                                    @Override
5381                                    public void performReceive(Intent intent, int resultCode,
5382                                            String data, Bundle extras, boolean ordered,
5383                                            boolean sticky, int sendingUser) {
5384                                        synchronized (ActivityManagerService.this) {
5385                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5386                                                    true, false);
5387                                        }
5388                                    }
5389                                },
5390                                0, null, null,
5391                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5392                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5393                                userId);
5394                    }
5395                }
5396                scheduleStartProfilesLocked();
5397            }
5398        }
5399    }
5400
5401    final void ensureBootCompleted() {
5402        boolean booting;
5403        boolean enableScreen;
5404        synchronized (this) {
5405            booting = mBooting;
5406            mBooting = false;
5407            enableScreen = !mBooted;
5408            mBooted = true;
5409        }
5410
5411        if (booting) {
5412            finishBooting();
5413        }
5414
5415        if (enableScreen) {
5416            enableScreenAfterBoot();
5417        }
5418    }
5419
5420    @Override
5421    public final void activityResumed(IBinder token) {
5422        final long origId = Binder.clearCallingIdentity();
5423        synchronized(this) {
5424            ActivityStack stack = ActivityRecord.getStackLocked(token);
5425            if (stack != null) {
5426                ActivityRecord.activityResumedLocked(token);
5427            }
5428        }
5429        Binder.restoreCallingIdentity(origId);
5430    }
5431
5432    @Override
5433    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5434        final long origId = Binder.clearCallingIdentity();
5435        synchronized(this) {
5436            ActivityStack stack = ActivityRecord.getStackLocked(token);
5437            if (stack != null) {
5438                stack.activityPausedLocked(token, false, persistentState);
5439            }
5440        }
5441        Binder.restoreCallingIdentity(origId);
5442    }
5443
5444    @Override
5445    public final void activityStopped(IBinder token, Bundle icicle,
5446            PersistableBundle persistentState, CharSequence description) {
5447        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5448
5449        // Refuse possible leaked file descriptors
5450        if (icicle != null && icicle.hasFileDescriptors()) {
5451            throw new IllegalArgumentException("File descriptors passed in Bundle");
5452        }
5453
5454        final long origId = Binder.clearCallingIdentity();
5455
5456        synchronized (this) {
5457            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5458            if (r != null) {
5459                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5460            }
5461        }
5462
5463        trimApplications();
5464
5465        Binder.restoreCallingIdentity(origId);
5466    }
5467
5468    @Override
5469    public final void activityDestroyed(IBinder token) {
5470        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5471        synchronized (this) {
5472            ActivityStack stack = ActivityRecord.getStackLocked(token);
5473            if (stack != null) {
5474                stack.activityDestroyedLocked(token);
5475            }
5476        }
5477    }
5478
5479    @Override
5480    public String getCallingPackage(IBinder token) {
5481        synchronized (this) {
5482            ActivityRecord r = getCallingRecordLocked(token);
5483            return r != null ? r.info.packageName : null;
5484        }
5485    }
5486
5487    @Override
5488    public ComponentName getCallingActivity(IBinder token) {
5489        synchronized (this) {
5490            ActivityRecord r = getCallingRecordLocked(token);
5491            return r != null ? r.intent.getComponent() : null;
5492        }
5493    }
5494
5495    private ActivityRecord getCallingRecordLocked(IBinder token) {
5496        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5497        if (r == null) {
5498            return null;
5499        }
5500        return r.resultTo;
5501    }
5502
5503    @Override
5504    public ComponentName getActivityClassForToken(IBinder token) {
5505        synchronized(this) {
5506            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5507            if (r == null) {
5508                return null;
5509            }
5510            return r.intent.getComponent();
5511        }
5512    }
5513
5514    @Override
5515    public String getPackageForToken(IBinder token) {
5516        synchronized(this) {
5517            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5518            if (r == null) {
5519                return null;
5520            }
5521            return r.packageName;
5522        }
5523    }
5524
5525    @Override
5526    public IIntentSender getIntentSender(int type,
5527            String packageName, IBinder token, String resultWho,
5528            int requestCode, Intent[] intents, String[] resolvedTypes,
5529            int flags, Bundle options, int userId) {
5530        enforceNotIsolatedCaller("getIntentSender");
5531        // Refuse possible leaked file descriptors
5532        if (intents != null) {
5533            if (intents.length < 1) {
5534                throw new IllegalArgumentException("Intents array length must be >= 1");
5535            }
5536            for (int i=0; i<intents.length; i++) {
5537                Intent intent = intents[i];
5538                if (intent != null) {
5539                    if (intent.hasFileDescriptors()) {
5540                        throw new IllegalArgumentException("File descriptors passed in Intent");
5541                    }
5542                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5543                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5544                        throw new IllegalArgumentException(
5545                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5546                    }
5547                    intents[i] = new Intent(intent);
5548                }
5549            }
5550            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5551                throw new IllegalArgumentException(
5552                        "Intent array length does not match resolvedTypes length");
5553            }
5554        }
5555        if (options != null) {
5556            if (options.hasFileDescriptors()) {
5557                throw new IllegalArgumentException("File descriptors passed in options");
5558            }
5559        }
5560
5561        synchronized(this) {
5562            int callingUid = Binder.getCallingUid();
5563            int origUserId = userId;
5564            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5565                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5566                    "getIntentSender", null);
5567            if (origUserId == UserHandle.USER_CURRENT) {
5568                // We don't want to evaluate this until the pending intent is
5569                // actually executed.  However, we do want to always do the
5570                // security checking for it above.
5571                userId = UserHandle.USER_CURRENT;
5572            }
5573            try {
5574                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5575                    int uid = AppGlobals.getPackageManager()
5576                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5577                    if (!UserHandle.isSameApp(callingUid, uid)) {
5578                        String msg = "Permission Denial: getIntentSender() from pid="
5579                            + Binder.getCallingPid()
5580                            + ", uid=" + Binder.getCallingUid()
5581                            + ", (need uid=" + uid + ")"
5582                            + " is not allowed to send as package " + packageName;
5583                        Slog.w(TAG, msg);
5584                        throw new SecurityException(msg);
5585                    }
5586                }
5587
5588                return getIntentSenderLocked(type, packageName, callingUid, userId,
5589                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5590
5591            } catch (RemoteException e) {
5592                throw new SecurityException(e);
5593            }
5594        }
5595    }
5596
5597    IIntentSender getIntentSenderLocked(int type, String packageName,
5598            int callingUid, int userId, IBinder token, String resultWho,
5599            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5600            Bundle options) {
5601        if (DEBUG_MU)
5602            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5603        ActivityRecord activity = null;
5604        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5605            activity = ActivityRecord.isInStackLocked(token);
5606            if (activity == null) {
5607                return null;
5608            }
5609            if (activity.finishing) {
5610                return null;
5611            }
5612        }
5613
5614        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5615        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5616        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5617        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5618                |PendingIntent.FLAG_UPDATE_CURRENT);
5619
5620        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5621                type, packageName, activity, resultWho,
5622                requestCode, intents, resolvedTypes, flags, options, userId);
5623        WeakReference<PendingIntentRecord> ref;
5624        ref = mIntentSenderRecords.get(key);
5625        PendingIntentRecord rec = ref != null ? ref.get() : null;
5626        if (rec != null) {
5627            if (!cancelCurrent) {
5628                if (updateCurrent) {
5629                    if (rec.key.requestIntent != null) {
5630                        rec.key.requestIntent.replaceExtras(intents != null ?
5631                                intents[intents.length - 1] : null);
5632                    }
5633                    if (intents != null) {
5634                        intents[intents.length-1] = rec.key.requestIntent;
5635                        rec.key.allIntents = intents;
5636                        rec.key.allResolvedTypes = resolvedTypes;
5637                    } else {
5638                        rec.key.allIntents = null;
5639                        rec.key.allResolvedTypes = null;
5640                    }
5641                }
5642                return rec;
5643            }
5644            rec.canceled = true;
5645            mIntentSenderRecords.remove(key);
5646        }
5647        if (noCreate) {
5648            return rec;
5649        }
5650        rec = new PendingIntentRecord(this, key, callingUid);
5651        mIntentSenderRecords.put(key, rec.ref);
5652        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5653            if (activity.pendingResults == null) {
5654                activity.pendingResults
5655                        = new HashSet<WeakReference<PendingIntentRecord>>();
5656            }
5657            activity.pendingResults.add(rec.ref);
5658        }
5659        return rec;
5660    }
5661
5662    @Override
5663    public void cancelIntentSender(IIntentSender sender) {
5664        if (!(sender instanceof PendingIntentRecord)) {
5665            return;
5666        }
5667        synchronized(this) {
5668            PendingIntentRecord rec = (PendingIntentRecord)sender;
5669            try {
5670                int uid = AppGlobals.getPackageManager()
5671                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5672                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5673                    String msg = "Permission Denial: cancelIntentSender() from pid="
5674                        + Binder.getCallingPid()
5675                        + ", uid=" + Binder.getCallingUid()
5676                        + " is not allowed to cancel packges "
5677                        + rec.key.packageName;
5678                    Slog.w(TAG, msg);
5679                    throw new SecurityException(msg);
5680                }
5681            } catch (RemoteException e) {
5682                throw new SecurityException(e);
5683            }
5684            cancelIntentSenderLocked(rec, true);
5685        }
5686    }
5687
5688    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5689        rec.canceled = true;
5690        mIntentSenderRecords.remove(rec.key);
5691        if (cleanActivity && rec.key.activity != null) {
5692            rec.key.activity.pendingResults.remove(rec.ref);
5693        }
5694    }
5695
5696    @Override
5697    public String getPackageForIntentSender(IIntentSender pendingResult) {
5698        if (!(pendingResult instanceof PendingIntentRecord)) {
5699            return null;
5700        }
5701        try {
5702            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5703            return res.key.packageName;
5704        } catch (ClassCastException e) {
5705        }
5706        return null;
5707    }
5708
5709    @Override
5710    public int getUidForIntentSender(IIntentSender sender) {
5711        if (sender instanceof PendingIntentRecord) {
5712            try {
5713                PendingIntentRecord res = (PendingIntentRecord)sender;
5714                return res.uid;
5715            } catch (ClassCastException e) {
5716            }
5717        }
5718        return -1;
5719    }
5720
5721    @Override
5722    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5723        if (!(pendingResult instanceof PendingIntentRecord)) {
5724            return false;
5725        }
5726        try {
5727            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5728            if (res.key.allIntents == null) {
5729                return false;
5730            }
5731            for (int i=0; i<res.key.allIntents.length; i++) {
5732                Intent intent = res.key.allIntents[i];
5733                if (intent.getPackage() != null && intent.getComponent() != null) {
5734                    return false;
5735                }
5736            }
5737            return true;
5738        } catch (ClassCastException e) {
5739        }
5740        return false;
5741    }
5742
5743    @Override
5744    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5745        if (!(pendingResult instanceof PendingIntentRecord)) {
5746            return false;
5747        }
5748        try {
5749            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5750            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5751                return true;
5752            }
5753            return false;
5754        } catch (ClassCastException e) {
5755        }
5756        return false;
5757    }
5758
5759    @Override
5760    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5761        if (!(pendingResult instanceof PendingIntentRecord)) {
5762            return null;
5763        }
5764        try {
5765            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5766            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5767        } catch (ClassCastException e) {
5768        }
5769        return null;
5770    }
5771
5772    @Override
5773    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5774        if (!(pendingResult instanceof PendingIntentRecord)) {
5775            return null;
5776        }
5777        try {
5778            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5779            Intent intent = res.key.requestIntent;
5780            if (intent != null) {
5781                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5782                        || res.lastTagPrefix.equals(prefix))) {
5783                    return res.lastTag;
5784                }
5785                res.lastTagPrefix = prefix;
5786                StringBuilder sb = new StringBuilder(128);
5787                if (prefix != null) {
5788                    sb.append(prefix);
5789                }
5790                if (intent.getAction() != null) {
5791                    sb.append(intent.getAction());
5792                } else if (intent.getComponent() != null) {
5793                    intent.getComponent().appendShortString(sb);
5794                } else {
5795                    sb.append("?");
5796                }
5797                return res.lastTag = sb.toString();
5798            }
5799        } catch (ClassCastException e) {
5800        }
5801        return null;
5802    }
5803
5804    @Override
5805    public void setProcessLimit(int max) {
5806        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5807                "setProcessLimit()");
5808        synchronized (this) {
5809            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5810            mProcessLimitOverride = max;
5811        }
5812        trimApplications();
5813    }
5814
5815    @Override
5816    public int getProcessLimit() {
5817        synchronized (this) {
5818            return mProcessLimitOverride;
5819        }
5820    }
5821
5822    void foregroundTokenDied(ForegroundToken token) {
5823        synchronized (ActivityManagerService.this) {
5824            synchronized (mPidsSelfLocked) {
5825                ForegroundToken cur
5826                    = mForegroundProcesses.get(token.pid);
5827                if (cur != token) {
5828                    return;
5829                }
5830                mForegroundProcesses.remove(token.pid);
5831                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5832                if (pr == null) {
5833                    return;
5834                }
5835                pr.forcingToForeground = null;
5836                updateProcessForegroundLocked(pr, false, false);
5837            }
5838            updateOomAdjLocked();
5839        }
5840    }
5841
5842    @Override
5843    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5844        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5845                "setProcessForeground()");
5846        synchronized(this) {
5847            boolean changed = false;
5848
5849            synchronized (mPidsSelfLocked) {
5850                ProcessRecord pr = mPidsSelfLocked.get(pid);
5851                if (pr == null && isForeground) {
5852                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5853                    return;
5854                }
5855                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5856                if (oldToken != null) {
5857                    oldToken.token.unlinkToDeath(oldToken, 0);
5858                    mForegroundProcesses.remove(pid);
5859                    if (pr != null) {
5860                        pr.forcingToForeground = null;
5861                    }
5862                    changed = true;
5863                }
5864                if (isForeground && token != null) {
5865                    ForegroundToken newToken = new ForegroundToken() {
5866                        @Override
5867                        public void binderDied() {
5868                            foregroundTokenDied(this);
5869                        }
5870                    };
5871                    newToken.pid = pid;
5872                    newToken.token = token;
5873                    try {
5874                        token.linkToDeath(newToken, 0);
5875                        mForegroundProcesses.put(pid, newToken);
5876                        pr.forcingToForeground = token;
5877                        changed = true;
5878                    } catch (RemoteException e) {
5879                        // If the process died while doing this, we will later
5880                        // do the cleanup with the process death link.
5881                    }
5882                }
5883            }
5884
5885            if (changed) {
5886                updateOomAdjLocked();
5887            }
5888        }
5889    }
5890
5891    // =========================================================
5892    // PERMISSIONS
5893    // =========================================================
5894
5895    static class PermissionController extends IPermissionController.Stub {
5896        ActivityManagerService mActivityManagerService;
5897        PermissionController(ActivityManagerService activityManagerService) {
5898            mActivityManagerService = activityManagerService;
5899        }
5900
5901        @Override
5902        public boolean checkPermission(String permission, int pid, int uid) {
5903            return mActivityManagerService.checkPermission(permission, pid,
5904                    uid) == PackageManager.PERMISSION_GRANTED;
5905        }
5906    }
5907
5908    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5909        @Override
5910        public int checkComponentPermission(String permission, int pid, int uid,
5911                int owningUid, boolean exported) {
5912            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5913                    owningUid, exported);
5914        }
5915
5916        @Override
5917        public Object getAMSLock() {
5918            return ActivityManagerService.this;
5919        }
5920    }
5921
5922    /**
5923     * This can be called with or without the global lock held.
5924     */
5925    int checkComponentPermission(String permission, int pid, int uid,
5926            int owningUid, boolean exported) {
5927        // We might be performing an operation on behalf of an indirect binder
5928        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5929        // client identity accordingly before proceeding.
5930        Identity tlsIdentity = sCallerIdentity.get();
5931        if (tlsIdentity != null) {
5932            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5933                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5934            uid = tlsIdentity.uid;
5935            pid = tlsIdentity.pid;
5936        }
5937
5938        if (pid == MY_PID) {
5939            return PackageManager.PERMISSION_GRANTED;
5940        }
5941
5942        return ActivityManager.checkComponentPermission(permission, uid,
5943                owningUid, exported);
5944    }
5945
5946    /**
5947     * As the only public entry point for permissions checking, this method
5948     * can enforce the semantic that requesting a check on a null global
5949     * permission is automatically denied.  (Internally a null permission
5950     * string is used when calling {@link #checkComponentPermission} in cases
5951     * when only uid-based security is needed.)
5952     *
5953     * This can be called with or without the global lock held.
5954     */
5955    @Override
5956    public int checkPermission(String permission, int pid, int uid) {
5957        if (permission == null) {
5958            return PackageManager.PERMISSION_DENIED;
5959        }
5960        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5961    }
5962
5963    /**
5964     * Binder IPC calls go through the public entry point.
5965     * This can be called with or without the global lock held.
5966     */
5967    int checkCallingPermission(String permission) {
5968        return checkPermission(permission,
5969                Binder.getCallingPid(),
5970                UserHandle.getAppId(Binder.getCallingUid()));
5971    }
5972
5973    /**
5974     * This can be called with or without the global lock held.
5975     */
5976    void enforceCallingPermission(String permission, String func) {
5977        if (checkCallingPermission(permission)
5978                == PackageManager.PERMISSION_GRANTED) {
5979            return;
5980        }
5981
5982        String msg = "Permission Denial: " + func + " from pid="
5983                + Binder.getCallingPid()
5984                + ", uid=" + Binder.getCallingUid()
5985                + " requires " + permission;
5986        Slog.w(TAG, msg);
5987        throw new SecurityException(msg);
5988    }
5989
5990    /**
5991     * Determine if UID is holding permissions required to access {@link Uri} in
5992     * the given {@link ProviderInfo}. Final permission checking is always done
5993     * in {@link ContentProvider}.
5994     */
5995    private final boolean checkHoldingPermissionsLocked(
5996            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, final int modeFlags) {
5997        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5998                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
5999
6000        if (pi.applicationInfo.uid == uid) {
6001            return true;
6002        } else if (!pi.exported) {
6003            return false;
6004        }
6005
6006        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6007        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6008        try {
6009            // check if target holds top-level <provider> permissions
6010            if (!readMet && pi.readPermission != null
6011                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6012                readMet = true;
6013            }
6014            if (!writeMet && pi.writePermission != null
6015                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6016                writeMet = true;
6017            }
6018
6019            // track if unprotected read/write is allowed; any denied
6020            // <path-permission> below removes this ability
6021            boolean allowDefaultRead = pi.readPermission == null;
6022            boolean allowDefaultWrite = pi.writePermission == null;
6023
6024            // check if target holds any <path-permission> that match uri
6025            final PathPermission[] pps = pi.pathPermissions;
6026            if (pps != null) {
6027                final String path = uri.getPath();
6028                int i = pps.length;
6029                while (i > 0 && (!readMet || !writeMet)) {
6030                    i--;
6031                    PathPermission pp = pps[i];
6032                    if (pp.match(path)) {
6033                        if (!readMet) {
6034                            final String pprperm = pp.getReadPermission();
6035                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6036                                    + pprperm + " for " + pp.getPath()
6037                                    + ": match=" + pp.match(path)
6038                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6039                            if (pprperm != null) {
6040                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
6041                                    readMet = true;
6042                                } else {
6043                                    allowDefaultRead = false;
6044                                }
6045                            }
6046                        }
6047                        if (!writeMet) {
6048                            final String ppwperm = pp.getWritePermission();
6049                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6050                                    + ppwperm + " for " + pp.getPath()
6051                                    + ": match=" + pp.match(path)
6052                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6053                            if (ppwperm != null) {
6054                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
6055                                    writeMet = true;
6056                                } else {
6057                                    allowDefaultWrite = false;
6058                                }
6059                            }
6060                        }
6061                    }
6062                }
6063            }
6064
6065            // grant unprotected <provider> read/write, if not blocked by
6066            // <path-permission> above
6067            if (allowDefaultRead) readMet = true;
6068            if (allowDefaultWrite) writeMet = true;
6069
6070        } catch (RemoteException e) {
6071            return false;
6072        }
6073
6074        return readMet && writeMet;
6075    }
6076
6077    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6078        ProviderInfo pi = null;
6079        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6080        if (cpr != null) {
6081            pi = cpr.info;
6082        } else {
6083            try {
6084                pi = AppGlobals.getPackageManager().resolveContentProvider(
6085                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6086            } catch (RemoteException ex) {
6087            }
6088        }
6089        return pi;
6090    }
6091
6092    private UriPermission findUriPermissionLocked(int targetUid, GrantUri uri) {
6093        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6094        if (targetUris != null) {
6095            return targetUris.get(uri);
6096        }
6097        return null;
6098    }
6099
6100    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6101            String targetPkg, int targetUid, GrantUri uri) {
6102        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6103        if (targetUris == null) {
6104            targetUris = Maps.newArrayMap();
6105            mGrantedUriPermissions.put(targetUid, targetUris);
6106        }
6107
6108        UriPermission perm = targetUris.get(uri);
6109        if (perm == null) {
6110            perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri);
6111            targetUris.put(uri, perm);
6112        }
6113
6114        return perm;
6115    }
6116
6117    private final boolean checkUriPermissionLocked(Uri uri, int uid, final int modeFlags) {
6118        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6119        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6120                : UriPermission.STRENGTH_OWNED;
6121
6122        // Root gets to do everything.
6123        if (uid == 0) {
6124            return true;
6125        }
6126
6127        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6128        if (perms == null) return false;
6129
6130        // First look for exact match
6131        final UriPermission exactPerm = perms.get(new GrantUri(uri, false));
6132        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6133            return true;
6134        }
6135
6136        // No exact match, look for prefixes
6137        final int N = perms.size();
6138        for (int i = 0; i < N; i++) {
6139            final UriPermission perm = perms.valueAt(i);
6140            if (perm.uri.prefix && uri.isPathPrefixMatch(perm.uri.uri)
6141                    && perm.getStrength(modeFlags) >= minStrength) {
6142                return true;
6143            }
6144        }
6145
6146        return false;
6147    }
6148
6149    @Override
6150    public int checkUriPermission(Uri uri, int pid, int uid, final int modeFlags) {
6151        enforceNotIsolatedCaller("checkUriPermission");
6152
6153        // Another redirected-binder-call permissions check as in
6154        // {@link checkComponentPermission}.
6155        Identity tlsIdentity = sCallerIdentity.get();
6156        if (tlsIdentity != null) {
6157            uid = tlsIdentity.uid;
6158            pid = tlsIdentity.pid;
6159        }
6160
6161        // Our own process gets to do everything.
6162        if (pid == MY_PID) {
6163            return PackageManager.PERMISSION_GRANTED;
6164        }
6165        synchronized (this) {
6166            return checkUriPermissionLocked(uri, uid, modeFlags)
6167                    ? PackageManager.PERMISSION_GRANTED
6168                    : PackageManager.PERMISSION_DENIED;
6169        }
6170    }
6171
6172    /**
6173     * Check if the targetPkg can be granted permission to access uri by
6174     * the callingUid using the given modeFlags.  Throws a security exception
6175     * if callingUid is not allowed to do this.  Returns the uid of the target
6176     * if the URI permission grant should be performed; returns -1 if it is not
6177     * needed (for example targetPkg already has permission to access the URI).
6178     * If you already know the uid of the target, you can supply it in
6179     * lastTargetUid else set that to -1.
6180     */
6181    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
6182            Uri uri, final int modeFlags, int lastTargetUid) {
6183        if (!Intent.isAccessUriMode(modeFlags)) {
6184            return -1;
6185        }
6186
6187        if (targetPkg != null) {
6188            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6189                    "Checking grant " + targetPkg + " permission to " + uri);
6190        }
6191
6192        final IPackageManager pm = AppGlobals.getPackageManager();
6193
6194        // If this is not a content: uri, we can't do anything with it.
6195        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
6196            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6197                    "Can't grant URI permission for non-content URI: " + uri);
6198            return -1;
6199        }
6200
6201        final String authority = uri.getAuthority();
6202        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6203        if (pi == null) {
6204            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
6205            return -1;
6206        }
6207
6208        int targetUid = lastTargetUid;
6209        if (targetUid < 0 && targetPkg != null) {
6210            try {
6211                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6212                if (targetUid < 0) {
6213                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6214                            "Can't grant URI permission no uid for: " + targetPkg);
6215                    return -1;
6216                }
6217            } catch (RemoteException ex) {
6218                return -1;
6219            }
6220        }
6221
6222        if (targetUid >= 0) {
6223            // First...  does the target actually need this permission?
6224            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
6225                // No need to grant the target this permission.
6226                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6227                        "Target " + targetPkg + " already has full permission to " + uri);
6228                return -1;
6229            }
6230        } else {
6231            // First...  there is no target package, so can anyone access it?
6232            boolean allowed = pi.exported;
6233            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6234                if (pi.readPermission != null) {
6235                    allowed = false;
6236                }
6237            }
6238            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6239                if (pi.writePermission != null) {
6240                    allowed = false;
6241                }
6242            }
6243            if (allowed) {
6244                return -1;
6245            }
6246        }
6247
6248        // Second...  is the provider allowing granting of URI permissions?
6249        if (!pi.grantUriPermissions) {
6250            throw new SecurityException("Provider " + pi.packageName
6251                    + "/" + pi.name
6252                    + " does not allow granting of Uri permissions (uri "
6253                    + uri + ")");
6254        }
6255        if (pi.uriPermissionPatterns != null) {
6256            final int N = pi.uriPermissionPatterns.length;
6257            boolean allowed = false;
6258            for (int i=0; i<N; i++) {
6259                if (pi.uriPermissionPatterns[i] != null
6260                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
6261                    allowed = true;
6262                    break;
6263                }
6264            }
6265            if (!allowed) {
6266                throw new SecurityException("Provider " + pi.packageName
6267                        + "/" + pi.name
6268                        + " does not allow granting of permission to path of Uri "
6269                        + uri);
6270            }
6271        }
6272
6273        // Third...  does the caller itself have permission to access
6274        // this uri?
6275        if (callingUid != Process.myUid()) {
6276            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6277                // Require they hold a strong enough Uri permission
6278                if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6279                    throw new SecurityException("Uid " + callingUid
6280                            + " does not have permission to uri " + uri);
6281                }
6282            }
6283        }
6284
6285        return targetUid;
6286    }
6287
6288    @Override
6289    public int checkGrantUriPermission(int callingUid, String targetPkg,
6290            Uri uri, final int modeFlags) {
6291        enforceNotIsolatedCaller("checkGrantUriPermission");
6292        synchronized(this) {
6293            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6294        }
6295    }
6296
6297    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, Uri uri,
6298            final int modeFlags, UriPermissionOwner owner) {
6299        if (!Intent.isAccessUriMode(modeFlags)) {
6300            return;
6301        }
6302
6303        // So here we are: the caller has the assumed permission
6304        // to the uri, and the target doesn't.  Let's now give this to
6305        // the target.
6306
6307        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6308                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
6309
6310        final String authority = uri.getAuthority();
6311        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid));
6312        if (pi == null) {
6313            Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString());
6314            return;
6315        }
6316
6317        final boolean prefix = (modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
6318        final UriPermission perm = findOrCreateUriPermissionLocked(
6319                pi.packageName, targetPkg, targetUid, new GrantUri(uri, prefix));
6320        perm.grantModes(modeFlags, owner);
6321    }
6322
6323    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
6324            final int modeFlags, UriPermissionOwner owner) {
6325        if (targetPkg == null) {
6326            throw new NullPointerException("targetPkg");
6327        }
6328
6329        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6330        if (targetUid < 0) {
6331            return;
6332        }
6333
6334        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
6335    }
6336
6337    static class NeededUriGrants extends ArrayList<Uri> {
6338        final String targetPkg;
6339        final int targetUid;
6340        final int flags;
6341
6342        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6343            this.targetPkg = targetPkg;
6344            this.targetUid = targetUid;
6345            this.flags = flags;
6346        }
6347    }
6348
6349    /**
6350     * Like checkGrantUriPermissionLocked, but takes an Intent.
6351     */
6352    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6353            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6354        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6355                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6356                + " clip=" + (intent != null ? intent.getClipData() : null)
6357                + " from " + intent + "; flags=0x"
6358                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6359
6360        if (targetPkg == null) {
6361            throw new NullPointerException("targetPkg");
6362        }
6363
6364        if (intent == null) {
6365            return null;
6366        }
6367        Uri data = intent.getData();
6368        ClipData clip = intent.getClipData();
6369        if (data == null && clip == null) {
6370            return null;
6371        }
6372
6373        if (data != null) {
6374            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
6375                mode, needed != null ? needed.targetUid : -1);
6376            if (targetUid > 0) {
6377                if (needed == null) {
6378                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6379                }
6380                needed.add(data);
6381            }
6382        }
6383        if (clip != null) {
6384            for (int i=0; i<clip.getItemCount(); i++) {
6385                Uri uri = clip.getItemAt(i).getUri();
6386                if (uri != null) {
6387                    int targetUid = -1;
6388                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
6389                            mode, needed != null ? needed.targetUid : -1);
6390                    if (targetUid > 0) {
6391                        if (needed == null) {
6392                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6393                        }
6394                        needed.add(uri);
6395                    }
6396                } else {
6397                    Intent clipIntent = clip.getItemAt(i).getIntent();
6398                    if (clipIntent != null) {
6399                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6400                                callingUid, targetPkg, clipIntent, mode, needed);
6401                        if (newNeeded != null) {
6402                            needed = newNeeded;
6403                        }
6404                    }
6405                }
6406            }
6407        }
6408
6409        return needed;
6410    }
6411
6412    /**
6413     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6414     */
6415    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6416            UriPermissionOwner owner) {
6417        if (needed != null) {
6418            for (int i=0; i<needed.size(); i++) {
6419                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6420                        needed.get(i), needed.flags, owner);
6421            }
6422        }
6423    }
6424
6425    void grantUriPermissionFromIntentLocked(int callingUid,
6426            String targetPkg, Intent intent, UriPermissionOwner owner) {
6427        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6428                intent, intent != null ? intent.getFlags() : 0, null);
6429        if (needed == null) {
6430            return;
6431        }
6432
6433        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6434    }
6435
6436    @Override
6437    public void grantUriPermission(IApplicationThread caller, String targetPkg,
6438            Uri uri, final int modeFlags) {
6439        enforceNotIsolatedCaller("grantUriPermission");
6440        synchronized(this) {
6441            final ProcessRecord r = getRecordForAppLocked(caller);
6442            if (r == null) {
6443                throw new SecurityException("Unable to find app for caller "
6444                        + caller
6445                        + " when granting permission to uri " + uri);
6446            }
6447            if (targetPkg == null) {
6448                throw new IllegalArgumentException("null target");
6449            }
6450            if (uri == null) {
6451                throw new IllegalArgumentException("null uri");
6452            }
6453
6454            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6455                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6456                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6457                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6458
6459            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, null);
6460        }
6461    }
6462
6463    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6464        if (perm.modeFlags == 0) {
6465            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6466                    perm.targetUid);
6467            if (perms != null) {
6468                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6469                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6470
6471                perms.remove(perm.uri);
6472                if (perms.isEmpty()) {
6473                    mGrantedUriPermissions.remove(perm.targetUid);
6474                }
6475            }
6476        }
6477    }
6478
6479    private void revokeUriPermissionLocked(int callingUid, Uri uri, final int modeFlags) {
6480        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri);
6481
6482        final IPackageManager pm = AppGlobals.getPackageManager();
6483        final String authority = uri.getAuthority();
6484        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6485        if (pi == null) {
6486            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
6487            return;
6488        }
6489
6490        // Does the caller have this permission on the URI?
6491        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6492            // Right now, if you are not the original owner of the permission,
6493            // you are not allowed to revoke it.
6494            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6495                throw new SecurityException("Uid " + callingUid
6496                        + " does not have permission to uri " + uri);
6497            //}
6498        }
6499
6500        boolean persistChanged = false;
6501
6502        // Go through all of the permissions and remove any that match.
6503        int N = mGrantedUriPermissions.size();
6504        for (int i = 0; i < N; i++) {
6505            final int targetUid = mGrantedUriPermissions.keyAt(i);
6506            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6507
6508            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6509                final UriPermission perm = it.next();
6510                if (perm.uri.uri.isPathPrefixMatch(uri)) {
6511                    if (DEBUG_URI_PERMISSION)
6512                        Slog.v(TAG,
6513                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6514                    persistChanged |= perm.revokeModes(
6515                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6516                    if (perm.modeFlags == 0) {
6517                        it.remove();
6518                    }
6519                }
6520            }
6521
6522            if (perms.isEmpty()) {
6523                mGrantedUriPermissions.remove(targetUid);
6524                N--;
6525                i--;
6526            }
6527        }
6528
6529        if (persistChanged) {
6530            schedulePersistUriGrants();
6531        }
6532    }
6533
6534    @Override
6535    public void revokeUriPermission(IApplicationThread caller, Uri uri,
6536            final int modeFlags) {
6537        enforceNotIsolatedCaller("revokeUriPermission");
6538        synchronized(this) {
6539            final ProcessRecord r = getRecordForAppLocked(caller);
6540            if (r == null) {
6541                throw new SecurityException("Unable to find app for caller "
6542                        + caller
6543                        + " when revoking permission to uri " + uri);
6544            }
6545            if (uri == null) {
6546                Slog.w(TAG, "revokeUriPermission: null uri");
6547                return;
6548            }
6549
6550            if (!Intent.isAccessUriMode(modeFlags)) {
6551                return;
6552            }
6553
6554            final IPackageManager pm = AppGlobals.getPackageManager();
6555            final String authority = uri.getAuthority();
6556            final ProviderInfo pi = getProviderInfoLocked(authority, r.userId);
6557            if (pi == null) {
6558                Slog.w(TAG, "No content provider found for permission revoke: "
6559                        + uri.toSafeString());
6560                return;
6561            }
6562
6563            revokeUriPermissionLocked(r.uid, uri, modeFlags);
6564        }
6565    }
6566
6567    /**
6568     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6569     * given package.
6570     *
6571     * @param packageName Package name to match, or {@code null} to apply to all
6572     *            packages.
6573     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6574     *            to all users.
6575     * @param persistable If persistable grants should be removed.
6576     */
6577    private void removeUriPermissionsForPackageLocked(
6578            String packageName, int userHandle, boolean persistable) {
6579        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6580            throw new IllegalArgumentException("Must narrow by either package or user");
6581        }
6582
6583        boolean persistChanged = false;
6584
6585        int N = mGrantedUriPermissions.size();
6586        for (int i = 0; i < N; i++) {
6587            final int targetUid = mGrantedUriPermissions.keyAt(i);
6588            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6589
6590            // Only inspect grants matching user
6591            if (userHandle == UserHandle.USER_ALL
6592                    || userHandle == UserHandle.getUserId(targetUid)) {
6593                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6594                    final UriPermission perm = it.next();
6595
6596                    // Only inspect grants matching package
6597                    if (packageName == null || perm.sourcePkg.equals(packageName)
6598                            || perm.targetPkg.equals(packageName)) {
6599                        persistChanged |= perm.revokeModes(
6600                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6601
6602                        // Only remove when no modes remain; any persisted grants
6603                        // will keep this alive.
6604                        if (perm.modeFlags == 0) {
6605                            it.remove();
6606                        }
6607                    }
6608                }
6609
6610                if (perms.isEmpty()) {
6611                    mGrantedUriPermissions.remove(targetUid);
6612                    N--;
6613                    i--;
6614                }
6615            }
6616        }
6617
6618        if (persistChanged) {
6619            schedulePersistUriGrants();
6620        }
6621    }
6622
6623    @Override
6624    public IBinder newUriPermissionOwner(String name) {
6625        enforceNotIsolatedCaller("newUriPermissionOwner");
6626        synchronized(this) {
6627            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6628            return owner.getExternalTokenLocked();
6629        }
6630    }
6631
6632    @Override
6633    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
6634            Uri uri, final int modeFlags) {
6635        synchronized(this) {
6636            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6637            if (owner == null) {
6638                throw new IllegalArgumentException("Unknown owner: " + token);
6639            }
6640            if (fromUid != Binder.getCallingUid()) {
6641                if (Binder.getCallingUid() != Process.myUid()) {
6642                    // Only system code can grant URI permissions on behalf
6643                    // of other users.
6644                    throw new SecurityException("nice try");
6645                }
6646            }
6647            if (targetPkg == null) {
6648                throw new IllegalArgumentException("null target");
6649            }
6650            if (uri == null) {
6651                throw new IllegalArgumentException("null uri");
6652            }
6653
6654            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
6655        }
6656    }
6657
6658    @Override
6659    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
6660        synchronized(this) {
6661            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6662            if (owner == null) {
6663                throw new IllegalArgumentException("Unknown owner: " + token);
6664            }
6665
6666            if (uri == null) {
6667                owner.removeUriPermissionsLocked(mode);
6668            } else {
6669                owner.removeUriPermissionLocked(uri, mode);
6670            }
6671        }
6672    }
6673
6674    private void schedulePersistUriGrants() {
6675        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6676            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6677                    10 * DateUtils.SECOND_IN_MILLIS);
6678        }
6679    }
6680
6681    private void writeGrantedUriPermissions() {
6682        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6683
6684        // Snapshot permissions so we can persist without lock
6685        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6686        synchronized (this) {
6687            final int size = mGrantedUriPermissions.size();
6688            for (int i = 0; i < size; i++) {
6689                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6690                for (UriPermission perm : perms.values()) {
6691                    if (perm.persistedModeFlags != 0) {
6692                        persist.add(perm.snapshot());
6693                    }
6694                }
6695            }
6696        }
6697
6698        FileOutputStream fos = null;
6699        try {
6700            fos = mGrantFile.startWrite();
6701
6702            XmlSerializer out = new FastXmlSerializer();
6703            out.setOutput(fos, "utf-8");
6704            out.startDocument(null, true);
6705            out.startTag(null, TAG_URI_GRANTS);
6706            for (UriPermission.Snapshot perm : persist) {
6707                out.startTag(null, TAG_URI_GRANT);
6708                writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle);
6709                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6710                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6711                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6712                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6713                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6714                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6715                out.endTag(null, TAG_URI_GRANT);
6716            }
6717            out.endTag(null, TAG_URI_GRANTS);
6718            out.endDocument();
6719
6720            mGrantFile.finishWrite(fos);
6721        } catch (IOException e) {
6722            if (fos != null) {
6723                mGrantFile.failWrite(fos);
6724            }
6725        }
6726    }
6727
6728    private void readGrantedUriPermissionsLocked() {
6729        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6730
6731        final long now = System.currentTimeMillis();
6732
6733        FileInputStream fis = null;
6734        try {
6735            fis = mGrantFile.openRead();
6736            final XmlPullParser in = Xml.newPullParser();
6737            in.setInput(fis, null);
6738
6739            int type;
6740            while ((type = in.next()) != END_DOCUMENT) {
6741                final String tag = in.getName();
6742                if (type == START_TAG) {
6743                    if (TAG_URI_GRANT.equals(tag)) {
6744                        final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE);
6745                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6746                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6747                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6748                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
6749                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6750                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6751
6752                        // Sanity check that provider still belongs to source package
6753                        final ProviderInfo pi = getProviderInfoLocked(
6754                                uri.getAuthority(), userHandle);
6755                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6756                            int targetUid = -1;
6757                            try {
6758                                targetUid = AppGlobals.getPackageManager()
6759                                        .getPackageUid(targetPkg, userHandle);
6760                            } catch (RemoteException e) {
6761                            }
6762                            if (targetUid != -1) {
6763                                final UriPermission perm = findOrCreateUriPermissionLocked(
6764                                        sourcePkg, targetPkg, targetUid, new GrantUri(uri, prefix));
6765                                perm.initPersistedModes(modeFlags, createdTime);
6766                            }
6767                        } else {
6768                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6769                                    + " but instead found " + pi);
6770                        }
6771                    }
6772                }
6773            }
6774        } catch (FileNotFoundException e) {
6775            // Missing grants is okay
6776        } catch (IOException e) {
6777            Log.wtf(TAG, "Failed reading Uri grants", e);
6778        } catch (XmlPullParserException e) {
6779            Log.wtf(TAG, "Failed reading Uri grants", e);
6780        } finally {
6781            IoUtils.closeQuietly(fis);
6782        }
6783    }
6784
6785    @Override
6786    public void takePersistableUriPermission(Uri uri, final int modeFlags) {
6787        enforceNotIsolatedCaller("takePersistableUriPermission");
6788
6789        Preconditions.checkFlagsArgument(modeFlags,
6790                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6791
6792        synchronized (this) {
6793            final int callingUid = Binder.getCallingUid();
6794            boolean persistChanged = false;
6795
6796            UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false));
6797            UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true));
6798
6799            final boolean exactValid = (exactPerm != null)
6800                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
6801            final boolean prefixValid = (prefixPerm != null)
6802                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
6803
6804            if (!(exactValid || prefixValid)) {
6805                throw new SecurityException("No persistable permission grants found for UID "
6806                        + callingUid + " and Uri " + uri.toSafeString());
6807            }
6808
6809            if (exactValid) {
6810                persistChanged |= exactPerm.takePersistableModes(modeFlags);
6811            }
6812            if (prefixValid) {
6813                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
6814            }
6815
6816            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6817
6818            if (persistChanged) {
6819                schedulePersistUriGrants();
6820            }
6821        }
6822    }
6823
6824    @Override
6825    public void releasePersistableUriPermission(Uri uri, final int modeFlags) {
6826        enforceNotIsolatedCaller("releasePersistableUriPermission");
6827
6828        Preconditions.checkFlagsArgument(modeFlags,
6829                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6830
6831        synchronized (this) {
6832            final int callingUid = Binder.getCallingUid();
6833            boolean persistChanged = false;
6834
6835            UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false));
6836            UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true));
6837            if (exactPerm == null && prefixPerm == null) {
6838                throw new SecurityException("No permission grants found for UID " + callingUid
6839                        + " and Uri " + uri.toSafeString());
6840            }
6841
6842            if (exactPerm != null) {
6843                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
6844                removeUriPermissionIfNeededLocked(exactPerm);
6845            }
6846            if (prefixPerm != null) {
6847                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
6848                removeUriPermissionIfNeededLocked(prefixPerm);
6849            }
6850
6851            if (persistChanged) {
6852                schedulePersistUriGrants();
6853            }
6854        }
6855    }
6856
6857    /**
6858     * Prune any older {@link UriPermission} for the given UID until outstanding
6859     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6860     *
6861     * @return if any mutations occured that require persisting.
6862     */
6863    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6864        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6865        if (perms == null) return false;
6866        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6867
6868        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6869        for (UriPermission perm : perms.values()) {
6870            if (perm.persistedModeFlags != 0) {
6871                persisted.add(perm);
6872            }
6873        }
6874
6875        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6876        if (trimCount <= 0) return false;
6877
6878        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6879        for (int i = 0; i < trimCount; i++) {
6880            final UriPermission perm = persisted.get(i);
6881
6882            if (DEBUG_URI_PERMISSION) {
6883                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6884            }
6885
6886            perm.releasePersistableModes(~0);
6887            removeUriPermissionIfNeededLocked(perm);
6888        }
6889
6890        return true;
6891    }
6892
6893    @Override
6894    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6895            String packageName, boolean incoming) {
6896        enforceNotIsolatedCaller("getPersistedUriPermissions");
6897        Preconditions.checkNotNull(packageName, "packageName");
6898
6899        final int callingUid = Binder.getCallingUid();
6900        final IPackageManager pm = AppGlobals.getPackageManager();
6901        try {
6902            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6903            if (packageUid != callingUid) {
6904                throw new SecurityException(
6905                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6906            }
6907        } catch (RemoteException e) {
6908            throw new SecurityException("Failed to verify package name ownership");
6909        }
6910
6911        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6912        synchronized (this) {
6913            if (incoming) {
6914                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6915                        callingUid);
6916                if (perms == null) {
6917                    Slog.w(TAG, "No permission grants found for " + packageName);
6918                } else {
6919                    for (UriPermission perm : perms.values()) {
6920                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6921                            result.add(perm.buildPersistedPublicApiObject());
6922                        }
6923                    }
6924                }
6925            } else {
6926                final int size = mGrantedUriPermissions.size();
6927                for (int i = 0; i < size; i++) {
6928                    final ArrayMap<GrantUri, UriPermission> perms =
6929                            mGrantedUriPermissions.valueAt(i);
6930                    for (UriPermission perm : perms.values()) {
6931                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6932                            result.add(perm.buildPersistedPublicApiObject());
6933                        }
6934                    }
6935                }
6936            }
6937        }
6938        return new ParceledListSlice<android.content.UriPermission>(result);
6939    }
6940
6941    @Override
6942    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6943        synchronized (this) {
6944            ProcessRecord app =
6945                who != null ? getRecordForAppLocked(who) : null;
6946            if (app == null) return;
6947
6948            Message msg = Message.obtain();
6949            msg.what = WAIT_FOR_DEBUGGER_MSG;
6950            msg.obj = app;
6951            msg.arg1 = waiting ? 1 : 0;
6952            mHandler.sendMessage(msg);
6953        }
6954    }
6955
6956    @Override
6957    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
6958        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
6959        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
6960        outInfo.availMem = Process.getFreeMemory();
6961        outInfo.totalMem = Process.getTotalMemory();
6962        outInfo.threshold = homeAppMem;
6963        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
6964        outInfo.hiddenAppThreshold = cachedAppMem;
6965        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
6966                ProcessList.SERVICE_ADJ);
6967        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
6968                ProcessList.VISIBLE_APP_ADJ);
6969        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
6970                ProcessList.FOREGROUND_APP_ADJ);
6971    }
6972
6973    // =========================================================
6974    // TASK MANAGEMENT
6975    // =========================================================
6976
6977    @Override
6978    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
6979        final int callingUid = Binder.getCallingUid();
6980        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
6981
6982        synchronized(this) {
6983            if (localLOGV) Slog.v(
6984                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
6985
6986            final boolean allowed = checkCallingPermission(
6987                    android.Manifest.permission.GET_TASKS)
6988                    == PackageManager.PERMISSION_GRANTED;
6989            if (!allowed) {
6990                Slog.w(TAG, "getTasks: caller " + callingUid
6991                        + " does not hold GET_TASKS; limiting output");
6992            }
6993
6994            // TODO: Improve with MRU list from all ActivityStacks.
6995            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
6996        }
6997
6998        return list;
6999    }
7000
7001    TaskRecord getMostRecentTask() {
7002        return mRecentTasks.get(0);
7003    }
7004
7005    @Override
7006    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
7007            int flags, int userId) {
7008        final int callingUid = Binder.getCallingUid();
7009        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7010                false, true, "getRecentTasks", null);
7011
7012        synchronized (this) {
7013            final boolean allowed = checkCallingPermission(
7014                    android.Manifest.permission.GET_TASKS)
7015                    == PackageManager.PERMISSION_GRANTED;
7016            if (!allowed) {
7017                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7018                        + " does not hold GET_TASKS; limiting output");
7019            }
7020            final boolean detailed = checkCallingPermission(
7021                    android.Manifest.permission.GET_DETAILED_TASKS)
7022                    == PackageManager.PERMISSION_GRANTED;
7023
7024            IPackageManager pm = AppGlobals.getPackageManager();
7025
7026            final int N = mRecentTasks.size();
7027            ArrayList<ActivityManager.RecentTaskInfo> res
7028                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7029                            maxNum < N ? maxNum : N);
7030
7031            final Set<Integer> includedUsers;
7032            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
7033                includedUsers = getProfileIdsLocked(userId);
7034            } else {
7035                includedUsers = new HashSet<Integer>();
7036            }
7037            includedUsers.add(Integer.valueOf(userId));
7038            for (int i=0; i<N && maxNum > 0; i++) {
7039                TaskRecord tr = mRecentTasks.get(i);
7040                // Only add calling user or related users recent tasks
7041                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7042
7043                // Return the entry if desired by the caller.  We always return
7044                // the first entry, because callers always expect this to be the
7045                // foreground app.  We may filter others if the caller has
7046                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7047                // we should exclude the entry.
7048
7049                if (i == 0
7050                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
7051                        || (tr.intent == null)
7052                        || ((tr.intent.getFlags()
7053                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
7054                    if (!allowed) {
7055                        // If the caller doesn't have the GET_TASKS permission, then only
7056                        // allow them to see a small subset of tasks -- their own and home.
7057                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7058                            continue;
7059                        }
7060                    }
7061                    ActivityManager.RecentTaskInfo rti
7062                            = new ActivityManager.RecentTaskInfo();
7063                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
7064                    rti.persistentId = tr.taskId;
7065                    rti.baseIntent = new Intent(
7066                            tr.intent != null ? tr.intent : tr.affinityIntent);
7067                    if (!detailed) {
7068                        rti.baseIntent.replaceExtras((Bundle)null);
7069                    }
7070                    rti.origActivity = tr.origActivity;
7071                    rti.description = tr.lastDescription;
7072                    rti.stackId = tr.stack.mStackId;
7073                    rti.userId = tr.userId;
7074
7075                    // Traverse upwards looking for any break between main task activities and
7076                    // utility activities.
7077                    final ArrayList<ActivityRecord> activities = tr.mActivities;
7078                    int activityNdx;
7079                    final int numActivities = activities.size();
7080                    for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities;
7081                            ++activityNdx) {
7082                        final ActivityRecord r = activities.get(activityNdx);
7083                        if (r.intent != null &&
7084                                (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET)
7085                                        != 0) {
7086                            break;
7087                        }
7088                    }
7089                    if (activityNdx > 0) {
7090                        // Traverse downwards starting below break looking for set label, icon.
7091                        // Note that if there are activities in the task but none of them set the
7092                        // recent activity values, then we do not fall back to the last set
7093                        // values in the TaskRecord.
7094                        rti.activityValues = new ActivityManager.RecentsActivityValues();
7095                        for (--activityNdx; activityNdx >= 0; --activityNdx) {
7096                            final ActivityRecord r = activities.get(activityNdx);
7097                            if (r.activityValues != null) {
7098                                if (rti.activityValues.label == null) {
7099                                    rti.activityValues.label = r.activityValues.label;
7100                                    tr.lastActivityValues.label = r.activityValues.label;
7101                                }
7102                                if (rti.activityValues.icon == null) {
7103                                    rti.activityValues.icon = r.activityValues.icon;
7104                                    tr.lastActivityValues.icon = r.activityValues.icon;
7105                                }
7106                                if (rti.activityValues.colorPrimary == 0) {
7107                                    rti.activityValues.colorPrimary = r.activityValues.colorPrimary;
7108                                    tr.lastActivityValues.colorPrimary = r.activityValues.colorPrimary;
7109                                }
7110                            }
7111                        }
7112                    } else {
7113                        // If there are no activity records in this task, then we use the last
7114                        // resolved values
7115                        rti.activityValues =
7116                                new ActivityManager.RecentsActivityValues(tr.lastActivityValues);
7117                    }
7118
7119                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7120                        // Check whether this activity is currently available.
7121                        try {
7122                            if (rti.origActivity != null) {
7123                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7124                                        == null) {
7125                                    continue;
7126                                }
7127                            } else if (rti.baseIntent != null) {
7128                                if (pm.queryIntentActivities(rti.baseIntent,
7129                                        null, 0, userId) == null) {
7130                                    continue;
7131                                }
7132                            }
7133                        } catch (RemoteException e) {
7134                            // Will never happen.
7135                        }
7136                    }
7137
7138                    res.add(rti);
7139                    maxNum--;
7140                }
7141            }
7142            return res;
7143        }
7144    }
7145
7146    private TaskRecord recentTaskForIdLocked(int id) {
7147        final int N = mRecentTasks.size();
7148            for (int i=0; i<N; i++) {
7149                TaskRecord tr = mRecentTasks.get(i);
7150                if (tr.taskId == id) {
7151                    return tr;
7152                }
7153            }
7154            return null;
7155    }
7156
7157    @Override
7158    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
7159        synchronized (this) {
7160            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7161                    "getTaskThumbnails()");
7162            TaskRecord tr = recentTaskForIdLocked(id);
7163            if (tr != null) {
7164                return tr.getTaskThumbnailsLocked();
7165            }
7166        }
7167        return null;
7168    }
7169
7170    @Override
7171    public Bitmap getTaskTopThumbnail(int id) {
7172        synchronized (this) {
7173            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7174                    "getTaskTopThumbnail()");
7175            TaskRecord tr = recentTaskForIdLocked(id);
7176            if (tr != null) {
7177                return tr.getTaskTopThumbnailLocked();
7178            }
7179        }
7180        return null;
7181    }
7182
7183    @Override
7184    public void setRecentsActivityValues(IBinder token, ActivityManager.RecentsActivityValues rav) {
7185        synchronized (this) {
7186            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7187            if (r != null) {
7188                r.activityValues = rav;
7189            }
7190        }
7191    }
7192
7193    @Override
7194    public boolean removeSubTask(int taskId, int subTaskIndex) {
7195        synchronized (this) {
7196            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7197                    "removeSubTask()");
7198            long ident = Binder.clearCallingIdentity();
7199            try {
7200                TaskRecord tr = recentTaskForIdLocked(taskId);
7201                if (tr != null) {
7202                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
7203                }
7204                return false;
7205            } finally {
7206                Binder.restoreCallingIdentity(ident);
7207            }
7208        }
7209    }
7210
7211    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7212        if (!pr.killedByAm) {
7213            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7214            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7215                    pr.processName, pr.setAdj, reason);
7216            pr.killedByAm = true;
7217            Process.killProcessQuiet(pr.pid);
7218        }
7219    }
7220
7221    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7222        tr.disposeThumbnail();
7223        mRecentTasks.remove(tr);
7224        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7225        Intent baseIntent = new Intent(
7226                tr.intent != null ? tr.intent : tr.affinityIntent);
7227        ComponentName component = baseIntent.getComponent();
7228        if (component == null) {
7229            Slog.w(TAG, "Now component for base intent of task: " + tr);
7230            return;
7231        }
7232
7233        // Find any running services associated with this app.
7234        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7235
7236        if (killProcesses) {
7237            // Find any running processes associated with this app.
7238            final String pkg = component.getPackageName();
7239            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7240            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7241            for (int i=0; i<pmap.size(); i++) {
7242                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7243                for (int j=0; j<uids.size(); j++) {
7244                    ProcessRecord proc = uids.valueAt(j);
7245                    if (proc.userId != tr.userId) {
7246                        continue;
7247                    }
7248                    if (!proc.pkgList.containsKey(pkg)) {
7249                        continue;
7250                    }
7251                    procs.add(proc);
7252                }
7253            }
7254
7255            // Kill the running processes.
7256            for (int i=0; i<procs.size(); i++) {
7257                ProcessRecord pr = procs.get(i);
7258                if (pr == mHomeProcess) {
7259                    // Don't kill the home process along with tasks from the same package.
7260                    continue;
7261                }
7262                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7263                    killUnneededProcessLocked(pr, "remove task");
7264                } else {
7265                    pr.waitingToKill = "remove task";
7266                }
7267            }
7268        }
7269    }
7270
7271    /**
7272     * Removes the task with the specified task id.
7273     *
7274     * @param taskId Identifier of the task to be removed.
7275     * @param flags Additional operational flags.  May be 0 or
7276     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7277     * @return Returns true if the given task was found and removed.
7278     */
7279    private boolean removeTaskByIdLocked(int taskId, int flags) {
7280        TaskRecord tr = recentTaskForIdLocked(taskId);
7281        if (tr != null) {
7282            tr.removeTaskActivitiesLocked(-1, false);
7283            cleanUpRemovedTaskLocked(tr, flags);
7284            return true;
7285        }
7286        return false;
7287    }
7288
7289    @Override
7290    public boolean removeTask(int taskId, int flags) {
7291        synchronized (this) {
7292            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7293                    "removeTask()");
7294            long ident = Binder.clearCallingIdentity();
7295            try {
7296                return removeTaskByIdLocked(taskId, flags);
7297            } finally {
7298                Binder.restoreCallingIdentity(ident);
7299            }
7300        }
7301    }
7302
7303    /**
7304     * TODO: Add mController hook
7305     */
7306    @Override
7307    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7308        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7309                "moveTaskToFront()");
7310
7311        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7312        synchronized(this) {
7313            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7314                    Binder.getCallingUid(), "Task to front")) {
7315                ActivityOptions.abort(options);
7316                return;
7317            }
7318            final long origId = Binder.clearCallingIdentity();
7319            try {
7320                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7321                if (task == null) {
7322                    return;
7323                }
7324                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7325                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7326                    return;
7327                }
7328                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7329            } finally {
7330                Binder.restoreCallingIdentity(origId);
7331            }
7332            ActivityOptions.abort(options);
7333        }
7334    }
7335
7336    @Override
7337    public void moveTaskToBack(int taskId) {
7338        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7339                "moveTaskToBack()");
7340
7341        synchronized(this) {
7342            TaskRecord tr = recentTaskForIdLocked(taskId);
7343            if (tr != null) {
7344                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7345                ActivityStack stack = tr.stack;
7346                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7347                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7348                            Binder.getCallingUid(), "Task to back")) {
7349                        return;
7350                    }
7351                }
7352                final long origId = Binder.clearCallingIdentity();
7353                try {
7354                    stack.moveTaskToBackLocked(taskId, null);
7355                } finally {
7356                    Binder.restoreCallingIdentity(origId);
7357                }
7358            }
7359        }
7360    }
7361
7362    /**
7363     * Moves an activity, and all of the other activities within the same task, to the bottom
7364     * of the history stack.  The activity's order within the task is unchanged.
7365     *
7366     * @param token A reference to the activity we wish to move
7367     * @param nonRoot If false then this only works if the activity is the root
7368     *                of a task; if true it will work for any activity in a task.
7369     * @return Returns true if the move completed, false if not.
7370     */
7371    @Override
7372    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7373        enforceNotIsolatedCaller("moveActivityTaskToBack");
7374        synchronized(this) {
7375            final long origId = Binder.clearCallingIdentity();
7376            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7377            if (taskId >= 0) {
7378                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7379            }
7380            Binder.restoreCallingIdentity(origId);
7381        }
7382        return false;
7383    }
7384
7385    @Override
7386    public void moveTaskBackwards(int task) {
7387        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7388                "moveTaskBackwards()");
7389
7390        synchronized(this) {
7391            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7392                    Binder.getCallingUid(), "Task backwards")) {
7393                return;
7394            }
7395            final long origId = Binder.clearCallingIdentity();
7396            moveTaskBackwardsLocked(task);
7397            Binder.restoreCallingIdentity(origId);
7398        }
7399    }
7400
7401    private final void moveTaskBackwardsLocked(int task) {
7402        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7403    }
7404
7405    @Override
7406    public IBinder getHomeActivityToken() throws RemoteException {
7407        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7408                "getHomeActivityToken()");
7409        synchronized (this) {
7410            return mStackSupervisor.getHomeActivityToken();
7411        }
7412    }
7413
7414    @Override
7415    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7416            IActivityContainerCallback callback) throws RemoteException {
7417        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7418                "createActivityContainer()");
7419        synchronized (this) {
7420            if (parentActivityToken == null) {
7421                throw new IllegalArgumentException("parent token must not be null");
7422            }
7423            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7424            if (r == null) {
7425                return null;
7426            }
7427            if (callback == null) {
7428                throw new IllegalArgumentException("callback must not be null");
7429            }
7430            return mStackSupervisor.createActivityContainer(r, callback);
7431        }
7432    }
7433
7434    @Override
7435    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7436        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7437                "deleteActivityContainer()");
7438        synchronized (this) {
7439            mStackSupervisor.deleteActivityContainer(container);
7440        }
7441    }
7442
7443    @Override
7444    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7445            throws RemoteException {
7446        synchronized (this) {
7447            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7448            if (stack != null) {
7449                return stack.mActivityContainer;
7450            }
7451            return null;
7452        }
7453    }
7454
7455    @Override
7456    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7457        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7458                "moveTaskToStack()");
7459        if (stackId == HOME_STACK_ID) {
7460            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7461                    new RuntimeException("here").fillInStackTrace());
7462        }
7463        synchronized (this) {
7464            long ident = Binder.clearCallingIdentity();
7465            try {
7466                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7467                        + stackId + " toTop=" + toTop);
7468                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7469            } finally {
7470                Binder.restoreCallingIdentity(ident);
7471            }
7472        }
7473    }
7474
7475    @Override
7476    public void resizeStack(int stackBoxId, Rect bounds) {
7477        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7478                "resizeStackBox()");
7479        long ident = Binder.clearCallingIdentity();
7480        try {
7481            mWindowManager.resizeStack(stackBoxId, bounds);
7482        } finally {
7483            Binder.restoreCallingIdentity(ident);
7484        }
7485    }
7486
7487    @Override
7488    public List<StackInfo> getAllStackInfos() {
7489        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7490                "getAllStackInfos()");
7491        long ident = Binder.clearCallingIdentity();
7492        try {
7493            synchronized (this) {
7494                return mStackSupervisor.getAllStackInfosLocked();
7495            }
7496        } finally {
7497            Binder.restoreCallingIdentity(ident);
7498        }
7499    }
7500
7501    @Override
7502    public StackInfo getStackInfo(int stackId) {
7503        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7504                "getStackInfo()");
7505        long ident = Binder.clearCallingIdentity();
7506        try {
7507            synchronized (this) {
7508                return mStackSupervisor.getStackInfoLocked(stackId);
7509            }
7510        } finally {
7511            Binder.restoreCallingIdentity(ident);
7512        }
7513    }
7514
7515    @Override
7516    public boolean isInHomeStack(int taskId) {
7517        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7518                "getStackInfo()");
7519        long ident = Binder.clearCallingIdentity();
7520        try {
7521            synchronized (this) {
7522                TaskRecord tr = recentTaskForIdLocked(taskId);
7523                if (tr != null) {
7524                    return tr.stack.isHomeStack();
7525                }
7526            }
7527        } finally {
7528            Binder.restoreCallingIdentity(ident);
7529        }
7530        return false;
7531    }
7532
7533    @Override
7534    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7535        synchronized(this) {
7536            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7537        }
7538    }
7539
7540    private boolean isLockTaskAuthorized(ComponentName name) {
7541//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7542//                "startLockTaskMode()");
7543//        DevicePolicyManager dpm = (DevicePolicyManager)
7544//                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7545//        return dpm != null && dpm.isLockTaskPermitted(name);
7546        return true;
7547    }
7548
7549    private void startLockTaskMode(TaskRecord task) {
7550        if (!isLockTaskAuthorized(task.intent.getComponent())) {
7551            return;
7552        }
7553        long ident = Binder.clearCallingIdentity();
7554        try {
7555            synchronized (this) {
7556                // Since we lost lock on task, make sure it is still there.
7557                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7558                if (task != null) {
7559                    mStackSupervisor.setLockTaskModeLocked(task);
7560                }
7561            }
7562        } finally {
7563            Binder.restoreCallingIdentity(ident);
7564        }
7565    }
7566
7567    @Override
7568    public void startLockTaskMode(int taskId) {
7569        long ident = Binder.clearCallingIdentity();
7570        try {
7571            final TaskRecord task;
7572            synchronized (this) {
7573                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7574            }
7575            if (task != null) {
7576                startLockTaskMode(task);
7577            }
7578        } finally {
7579            Binder.restoreCallingIdentity(ident);
7580        }
7581    }
7582
7583    @Override
7584    public void startLockTaskMode(IBinder token) {
7585        long ident = Binder.clearCallingIdentity();
7586        try {
7587            final TaskRecord task;
7588            synchronized (this) {
7589                final ActivityRecord r = ActivityRecord.forToken(token);
7590                if (r == null) {
7591                    return;
7592                }
7593                task = r.task;
7594            }
7595            if (task != null) {
7596                startLockTaskMode(task);
7597            }
7598        } finally {
7599            Binder.restoreCallingIdentity(ident);
7600        }
7601    }
7602
7603    @Override
7604    public void stopLockTaskMode() {
7605//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7606//                "stopLockTaskMode()");
7607        synchronized (this) {
7608            mStackSupervisor.setLockTaskModeLocked(null);
7609        }
7610    }
7611
7612    @Override
7613    public boolean isInLockTaskMode() {
7614        synchronized (this) {
7615            return mStackSupervisor.isInLockTaskMode();
7616        }
7617    }
7618
7619    // =========================================================
7620    // CONTENT PROVIDERS
7621    // =========================================================
7622
7623    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7624        List<ProviderInfo> providers = null;
7625        try {
7626            providers = AppGlobals.getPackageManager().
7627                queryContentProviders(app.processName, app.uid,
7628                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7629        } catch (RemoteException ex) {
7630        }
7631        if (DEBUG_MU)
7632            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7633        int userId = app.userId;
7634        if (providers != null) {
7635            int N = providers.size();
7636            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7637            for (int i=0; i<N; i++) {
7638                ProviderInfo cpi =
7639                    (ProviderInfo)providers.get(i);
7640                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7641                        cpi.name, cpi.flags);
7642                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7643                    // This is a singleton provider, but a user besides the
7644                    // default user is asking to initialize a process it runs
7645                    // in...  well, no, it doesn't actually run in this process,
7646                    // it runs in the process of the default user.  Get rid of it.
7647                    providers.remove(i);
7648                    N--;
7649                    i--;
7650                    continue;
7651                }
7652
7653                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7654                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7655                if (cpr == null) {
7656                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7657                    mProviderMap.putProviderByClass(comp, cpr);
7658                }
7659                if (DEBUG_MU)
7660                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7661                app.pubProviders.put(cpi.name, cpr);
7662                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7663                    // Don't add this if it is a platform component that is marked
7664                    // to run in multiple processes, because this is actually
7665                    // part of the framework so doesn't make sense to track as a
7666                    // separate apk in the process.
7667                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7668                }
7669                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7670            }
7671        }
7672        return providers;
7673    }
7674
7675    /**
7676     * Check if {@link ProcessRecord} has a possible chance at accessing the
7677     * given {@link ProviderInfo}. Final permission checking is always done
7678     * in {@link ContentProvider}.
7679     */
7680    private final String checkContentProviderPermissionLocked(
7681            ProviderInfo cpi, ProcessRecord r) {
7682        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7683        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7684        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7685                cpi.applicationInfo.uid, cpi.exported)
7686                == PackageManager.PERMISSION_GRANTED) {
7687            return null;
7688        }
7689        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7690                cpi.applicationInfo.uid, cpi.exported)
7691                == PackageManager.PERMISSION_GRANTED) {
7692            return null;
7693        }
7694
7695        PathPermission[] pps = cpi.pathPermissions;
7696        if (pps != null) {
7697            int i = pps.length;
7698            while (i > 0) {
7699                i--;
7700                PathPermission pp = pps[i];
7701                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7702                        cpi.applicationInfo.uid, cpi.exported)
7703                        == PackageManager.PERMISSION_GRANTED) {
7704                    return null;
7705                }
7706                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7707                        cpi.applicationInfo.uid, cpi.exported)
7708                        == PackageManager.PERMISSION_GRANTED) {
7709                    return null;
7710                }
7711            }
7712        }
7713
7714        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7715        if (perms != null) {
7716            for (GrantUri uri : perms.keySet()) {
7717                if (uri.uri.getAuthority().equals(cpi.authority)) {
7718                    return null;
7719                }
7720            }
7721        }
7722
7723        String msg;
7724        if (!cpi.exported) {
7725            msg = "Permission Denial: opening provider " + cpi.name
7726                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7727                    + ", uid=" + callingUid + ") that is not exported from uid "
7728                    + cpi.applicationInfo.uid;
7729        } else {
7730            msg = "Permission Denial: opening provider " + cpi.name
7731                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7732                    + ", uid=" + callingUid + ") requires "
7733                    + cpi.readPermission + " or " + cpi.writePermission;
7734        }
7735        Slog.w(TAG, msg);
7736        return msg;
7737    }
7738
7739    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7740            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7741        if (r != null) {
7742            for (int i=0; i<r.conProviders.size(); i++) {
7743                ContentProviderConnection conn = r.conProviders.get(i);
7744                if (conn.provider == cpr) {
7745                    if (DEBUG_PROVIDER) Slog.v(TAG,
7746                            "Adding provider requested by "
7747                            + r.processName + " from process "
7748                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7749                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7750                    if (stable) {
7751                        conn.stableCount++;
7752                        conn.numStableIncs++;
7753                    } else {
7754                        conn.unstableCount++;
7755                        conn.numUnstableIncs++;
7756                    }
7757                    return conn;
7758                }
7759            }
7760            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7761            if (stable) {
7762                conn.stableCount = 1;
7763                conn.numStableIncs = 1;
7764            } else {
7765                conn.unstableCount = 1;
7766                conn.numUnstableIncs = 1;
7767            }
7768            cpr.connections.add(conn);
7769            r.conProviders.add(conn);
7770            return conn;
7771        }
7772        cpr.addExternalProcessHandleLocked(externalProcessToken);
7773        return null;
7774    }
7775
7776    boolean decProviderCountLocked(ContentProviderConnection conn,
7777            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7778        if (conn != null) {
7779            cpr = conn.provider;
7780            if (DEBUG_PROVIDER) Slog.v(TAG,
7781                    "Removing provider requested by "
7782                    + conn.client.processName + " from process "
7783                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7784                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7785            if (stable) {
7786                conn.stableCount--;
7787            } else {
7788                conn.unstableCount--;
7789            }
7790            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7791                cpr.connections.remove(conn);
7792                conn.client.conProviders.remove(conn);
7793                return true;
7794            }
7795            return false;
7796        }
7797        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7798        return false;
7799    }
7800
7801    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7802            String name, IBinder token, boolean stable, int userId) {
7803        ContentProviderRecord cpr;
7804        ContentProviderConnection conn = null;
7805        ProviderInfo cpi = null;
7806
7807        synchronized(this) {
7808            ProcessRecord r = null;
7809            if (caller != null) {
7810                r = getRecordForAppLocked(caller);
7811                if (r == null) {
7812                    throw new SecurityException(
7813                            "Unable to find app for caller " + caller
7814                          + " (pid=" + Binder.getCallingPid()
7815                          + ") when getting content provider " + name);
7816                }
7817            }
7818
7819            // First check if this content provider has been published...
7820            cpr = mProviderMap.getProviderByName(name, userId);
7821            boolean providerRunning = cpr != null;
7822            if (providerRunning) {
7823                cpi = cpr.info;
7824                String msg;
7825                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7826                    throw new SecurityException(msg);
7827                }
7828
7829                if (r != null && cpr.canRunHere(r)) {
7830                    // This provider has been published or is in the process
7831                    // of being published...  but it is also allowed to run
7832                    // in the caller's process, so don't make a connection
7833                    // and just let the caller instantiate its own instance.
7834                    ContentProviderHolder holder = cpr.newHolder(null);
7835                    // don't give caller the provider object, it needs
7836                    // to make its own.
7837                    holder.provider = null;
7838                    return holder;
7839                }
7840
7841                final long origId = Binder.clearCallingIdentity();
7842
7843                // In this case the provider instance already exists, so we can
7844                // return it right away.
7845                conn = incProviderCountLocked(r, cpr, token, stable);
7846                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7847                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7848                        // If this is a perceptible app accessing the provider,
7849                        // make sure to count it as being accessed and thus
7850                        // back up on the LRU list.  This is good because
7851                        // content providers are often expensive to start.
7852                        updateLruProcessLocked(cpr.proc, false, null);
7853                    }
7854                }
7855
7856                if (cpr.proc != null) {
7857                    if (false) {
7858                        if (cpr.name.flattenToShortString().equals(
7859                                "com.android.providers.calendar/.CalendarProvider2")) {
7860                            Slog.v(TAG, "****************** KILLING "
7861                                + cpr.name.flattenToShortString());
7862                            Process.killProcess(cpr.proc.pid);
7863                        }
7864                    }
7865                    boolean success = updateOomAdjLocked(cpr.proc);
7866                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7867                    // NOTE: there is still a race here where a signal could be
7868                    // pending on the process even though we managed to update its
7869                    // adj level.  Not sure what to do about this, but at least
7870                    // the race is now smaller.
7871                    if (!success) {
7872                        // Uh oh...  it looks like the provider's process
7873                        // has been killed on us.  We need to wait for a new
7874                        // process to be started, and make sure its death
7875                        // doesn't kill our process.
7876                        Slog.i(TAG,
7877                                "Existing provider " + cpr.name.flattenToShortString()
7878                                + " is crashing; detaching " + r);
7879                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7880                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7881                        if (!lastRef) {
7882                            // This wasn't the last ref our process had on
7883                            // the provider...  we have now been killed, bail.
7884                            return null;
7885                        }
7886                        providerRunning = false;
7887                        conn = null;
7888                    }
7889                }
7890
7891                Binder.restoreCallingIdentity(origId);
7892            }
7893
7894            boolean singleton;
7895            if (!providerRunning) {
7896                try {
7897                    cpi = AppGlobals.getPackageManager().
7898                        resolveContentProvider(name,
7899                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7900                } catch (RemoteException ex) {
7901                }
7902                if (cpi == null) {
7903                    return null;
7904                }
7905                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7906                        cpi.name, cpi.flags);
7907                if (singleton) {
7908                    userId = 0;
7909                }
7910                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7911
7912                String msg;
7913                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7914                    throw new SecurityException(msg);
7915                }
7916
7917                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
7918                        && !cpi.processName.equals("system")) {
7919                    // If this content provider does not run in the system
7920                    // process, and the system is not yet ready to run other
7921                    // processes, then fail fast instead of hanging.
7922                    throw new IllegalArgumentException(
7923                            "Attempt to launch content provider before system ready");
7924                }
7925
7926                // Make sure that the user who owns this provider is started.  If not,
7927                // we don't want to allow it to run.
7928                if (mStartedUsers.get(userId) == null) {
7929                    Slog.w(TAG, "Unable to launch app "
7930                            + cpi.applicationInfo.packageName + "/"
7931                            + cpi.applicationInfo.uid + " for provider "
7932                            + name + ": user " + userId + " is stopped");
7933                    return null;
7934                }
7935
7936                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7937                cpr = mProviderMap.getProviderByClass(comp, userId);
7938                final boolean firstClass = cpr == null;
7939                if (firstClass) {
7940                    try {
7941                        ApplicationInfo ai =
7942                            AppGlobals.getPackageManager().
7943                                getApplicationInfo(
7944                                        cpi.applicationInfo.packageName,
7945                                        STOCK_PM_FLAGS, userId);
7946                        if (ai == null) {
7947                            Slog.w(TAG, "No package info for content provider "
7948                                    + cpi.name);
7949                            return null;
7950                        }
7951                        ai = getAppInfoForUser(ai, userId);
7952                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
7953                    } catch (RemoteException ex) {
7954                        // pm is in same process, this will never happen.
7955                    }
7956                }
7957
7958                if (r != null && cpr.canRunHere(r)) {
7959                    // If this is a multiprocess provider, then just return its
7960                    // info and allow the caller to instantiate it.  Only do
7961                    // this if the provider is the same user as the caller's
7962                    // process, or can run as root (so can be in any process).
7963                    return cpr.newHolder(null);
7964                }
7965
7966                if (DEBUG_PROVIDER) {
7967                    RuntimeException e = new RuntimeException("here");
7968                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
7969                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
7970                }
7971
7972                // This is single process, and our app is now connecting to it.
7973                // See if we are already in the process of launching this
7974                // provider.
7975                final int N = mLaunchingProviders.size();
7976                int i;
7977                for (i=0; i<N; i++) {
7978                    if (mLaunchingProviders.get(i) == cpr) {
7979                        break;
7980                    }
7981                }
7982
7983                // If the provider is not already being launched, then get it
7984                // started.
7985                if (i >= N) {
7986                    final long origId = Binder.clearCallingIdentity();
7987
7988                    try {
7989                        // Content provider is now in use, its package can't be stopped.
7990                        try {
7991                            AppGlobals.getPackageManager().setPackageStoppedState(
7992                                    cpr.appInfo.packageName, false, userId);
7993                        } catch (RemoteException e) {
7994                        } catch (IllegalArgumentException e) {
7995                            Slog.w(TAG, "Failed trying to unstop package "
7996                                    + cpr.appInfo.packageName + ": " + e);
7997                        }
7998
7999                        // Use existing process if already started
8000                        ProcessRecord proc = getProcessRecordLocked(
8001                                cpi.processName, cpr.appInfo.uid, false);
8002                        if (proc != null && proc.thread != null) {
8003                            if (DEBUG_PROVIDER) {
8004                                Slog.d(TAG, "Installing in existing process " + proc);
8005                            }
8006                            proc.pubProviders.put(cpi.name, cpr);
8007                            try {
8008                                proc.thread.scheduleInstallProvider(cpi);
8009                            } catch (RemoteException e) {
8010                            }
8011                        } else {
8012                            proc = startProcessLocked(cpi.processName,
8013                                    cpr.appInfo, false, 0, "content provider",
8014                                    new ComponentName(cpi.applicationInfo.packageName,
8015                                            cpi.name), false, false, false);
8016                            if (proc == null) {
8017                                Slog.w(TAG, "Unable to launch app "
8018                                        + cpi.applicationInfo.packageName + "/"
8019                                        + cpi.applicationInfo.uid + " for provider "
8020                                        + name + ": process is bad");
8021                                return null;
8022                            }
8023                        }
8024                        cpr.launchingApp = proc;
8025                        mLaunchingProviders.add(cpr);
8026                    } finally {
8027                        Binder.restoreCallingIdentity(origId);
8028                    }
8029                }
8030
8031                // Make sure the provider is published (the same provider class
8032                // may be published under multiple names).
8033                if (firstClass) {
8034                    mProviderMap.putProviderByClass(comp, cpr);
8035                }
8036
8037                mProviderMap.putProviderByName(name, cpr);
8038                conn = incProviderCountLocked(r, cpr, token, stable);
8039                if (conn != null) {
8040                    conn.waiting = true;
8041                }
8042            }
8043        }
8044
8045        // Wait for the provider to be published...
8046        synchronized (cpr) {
8047            while (cpr.provider == null) {
8048                if (cpr.launchingApp == null) {
8049                    Slog.w(TAG, "Unable to launch app "
8050                            + cpi.applicationInfo.packageName + "/"
8051                            + cpi.applicationInfo.uid + " for provider "
8052                            + name + ": launching app became null");
8053                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8054                            UserHandle.getUserId(cpi.applicationInfo.uid),
8055                            cpi.applicationInfo.packageName,
8056                            cpi.applicationInfo.uid, name);
8057                    return null;
8058                }
8059                try {
8060                    if (DEBUG_MU) {
8061                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8062                                + cpr.launchingApp);
8063                    }
8064                    if (conn != null) {
8065                        conn.waiting = true;
8066                    }
8067                    cpr.wait();
8068                } catch (InterruptedException ex) {
8069                } finally {
8070                    if (conn != null) {
8071                        conn.waiting = false;
8072                    }
8073                }
8074            }
8075        }
8076        return cpr != null ? cpr.newHolder(conn) : null;
8077    }
8078
8079    public final ContentProviderHolder getContentProvider(
8080            IApplicationThread caller, String name, int userId, boolean stable) {
8081        enforceNotIsolatedCaller("getContentProvider");
8082        if (caller == null) {
8083            String msg = "null IApplicationThread when getting content provider "
8084                    + name;
8085            Slog.w(TAG, msg);
8086            throw new SecurityException(msg);
8087        }
8088
8089        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8090                false, true, "getContentProvider", null);
8091        return getContentProviderImpl(caller, name, null, stable, userId);
8092    }
8093
8094    public ContentProviderHolder getContentProviderExternal(
8095            String name, int userId, IBinder token) {
8096        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8097            "Do not have permission in call getContentProviderExternal()");
8098        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8099                false, true, "getContentProvider", null);
8100        return getContentProviderExternalUnchecked(name, token, userId);
8101    }
8102
8103    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8104            IBinder token, int userId) {
8105        return getContentProviderImpl(null, name, token, true, userId);
8106    }
8107
8108    /**
8109     * Drop a content provider from a ProcessRecord's bookkeeping
8110     */
8111    public void removeContentProvider(IBinder connection, boolean stable) {
8112        enforceNotIsolatedCaller("removeContentProvider");
8113        long ident = Binder.clearCallingIdentity();
8114        try {
8115            synchronized (this) {
8116                ContentProviderConnection conn;
8117                try {
8118                    conn = (ContentProviderConnection)connection;
8119                } catch (ClassCastException e) {
8120                    String msg ="removeContentProvider: " + connection
8121                            + " not a ContentProviderConnection";
8122                    Slog.w(TAG, msg);
8123                    throw new IllegalArgumentException(msg);
8124                }
8125                if (conn == null) {
8126                    throw new NullPointerException("connection is null");
8127                }
8128                if (decProviderCountLocked(conn, null, null, stable)) {
8129                    updateOomAdjLocked();
8130                }
8131            }
8132        } finally {
8133            Binder.restoreCallingIdentity(ident);
8134        }
8135    }
8136
8137    public void removeContentProviderExternal(String name, IBinder token) {
8138        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8139            "Do not have permission in call removeContentProviderExternal()");
8140        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8141    }
8142
8143    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8144        synchronized (this) {
8145            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8146            if(cpr == null) {
8147                //remove from mProvidersByClass
8148                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8149                return;
8150            }
8151
8152            //update content provider record entry info
8153            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8154            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8155            if (localCpr.hasExternalProcessHandles()) {
8156                if (localCpr.removeExternalProcessHandleLocked(token)) {
8157                    updateOomAdjLocked();
8158                } else {
8159                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8160                            + " with no external reference for token: "
8161                            + token + ".");
8162                }
8163            } else {
8164                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8165                        + " with no external references.");
8166            }
8167        }
8168    }
8169
8170    public final void publishContentProviders(IApplicationThread caller,
8171            List<ContentProviderHolder> providers) {
8172        if (providers == null) {
8173            return;
8174        }
8175
8176        enforceNotIsolatedCaller("publishContentProviders");
8177        synchronized (this) {
8178            final ProcessRecord r = getRecordForAppLocked(caller);
8179            if (DEBUG_MU)
8180                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8181            if (r == null) {
8182                throw new SecurityException(
8183                        "Unable to find app for caller " + caller
8184                      + " (pid=" + Binder.getCallingPid()
8185                      + ") when publishing content providers");
8186            }
8187
8188            final long origId = Binder.clearCallingIdentity();
8189
8190            final int N = providers.size();
8191            for (int i=0; i<N; i++) {
8192                ContentProviderHolder src = providers.get(i);
8193                if (src == null || src.info == null || src.provider == null) {
8194                    continue;
8195                }
8196                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8197                if (DEBUG_MU)
8198                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8199                if (dst != null) {
8200                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8201                    mProviderMap.putProviderByClass(comp, dst);
8202                    String names[] = dst.info.authority.split(";");
8203                    for (int j = 0; j < names.length; j++) {
8204                        mProviderMap.putProviderByName(names[j], dst);
8205                    }
8206
8207                    int NL = mLaunchingProviders.size();
8208                    int j;
8209                    for (j=0; j<NL; j++) {
8210                        if (mLaunchingProviders.get(j) == dst) {
8211                            mLaunchingProviders.remove(j);
8212                            j--;
8213                            NL--;
8214                        }
8215                    }
8216                    synchronized (dst) {
8217                        dst.provider = src.provider;
8218                        dst.proc = r;
8219                        dst.notifyAll();
8220                    }
8221                    updateOomAdjLocked(r);
8222                }
8223            }
8224
8225            Binder.restoreCallingIdentity(origId);
8226        }
8227    }
8228
8229    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8230        ContentProviderConnection conn;
8231        try {
8232            conn = (ContentProviderConnection)connection;
8233        } catch (ClassCastException e) {
8234            String msg ="refContentProvider: " + connection
8235                    + " not a ContentProviderConnection";
8236            Slog.w(TAG, msg);
8237            throw new IllegalArgumentException(msg);
8238        }
8239        if (conn == null) {
8240            throw new NullPointerException("connection is null");
8241        }
8242
8243        synchronized (this) {
8244            if (stable > 0) {
8245                conn.numStableIncs += stable;
8246            }
8247            stable = conn.stableCount + stable;
8248            if (stable < 0) {
8249                throw new IllegalStateException("stableCount < 0: " + stable);
8250            }
8251
8252            if (unstable > 0) {
8253                conn.numUnstableIncs += unstable;
8254            }
8255            unstable = conn.unstableCount + unstable;
8256            if (unstable < 0) {
8257                throw new IllegalStateException("unstableCount < 0: " + unstable);
8258            }
8259
8260            if ((stable+unstable) <= 0) {
8261                throw new IllegalStateException("ref counts can't go to zero here: stable="
8262                        + stable + " unstable=" + unstable);
8263            }
8264            conn.stableCount = stable;
8265            conn.unstableCount = unstable;
8266            return !conn.dead;
8267        }
8268    }
8269
8270    public void unstableProviderDied(IBinder connection) {
8271        ContentProviderConnection conn;
8272        try {
8273            conn = (ContentProviderConnection)connection;
8274        } catch (ClassCastException e) {
8275            String msg ="refContentProvider: " + connection
8276                    + " not a ContentProviderConnection";
8277            Slog.w(TAG, msg);
8278            throw new IllegalArgumentException(msg);
8279        }
8280        if (conn == null) {
8281            throw new NullPointerException("connection is null");
8282        }
8283
8284        // Safely retrieve the content provider associated with the connection.
8285        IContentProvider provider;
8286        synchronized (this) {
8287            provider = conn.provider.provider;
8288        }
8289
8290        if (provider == null) {
8291            // Um, yeah, we're way ahead of you.
8292            return;
8293        }
8294
8295        // Make sure the caller is being honest with us.
8296        if (provider.asBinder().pingBinder()) {
8297            // Er, no, still looks good to us.
8298            synchronized (this) {
8299                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8300                        + " says " + conn + " died, but we don't agree");
8301                return;
8302            }
8303        }
8304
8305        // Well look at that!  It's dead!
8306        synchronized (this) {
8307            if (conn.provider.provider != provider) {
8308                // But something changed...  good enough.
8309                return;
8310            }
8311
8312            ProcessRecord proc = conn.provider.proc;
8313            if (proc == null || proc.thread == null) {
8314                // Seems like the process is already cleaned up.
8315                return;
8316            }
8317
8318            // As far as we're concerned, this is just like receiving a
8319            // death notification...  just a bit prematurely.
8320            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8321                    + ") early provider death");
8322            final long ident = Binder.clearCallingIdentity();
8323            try {
8324                appDiedLocked(proc, proc.pid, proc.thread);
8325            } finally {
8326                Binder.restoreCallingIdentity(ident);
8327            }
8328        }
8329    }
8330
8331    @Override
8332    public void appNotRespondingViaProvider(IBinder connection) {
8333        enforceCallingPermission(
8334                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8335
8336        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8337        if (conn == null) {
8338            Slog.w(TAG, "ContentProviderConnection is null");
8339            return;
8340        }
8341
8342        final ProcessRecord host = conn.provider.proc;
8343        if (host == null) {
8344            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8345            return;
8346        }
8347
8348        final long token = Binder.clearCallingIdentity();
8349        try {
8350            appNotResponding(host, null, null, false, "ContentProvider not responding");
8351        } finally {
8352            Binder.restoreCallingIdentity(token);
8353        }
8354    }
8355
8356    public final void installSystemProviders() {
8357        List<ProviderInfo> providers;
8358        synchronized (this) {
8359            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8360            providers = generateApplicationProvidersLocked(app);
8361            if (providers != null) {
8362                for (int i=providers.size()-1; i>=0; i--) {
8363                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8364                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8365                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8366                                + ": not system .apk");
8367                        providers.remove(i);
8368                    }
8369                }
8370            }
8371        }
8372        if (providers != null) {
8373            mSystemThread.installSystemProviders(providers);
8374        }
8375
8376        mCoreSettingsObserver = new CoreSettingsObserver(this);
8377
8378        mUsageStatsService.monitorPackages();
8379    }
8380
8381    /**
8382     * Allows app to retrieve the MIME type of a URI without having permission
8383     * to access its content provider.
8384     *
8385     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8386     *
8387     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8388     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8389     */
8390    public String getProviderMimeType(Uri uri, int userId) {
8391        enforceNotIsolatedCaller("getProviderMimeType");
8392        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8393                userId, false, true, "getProviderMimeType", null);
8394        final String name = uri.getAuthority();
8395        final long ident = Binder.clearCallingIdentity();
8396        ContentProviderHolder holder = null;
8397
8398        try {
8399            holder = getContentProviderExternalUnchecked(name, null, userId);
8400            if (holder != null) {
8401                return holder.provider.getType(uri);
8402            }
8403        } catch (RemoteException e) {
8404            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8405            return null;
8406        } finally {
8407            if (holder != null) {
8408                removeContentProviderExternalUnchecked(name, null, userId);
8409            }
8410            Binder.restoreCallingIdentity(ident);
8411        }
8412
8413        return null;
8414    }
8415
8416    // =========================================================
8417    // GLOBAL MANAGEMENT
8418    // =========================================================
8419
8420    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8421            boolean isolated) {
8422        String proc = customProcess != null ? customProcess : info.processName;
8423        BatteryStatsImpl.Uid.Proc ps = null;
8424        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8425        int uid = info.uid;
8426        if (isolated) {
8427            int userId = UserHandle.getUserId(uid);
8428            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8429            while (true) {
8430                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8431                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8432                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8433                }
8434                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8435                mNextIsolatedProcessUid++;
8436                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8437                    // No process for this uid, use it.
8438                    break;
8439                }
8440                stepsLeft--;
8441                if (stepsLeft <= 0) {
8442                    return null;
8443                }
8444            }
8445        }
8446        return new ProcessRecord(stats, info, proc, uid);
8447    }
8448
8449    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8450        ProcessRecord app;
8451        if (!isolated) {
8452            app = getProcessRecordLocked(info.processName, info.uid, true);
8453        } else {
8454            app = null;
8455        }
8456
8457        if (app == null) {
8458            app = newProcessRecordLocked(info, null, isolated);
8459            mProcessNames.put(info.processName, app.uid, app);
8460            if (isolated) {
8461                mIsolatedProcesses.put(app.uid, app);
8462            }
8463            updateLruProcessLocked(app, false, null);
8464            updateOomAdjLocked();
8465        }
8466
8467        // This package really, really can not be stopped.
8468        try {
8469            AppGlobals.getPackageManager().setPackageStoppedState(
8470                    info.packageName, false, UserHandle.getUserId(app.uid));
8471        } catch (RemoteException e) {
8472        } catch (IllegalArgumentException e) {
8473            Slog.w(TAG, "Failed trying to unstop package "
8474                    + info.packageName + ": " + e);
8475        }
8476
8477        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8478                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8479            app.persistent = true;
8480            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8481        }
8482        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8483            mPersistentStartingProcesses.add(app);
8484            startProcessLocked(app, "added application", app.processName);
8485        }
8486
8487        return app;
8488    }
8489
8490    public void unhandledBack() {
8491        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8492                "unhandledBack()");
8493
8494        synchronized(this) {
8495            final long origId = Binder.clearCallingIdentity();
8496            try {
8497                getFocusedStack().unhandledBackLocked();
8498            } finally {
8499                Binder.restoreCallingIdentity(origId);
8500            }
8501        }
8502    }
8503
8504    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8505        enforceNotIsolatedCaller("openContentUri");
8506        final int userId = UserHandle.getCallingUserId();
8507        String name = uri.getAuthority();
8508        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8509        ParcelFileDescriptor pfd = null;
8510        if (cph != null) {
8511            // We record the binder invoker's uid in thread-local storage before
8512            // going to the content provider to open the file.  Later, in the code
8513            // that handles all permissions checks, we look for this uid and use
8514            // that rather than the Activity Manager's own uid.  The effect is that
8515            // we do the check against the caller's permissions even though it looks
8516            // to the content provider like the Activity Manager itself is making
8517            // the request.
8518            sCallerIdentity.set(new Identity(
8519                    Binder.getCallingPid(), Binder.getCallingUid()));
8520            try {
8521                pfd = cph.provider.openFile(null, uri, "r", null);
8522            } catch (FileNotFoundException e) {
8523                // do nothing; pfd will be returned null
8524            } finally {
8525                // Ensure that whatever happens, we clean up the identity state
8526                sCallerIdentity.remove();
8527            }
8528
8529            // We've got the fd now, so we're done with the provider.
8530            removeContentProviderExternalUnchecked(name, null, userId);
8531        } else {
8532            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8533        }
8534        return pfd;
8535    }
8536
8537    // Actually is sleeping or shutting down or whatever else in the future
8538    // is an inactive state.
8539    public boolean isSleepingOrShuttingDown() {
8540        return mSleeping || mShuttingDown;
8541    }
8542
8543    public boolean isSleeping() {
8544        return mSleeping;
8545    }
8546
8547    void goingToSleep() {
8548        synchronized(this) {
8549            mWentToSleep = true;
8550            updateEventDispatchingLocked();
8551            goToSleepIfNeededLocked();
8552        }
8553    }
8554
8555    void finishRunningVoiceLocked() {
8556        if (mRunningVoice) {
8557            mRunningVoice = false;
8558            goToSleepIfNeededLocked();
8559        }
8560    }
8561
8562    void goToSleepIfNeededLocked() {
8563        if (mWentToSleep && !mRunningVoice) {
8564            if (!mSleeping) {
8565                mSleeping = true;
8566                mStackSupervisor.goingToSleepLocked();
8567
8568                // Initialize the wake times of all processes.
8569                checkExcessivePowerUsageLocked(false);
8570                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8571                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8572                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8573            }
8574        }
8575    }
8576
8577    @Override
8578    public boolean shutdown(int timeout) {
8579        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8580                != PackageManager.PERMISSION_GRANTED) {
8581            throw new SecurityException("Requires permission "
8582                    + android.Manifest.permission.SHUTDOWN);
8583        }
8584
8585        boolean timedout = false;
8586
8587        synchronized(this) {
8588            mShuttingDown = true;
8589            updateEventDispatchingLocked();
8590            timedout = mStackSupervisor.shutdownLocked(timeout);
8591        }
8592
8593        mAppOpsService.shutdown();
8594        mUsageStatsService.shutdown();
8595        mBatteryStatsService.shutdown();
8596        synchronized (this) {
8597            mProcessStats.shutdownLocked();
8598        }
8599
8600        return timedout;
8601    }
8602
8603    public final void activitySlept(IBinder token) {
8604        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8605
8606        final long origId = Binder.clearCallingIdentity();
8607
8608        synchronized (this) {
8609            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8610            if (r != null) {
8611                mStackSupervisor.activitySleptLocked(r);
8612            }
8613        }
8614
8615        Binder.restoreCallingIdentity(origId);
8616    }
8617
8618    void logLockScreen(String msg) {
8619        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8620                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8621                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8622                mStackSupervisor.mDismissKeyguardOnNextActivity);
8623    }
8624
8625    private void comeOutOfSleepIfNeededLocked() {
8626        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
8627            if (mSleeping) {
8628                mSleeping = false;
8629                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8630            }
8631        }
8632    }
8633
8634    void wakingUp() {
8635        synchronized(this) {
8636            mWentToSleep = false;
8637            updateEventDispatchingLocked();
8638            comeOutOfSleepIfNeededLocked();
8639        }
8640    }
8641
8642    void startRunningVoiceLocked() {
8643        if (!mRunningVoice) {
8644            mRunningVoice = true;
8645            comeOutOfSleepIfNeededLocked();
8646        }
8647    }
8648
8649    private void updateEventDispatchingLocked() {
8650        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8651    }
8652
8653    public void setLockScreenShown(boolean shown) {
8654        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8655                != PackageManager.PERMISSION_GRANTED) {
8656            throw new SecurityException("Requires permission "
8657                    + android.Manifest.permission.DEVICE_POWER);
8658        }
8659
8660        synchronized(this) {
8661            long ident = Binder.clearCallingIdentity();
8662            try {
8663                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8664                mLockScreenShown = shown;
8665                comeOutOfSleepIfNeededLocked();
8666            } finally {
8667                Binder.restoreCallingIdentity(ident);
8668            }
8669        }
8670    }
8671
8672    public void stopAppSwitches() {
8673        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8674                != PackageManager.PERMISSION_GRANTED) {
8675            throw new SecurityException("Requires permission "
8676                    + android.Manifest.permission.STOP_APP_SWITCHES);
8677        }
8678
8679        synchronized(this) {
8680            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8681                    + APP_SWITCH_DELAY_TIME;
8682            mDidAppSwitch = false;
8683            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8684            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8685            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8686        }
8687    }
8688
8689    public void resumeAppSwitches() {
8690        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8691                != PackageManager.PERMISSION_GRANTED) {
8692            throw new SecurityException("Requires permission "
8693                    + android.Manifest.permission.STOP_APP_SWITCHES);
8694        }
8695
8696        synchronized(this) {
8697            // Note that we don't execute any pending app switches... we will
8698            // let those wait until either the timeout, or the next start
8699            // activity request.
8700            mAppSwitchesAllowedTime = 0;
8701        }
8702    }
8703
8704    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8705            String name) {
8706        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8707            return true;
8708        }
8709
8710        final int perm = checkComponentPermission(
8711                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8712                callingUid, -1, true);
8713        if (perm == PackageManager.PERMISSION_GRANTED) {
8714            return true;
8715        }
8716
8717        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8718        return false;
8719    }
8720
8721    public void setDebugApp(String packageName, boolean waitForDebugger,
8722            boolean persistent) {
8723        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8724                "setDebugApp()");
8725
8726        long ident = Binder.clearCallingIdentity();
8727        try {
8728            // Note that this is not really thread safe if there are multiple
8729            // callers into it at the same time, but that's not a situation we
8730            // care about.
8731            if (persistent) {
8732                final ContentResolver resolver = mContext.getContentResolver();
8733                Settings.Global.putString(
8734                    resolver, Settings.Global.DEBUG_APP,
8735                    packageName);
8736                Settings.Global.putInt(
8737                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8738                    waitForDebugger ? 1 : 0);
8739            }
8740
8741            synchronized (this) {
8742                if (!persistent) {
8743                    mOrigDebugApp = mDebugApp;
8744                    mOrigWaitForDebugger = mWaitForDebugger;
8745                }
8746                mDebugApp = packageName;
8747                mWaitForDebugger = waitForDebugger;
8748                mDebugTransient = !persistent;
8749                if (packageName != null) {
8750                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8751                            false, UserHandle.USER_ALL, "set debug app");
8752                }
8753            }
8754        } finally {
8755            Binder.restoreCallingIdentity(ident);
8756        }
8757    }
8758
8759    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8760        synchronized (this) {
8761            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8762            if (!isDebuggable) {
8763                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8764                    throw new SecurityException("Process not debuggable: " + app.packageName);
8765                }
8766            }
8767
8768            mOpenGlTraceApp = processName;
8769        }
8770    }
8771
8772    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8773            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8774        synchronized (this) {
8775            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8776            if (!isDebuggable) {
8777                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8778                    throw new SecurityException("Process not debuggable: " + app.packageName);
8779                }
8780            }
8781            mProfileApp = processName;
8782            mProfileFile = profileFile;
8783            if (mProfileFd != null) {
8784                try {
8785                    mProfileFd.close();
8786                } catch (IOException e) {
8787                }
8788                mProfileFd = null;
8789            }
8790            mProfileFd = profileFd;
8791            mProfileType = 0;
8792            mAutoStopProfiler = autoStopProfiler;
8793        }
8794    }
8795
8796    @Override
8797    public void setAlwaysFinish(boolean enabled) {
8798        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8799                "setAlwaysFinish()");
8800
8801        Settings.Global.putInt(
8802                mContext.getContentResolver(),
8803                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8804
8805        synchronized (this) {
8806            mAlwaysFinishActivities = enabled;
8807        }
8808    }
8809
8810    @Override
8811    public void setActivityController(IActivityController controller) {
8812        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8813                "setActivityController()");
8814        synchronized (this) {
8815            mController = controller;
8816            Watchdog.getInstance().setActivityController(controller);
8817        }
8818    }
8819
8820    @Override
8821    public void setUserIsMonkey(boolean userIsMonkey) {
8822        synchronized (this) {
8823            synchronized (mPidsSelfLocked) {
8824                final int callingPid = Binder.getCallingPid();
8825                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8826                if (precessRecord == null) {
8827                    throw new SecurityException("Unknown process: " + callingPid);
8828                }
8829                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8830                    throw new SecurityException("Only an instrumentation process "
8831                            + "with a UiAutomation can call setUserIsMonkey");
8832                }
8833            }
8834            mUserIsMonkey = userIsMonkey;
8835        }
8836    }
8837
8838    @Override
8839    public boolean isUserAMonkey() {
8840        synchronized (this) {
8841            // If there is a controller also implies the user is a monkey.
8842            return (mUserIsMonkey || mController != null);
8843        }
8844    }
8845
8846    public void requestBugReport() {
8847        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8848        SystemProperties.set("ctl.start", "bugreport");
8849    }
8850
8851    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8852        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8853    }
8854
8855    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8856        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8857            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8858        }
8859        return KEY_DISPATCHING_TIMEOUT;
8860    }
8861
8862    @Override
8863    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8864        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8865                != PackageManager.PERMISSION_GRANTED) {
8866            throw new SecurityException("Requires permission "
8867                    + android.Manifest.permission.FILTER_EVENTS);
8868        }
8869        ProcessRecord proc;
8870        long timeout;
8871        synchronized (this) {
8872            synchronized (mPidsSelfLocked) {
8873                proc = mPidsSelfLocked.get(pid);
8874            }
8875            timeout = getInputDispatchingTimeoutLocked(proc);
8876        }
8877
8878        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8879            return -1;
8880        }
8881
8882        return timeout;
8883    }
8884
8885    /**
8886     * Handle input dispatching timeouts.
8887     * Returns whether input dispatching should be aborted or not.
8888     */
8889    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8890            final ActivityRecord activity, final ActivityRecord parent,
8891            final boolean aboveSystem, String reason) {
8892        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8893                != PackageManager.PERMISSION_GRANTED) {
8894            throw new SecurityException("Requires permission "
8895                    + android.Manifest.permission.FILTER_EVENTS);
8896        }
8897
8898        final String annotation;
8899        if (reason == null) {
8900            annotation = "Input dispatching timed out";
8901        } else {
8902            annotation = "Input dispatching timed out (" + reason + ")";
8903        }
8904
8905        if (proc != null) {
8906            synchronized (this) {
8907                if (proc.debugging) {
8908                    return false;
8909                }
8910
8911                if (mDidDexOpt) {
8912                    // Give more time since we were dexopting.
8913                    mDidDexOpt = false;
8914                    return false;
8915                }
8916
8917                if (proc.instrumentationClass != null) {
8918                    Bundle info = new Bundle();
8919                    info.putString("shortMsg", "keyDispatchingTimedOut");
8920                    info.putString("longMsg", annotation);
8921                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8922                    return true;
8923                }
8924            }
8925            mHandler.post(new Runnable() {
8926                @Override
8927                public void run() {
8928                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
8929                }
8930            });
8931        }
8932
8933        return true;
8934    }
8935
8936    public Bundle getAssistContextExtras(int requestType) {
8937        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
8938                "getAssistContextExtras()");
8939        PendingAssistExtras pae;
8940        Bundle extras = new Bundle();
8941        synchronized (this) {
8942            ActivityRecord activity = getFocusedStack().mResumedActivity;
8943            if (activity == null) {
8944                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
8945                return null;
8946            }
8947            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
8948            if (activity.app == null || activity.app.thread == null) {
8949                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
8950                return extras;
8951            }
8952            if (activity.app.pid == Binder.getCallingPid()) {
8953                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
8954                return extras;
8955            }
8956            pae = new PendingAssistExtras(activity);
8957            try {
8958                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
8959                        requestType);
8960                mPendingAssistExtras.add(pae);
8961                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
8962            } catch (RemoteException e) {
8963                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
8964                return extras;
8965            }
8966        }
8967        synchronized (pae) {
8968            while (!pae.haveResult) {
8969                try {
8970                    pae.wait();
8971                } catch (InterruptedException e) {
8972                }
8973            }
8974            if (pae.result != null) {
8975                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
8976            }
8977        }
8978        synchronized (this) {
8979            mPendingAssistExtras.remove(pae);
8980            mHandler.removeCallbacks(pae);
8981        }
8982        return extras;
8983    }
8984
8985    public void reportAssistContextExtras(IBinder token, Bundle extras) {
8986        PendingAssistExtras pae = (PendingAssistExtras)token;
8987        synchronized (pae) {
8988            pae.result = extras;
8989            pae.haveResult = true;
8990            pae.notifyAll();
8991        }
8992    }
8993
8994    public void registerProcessObserver(IProcessObserver observer) {
8995        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8996                "registerProcessObserver()");
8997        synchronized (this) {
8998            mProcessObservers.register(observer);
8999        }
9000    }
9001
9002    @Override
9003    public void unregisterProcessObserver(IProcessObserver observer) {
9004        synchronized (this) {
9005            mProcessObservers.unregister(observer);
9006        }
9007    }
9008
9009    @Override
9010    public boolean convertFromTranslucent(IBinder token) {
9011        final long origId = Binder.clearCallingIdentity();
9012        try {
9013            synchronized (this) {
9014                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9015                if (r == null) {
9016                    return false;
9017                }
9018                if (r.changeWindowTranslucency(true)) {
9019                    mWindowManager.setAppFullscreen(token, true);
9020                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9021                    return true;
9022                }
9023                return false;
9024            }
9025        } finally {
9026            Binder.restoreCallingIdentity(origId);
9027        }
9028    }
9029
9030    @Override
9031    public boolean convertToTranslucent(IBinder token) {
9032        final long origId = Binder.clearCallingIdentity();
9033        try {
9034            synchronized (this) {
9035                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9036                if (r == null) {
9037                    return false;
9038                }
9039                if (r.changeWindowTranslucency(false)) {
9040                    r.task.stack.convertToTranslucent(r);
9041                    mWindowManager.setAppFullscreen(token, false);
9042                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9043                    return true;
9044                }
9045                return false;
9046            }
9047        } finally {
9048            Binder.restoreCallingIdentity(origId);
9049        }
9050    }
9051
9052    @Override
9053    public void setImmersive(IBinder token, boolean immersive) {
9054        synchronized(this) {
9055            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9056            if (r == null) {
9057                throw new IllegalArgumentException();
9058            }
9059            r.immersive = immersive;
9060
9061            // update associated state if we're frontmost
9062            if (r == mFocusedActivity) {
9063                if (DEBUG_IMMERSIVE) {
9064                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9065                }
9066                applyUpdateLockStateLocked(r);
9067            }
9068        }
9069    }
9070
9071    @Override
9072    public boolean isImmersive(IBinder token) {
9073        synchronized (this) {
9074            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9075            if (r == null) {
9076                throw new IllegalArgumentException();
9077            }
9078            return r.immersive;
9079        }
9080    }
9081
9082    public boolean isTopActivityImmersive() {
9083        enforceNotIsolatedCaller("startActivity");
9084        synchronized (this) {
9085            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9086            return (r != null) ? r.immersive : false;
9087        }
9088    }
9089
9090    public final void enterSafeMode() {
9091        synchronized(this) {
9092            // It only makes sense to do this before the system is ready
9093            // and started launching other packages.
9094            if (!mSystemReady) {
9095                try {
9096                    AppGlobals.getPackageManager().enterSafeMode();
9097                } catch (RemoteException e) {
9098                }
9099            }
9100
9101            mSafeMode = true;
9102        }
9103    }
9104
9105    public final void showSafeModeOverlay() {
9106        View v = LayoutInflater.from(mContext).inflate(
9107                com.android.internal.R.layout.safe_mode, null);
9108        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9109        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9110        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9111        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9112        lp.gravity = Gravity.BOTTOM | Gravity.START;
9113        lp.format = v.getBackground().getOpacity();
9114        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9115                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9116        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9117        ((WindowManager)mContext.getSystemService(
9118                Context.WINDOW_SERVICE)).addView(v, lp);
9119    }
9120
9121    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9122        if (!(sender instanceof PendingIntentRecord)) {
9123            return;
9124        }
9125        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9126        synchronized (stats) {
9127            if (mBatteryStatsService.isOnBattery()) {
9128                mBatteryStatsService.enforceCallingPermission();
9129                PendingIntentRecord rec = (PendingIntentRecord)sender;
9130                int MY_UID = Binder.getCallingUid();
9131                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9132                BatteryStatsImpl.Uid.Pkg pkg =
9133                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9134                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9135                pkg.incWakeupsLocked();
9136            }
9137        }
9138    }
9139
9140    public boolean killPids(int[] pids, String pReason, boolean secure) {
9141        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9142            throw new SecurityException("killPids only available to the system");
9143        }
9144        String reason = (pReason == null) ? "Unknown" : pReason;
9145        // XXX Note: don't acquire main activity lock here, because the window
9146        // manager calls in with its locks held.
9147
9148        boolean killed = false;
9149        synchronized (mPidsSelfLocked) {
9150            int[] types = new int[pids.length];
9151            int worstType = 0;
9152            for (int i=0; i<pids.length; i++) {
9153                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9154                if (proc != null) {
9155                    int type = proc.setAdj;
9156                    types[i] = type;
9157                    if (type > worstType) {
9158                        worstType = type;
9159                    }
9160                }
9161            }
9162
9163            // If the worst oom_adj is somewhere in the cached proc LRU range,
9164            // then constrain it so we will kill all cached procs.
9165            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9166                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9167                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9168            }
9169
9170            // If this is not a secure call, don't let it kill processes that
9171            // are important.
9172            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9173                worstType = ProcessList.SERVICE_ADJ;
9174            }
9175
9176            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9177            for (int i=0; i<pids.length; i++) {
9178                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9179                if (proc == null) {
9180                    continue;
9181                }
9182                int adj = proc.setAdj;
9183                if (adj >= worstType && !proc.killedByAm) {
9184                    killUnneededProcessLocked(proc, reason);
9185                    killed = true;
9186                }
9187            }
9188        }
9189        return killed;
9190    }
9191
9192    @Override
9193    public void killUid(int uid, String reason) {
9194        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9195            throw new SecurityException("killUid only available to the system");
9196        }
9197        synchronized (this) {
9198            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9199                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9200                    reason != null ? reason : "kill uid");
9201        }
9202    }
9203
9204    @Override
9205    public boolean killProcessesBelowForeground(String reason) {
9206        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9207            throw new SecurityException("killProcessesBelowForeground() only available to system");
9208        }
9209
9210        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9211    }
9212
9213    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9214        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9215            throw new SecurityException("killProcessesBelowAdj() only available to system");
9216        }
9217
9218        boolean killed = false;
9219        synchronized (mPidsSelfLocked) {
9220            final int size = mPidsSelfLocked.size();
9221            for (int i = 0; i < size; i++) {
9222                final int pid = mPidsSelfLocked.keyAt(i);
9223                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9224                if (proc == null) continue;
9225
9226                final int adj = proc.setAdj;
9227                if (adj > belowAdj && !proc.killedByAm) {
9228                    killUnneededProcessLocked(proc, reason);
9229                    killed = true;
9230                }
9231            }
9232        }
9233        return killed;
9234    }
9235
9236    @Override
9237    public void hang(final IBinder who, boolean allowRestart) {
9238        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9239                != PackageManager.PERMISSION_GRANTED) {
9240            throw new SecurityException("Requires permission "
9241                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9242        }
9243
9244        final IBinder.DeathRecipient death = new DeathRecipient() {
9245            @Override
9246            public void binderDied() {
9247                synchronized (this) {
9248                    notifyAll();
9249                }
9250            }
9251        };
9252
9253        try {
9254            who.linkToDeath(death, 0);
9255        } catch (RemoteException e) {
9256            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9257            return;
9258        }
9259
9260        synchronized (this) {
9261            Watchdog.getInstance().setAllowRestart(allowRestart);
9262            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9263            synchronized (death) {
9264                while (who.isBinderAlive()) {
9265                    try {
9266                        death.wait();
9267                    } catch (InterruptedException e) {
9268                    }
9269                }
9270            }
9271            Watchdog.getInstance().setAllowRestart(true);
9272        }
9273    }
9274
9275    @Override
9276    public void restart() {
9277        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9278                != PackageManager.PERMISSION_GRANTED) {
9279            throw new SecurityException("Requires permission "
9280                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9281        }
9282
9283        Log.i(TAG, "Sending shutdown broadcast...");
9284
9285        BroadcastReceiver br = new BroadcastReceiver() {
9286            @Override public void onReceive(Context context, Intent intent) {
9287                // Now the broadcast is done, finish up the low-level shutdown.
9288                Log.i(TAG, "Shutting down activity manager...");
9289                shutdown(10000);
9290                Log.i(TAG, "Shutdown complete, restarting!");
9291                Process.killProcess(Process.myPid());
9292                System.exit(10);
9293            }
9294        };
9295
9296        // First send the high-level shut down broadcast.
9297        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9298        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9299        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9300        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9301        mContext.sendOrderedBroadcastAsUser(intent,
9302                UserHandle.ALL, null, br, mHandler, 0, null, null);
9303        */
9304        br.onReceive(mContext, intent);
9305    }
9306
9307    private long getLowRamTimeSinceIdle(long now) {
9308        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9309    }
9310
9311    @Override
9312    public void performIdleMaintenance() {
9313        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9314                != PackageManager.PERMISSION_GRANTED) {
9315            throw new SecurityException("Requires permission "
9316                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9317        }
9318
9319        synchronized (this) {
9320            final long now = SystemClock.uptimeMillis();
9321            final long timeSinceLastIdle = now - mLastIdleTime;
9322            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9323            mLastIdleTime = now;
9324            mLowRamTimeSinceLastIdle = 0;
9325            if (mLowRamStartTime != 0) {
9326                mLowRamStartTime = now;
9327            }
9328
9329            StringBuilder sb = new StringBuilder(128);
9330            sb.append("Idle maintenance over ");
9331            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9332            sb.append(" low RAM for ");
9333            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9334            Slog.i(TAG, sb.toString());
9335
9336            // If at least 1/3 of our time since the last idle period has been spent
9337            // with RAM low, then we want to kill processes.
9338            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9339
9340            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9341                ProcessRecord proc = mLruProcesses.get(i);
9342                if (proc.notCachedSinceIdle) {
9343                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9344                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9345                        if (doKilling && proc.initialIdlePss != 0
9346                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9347                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9348                                    + " from " + proc.initialIdlePss + ")");
9349                        }
9350                    }
9351                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9352                    proc.notCachedSinceIdle = true;
9353                    proc.initialIdlePss = 0;
9354                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9355                            isSleeping(), now);
9356                }
9357            }
9358
9359            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9360            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9361        }
9362    }
9363
9364    private void retrieveSettings() {
9365        final ContentResolver resolver = mContext.getContentResolver();
9366        String debugApp = Settings.Global.getString(
9367            resolver, Settings.Global.DEBUG_APP);
9368        boolean waitForDebugger = Settings.Global.getInt(
9369            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9370        boolean alwaysFinishActivities = Settings.Global.getInt(
9371            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9372        boolean forceRtl = Settings.Global.getInt(
9373                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9374        // Transfer any global setting for forcing RTL layout, into a System Property
9375        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9376
9377        Configuration configuration = new Configuration();
9378        Settings.System.getConfiguration(resolver, configuration);
9379        if (forceRtl) {
9380            // This will take care of setting the correct layout direction flags
9381            configuration.setLayoutDirection(configuration.locale);
9382        }
9383
9384        synchronized (this) {
9385            mDebugApp = mOrigDebugApp = debugApp;
9386            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9387            mAlwaysFinishActivities = alwaysFinishActivities;
9388            // This happens before any activities are started, so we can
9389            // change mConfiguration in-place.
9390            updateConfigurationLocked(configuration, null, false, true);
9391            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9392        }
9393    }
9394
9395    public boolean testIsSystemReady() {
9396        // no need to synchronize(this) just to read & return the value
9397        return mSystemReady;
9398    }
9399
9400    private static File getCalledPreBootReceiversFile() {
9401        File dataDir = Environment.getDataDirectory();
9402        File systemDir = new File(dataDir, "system");
9403        File fname = new File(systemDir, "called_pre_boots.dat");
9404        return fname;
9405    }
9406
9407    static final int LAST_DONE_VERSION = 10000;
9408
9409    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9410        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9411        File file = getCalledPreBootReceiversFile();
9412        FileInputStream fis = null;
9413        try {
9414            fis = new FileInputStream(file);
9415            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9416            int fvers = dis.readInt();
9417            if (fvers == LAST_DONE_VERSION) {
9418                String vers = dis.readUTF();
9419                String codename = dis.readUTF();
9420                String build = dis.readUTF();
9421                if (android.os.Build.VERSION.RELEASE.equals(vers)
9422                        && android.os.Build.VERSION.CODENAME.equals(codename)
9423                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9424                    int num = dis.readInt();
9425                    while (num > 0) {
9426                        num--;
9427                        String pkg = dis.readUTF();
9428                        String cls = dis.readUTF();
9429                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9430                    }
9431                }
9432            }
9433        } catch (FileNotFoundException e) {
9434        } catch (IOException e) {
9435            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9436        } finally {
9437            if (fis != null) {
9438                try {
9439                    fis.close();
9440                } catch (IOException e) {
9441                }
9442            }
9443        }
9444        return lastDoneReceivers;
9445    }
9446
9447    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9448        File file = getCalledPreBootReceiversFile();
9449        FileOutputStream fos = null;
9450        DataOutputStream dos = null;
9451        try {
9452            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9453            fos = new FileOutputStream(file);
9454            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9455            dos.writeInt(LAST_DONE_VERSION);
9456            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9457            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9458            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9459            dos.writeInt(list.size());
9460            for (int i=0; i<list.size(); i++) {
9461                dos.writeUTF(list.get(i).getPackageName());
9462                dos.writeUTF(list.get(i).getClassName());
9463            }
9464        } catch (IOException e) {
9465            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9466            file.delete();
9467        } finally {
9468            FileUtils.sync(fos);
9469            if (dos != null) {
9470                try {
9471                    dos.close();
9472                } catch (IOException e) {
9473                    // TODO Auto-generated catch block
9474                    e.printStackTrace();
9475                }
9476            }
9477        }
9478    }
9479
9480    public void systemReady(final Runnable goingCallback) {
9481        synchronized(this) {
9482            if (mSystemReady) {
9483                if (goingCallback != null) goingCallback.run();
9484                return;
9485            }
9486
9487            // Check to see if there are any update receivers to run.
9488            if (!mDidUpdate) {
9489                if (mWaitingUpdate) {
9490                    return;
9491                }
9492                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9493                List<ResolveInfo> ris = null;
9494                try {
9495                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9496                            intent, null, 0, 0);
9497                } catch (RemoteException e) {
9498                }
9499                if (ris != null) {
9500                    for (int i=ris.size()-1; i>=0; i--) {
9501                        if ((ris.get(i).activityInfo.applicationInfo.flags
9502                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9503                            ris.remove(i);
9504                        }
9505                    }
9506                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9507
9508                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9509
9510                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9511                    for (int i=0; i<ris.size(); i++) {
9512                        ActivityInfo ai = ris.get(i).activityInfo;
9513                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9514                        if (lastDoneReceivers.contains(comp)) {
9515                            // We already did the pre boot receiver for this app with the current
9516                            // platform version, so don't do it again...
9517                            ris.remove(i);
9518                            i--;
9519                            // ...however, do keep it as one that has been done, so we don't
9520                            // forget about it when rewriting the file of last done receivers.
9521                            doneReceivers.add(comp);
9522                        }
9523                    }
9524
9525                    final int[] users = getUsersLocked();
9526                    for (int i=0; i<ris.size(); i++) {
9527                        ActivityInfo ai = ris.get(i).activityInfo;
9528                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9529                        doneReceivers.add(comp);
9530                        intent.setComponent(comp);
9531                        for (int j=0; j<users.length; j++) {
9532                            IIntentReceiver finisher = null;
9533                            if (i == ris.size()-1 && j == users.length-1) {
9534                                finisher = new IIntentReceiver.Stub() {
9535                                    public void performReceive(Intent intent, int resultCode,
9536                                            String data, Bundle extras, boolean ordered,
9537                                            boolean sticky, int sendingUser) {
9538                                        // The raw IIntentReceiver interface is called
9539                                        // with the AM lock held, so redispatch to
9540                                        // execute our code without the lock.
9541                                        mHandler.post(new Runnable() {
9542                                            public void run() {
9543                                                synchronized (ActivityManagerService.this) {
9544                                                    mDidUpdate = true;
9545                                                }
9546                                                writeLastDonePreBootReceivers(doneReceivers);
9547                                                showBootMessage(mContext.getText(
9548                                                        R.string.android_upgrading_complete),
9549                                                        false);
9550                                                systemReady(goingCallback);
9551                                            }
9552                                        });
9553                                    }
9554                                };
9555                            }
9556                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9557                                    + " for user " + users[j]);
9558                            broadcastIntentLocked(null, null, intent, null, finisher,
9559                                    0, null, null, null, AppOpsManager.OP_NONE,
9560                                    true, false, MY_PID, Process.SYSTEM_UID,
9561                                    users[j]);
9562                            if (finisher != null) {
9563                                mWaitingUpdate = true;
9564                            }
9565                        }
9566                    }
9567                }
9568                if (mWaitingUpdate) {
9569                    return;
9570                }
9571                mDidUpdate = true;
9572            }
9573
9574            mAppOpsService.systemReady();
9575            mUsageStatsService.systemReady();
9576            mSystemReady = true;
9577        }
9578
9579        ArrayList<ProcessRecord> procsToKill = null;
9580        synchronized(mPidsSelfLocked) {
9581            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9582                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9583                if (!isAllowedWhileBooting(proc.info)){
9584                    if (procsToKill == null) {
9585                        procsToKill = new ArrayList<ProcessRecord>();
9586                    }
9587                    procsToKill.add(proc);
9588                }
9589            }
9590        }
9591
9592        synchronized(this) {
9593            if (procsToKill != null) {
9594                for (int i=procsToKill.size()-1; i>=0; i--) {
9595                    ProcessRecord proc = procsToKill.get(i);
9596                    Slog.i(TAG, "Removing system update proc: " + proc);
9597                    removeProcessLocked(proc, true, false, "system update done");
9598                }
9599            }
9600
9601            // Now that we have cleaned up any update processes, we
9602            // are ready to start launching real processes and know that
9603            // we won't trample on them any more.
9604            mProcessesReady = true;
9605        }
9606
9607        Slog.i(TAG, "System now ready");
9608        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9609            SystemClock.uptimeMillis());
9610
9611        synchronized(this) {
9612            // Make sure we have no pre-ready processes sitting around.
9613
9614            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9615                ResolveInfo ri = mContext.getPackageManager()
9616                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9617                                STOCK_PM_FLAGS);
9618                CharSequence errorMsg = null;
9619                if (ri != null) {
9620                    ActivityInfo ai = ri.activityInfo;
9621                    ApplicationInfo app = ai.applicationInfo;
9622                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9623                        mTopAction = Intent.ACTION_FACTORY_TEST;
9624                        mTopData = null;
9625                        mTopComponent = new ComponentName(app.packageName,
9626                                ai.name);
9627                    } else {
9628                        errorMsg = mContext.getResources().getText(
9629                                com.android.internal.R.string.factorytest_not_system);
9630                    }
9631                } else {
9632                    errorMsg = mContext.getResources().getText(
9633                            com.android.internal.R.string.factorytest_no_action);
9634                }
9635                if (errorMsg != null) {
9636                    mTopAction = null;
9637                    mTopData = null;
9638                    mTopComponent = null;
9639                    Message msg = Message.obtain();
9640                    msg.what = SHOW_FACTORY_ERROR_MSG;
9641                    msg.getData().putCharSequence("msg", errorMsg);
9642                    mHandler.sendMessage(msg);
9643                }
9644            }
9645        }
9646
9647        retrieveSettings();
9648
9649        synchronized (this) {
9650            readGrantedUriPermissionsLocked();
9651        }
9652
9653        if (goingCallback != null) goingCallback.run();
9654
9655        mSystemServiceManager.startUser(mCurrentUserId);
9656
9657        synchronized (this) {
9658            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9659                try {
9660                    List apps = AppGlobals.getPackageManager().
9661                        getPersistentApplications(STOCK_PM_FLAGS);
9662                    if (apps != null) {
9663                        int N = apps.size();
9664                        int i;
9665                        for (i=0; i<N; i++) {
9666                            ApplicationInfo info
9667                                = (ApplicationInfo)apps.get(i);
9668                            if (info != null &&
9669                                    !info.packageName.equals("android")) {
9670                                addAppLocked(info, false);
9671                            }
9672                        }
9673                    }
9674                } catch (RemoteException ex) {
9675                    // pm is in same process, this will never happen.
9676                }
9677            }
9678
9679            // Start up initial activity.
9680            mBooting = true;
9681
9682            try {
9683                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9684                    Message msg = Message.obtain();
9685                    msg.what = SHOW_UID_ERROR_MSG;
9686                    mHandler.sendMessage(msg);
9687                }
9688            } catch (RemoteException e) {
9689            }
9690
9691            long ident = Binder.clearCallingIdentity();
9692            try {
9693                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9694                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9695                        | Intent.FLAG_RECEIVER_FOREGROUND);
9696                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9697                broadcastIntentLocked(null, null, intent,
9698                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9699                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9700                intent = new Intent(Intent.ACTION_USER_STARTING);
9701                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9702                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9703                broadcastIntentLocked(null, null, intent,
9704                        null, new IIntentReceiver.Stub() {
9705                            @Override
9706                            public void performReceive(Intent intent, int resultCode, String data,
9707                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9708                                    throws RemoteException {
9709                            }
9710                        }, 0, null, null,
9711                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9712                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9713            } catch (Throwable t) {
9714                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
9715            } finally {
9716                Binder.restoreCallingIdentity(ident);
9717            }
9718            mStackSupervisor.resumeTopActivitiesLocked();
9719            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9720        }
9721    }
9722
9723    private boolean makeAppCrashingLocked(ProcessRecord app,
9724            String shortMsg, String longMsg, String stackTrace) {
9725        app.crashing = true;
9726        app.crashingReport = generateProcessError(app,
9727                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9728        startAppProblemLocked(app);
9729        app.stopFreezingAllLocked();
9730        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9731    }
9732
9733    private void makeAppNotRespondingLocked(ProcessRecord app,
9734            String activity, String shortMsg, String longMsg) {
9735        app.notResponding = true;
9736        app.notRespondingReport = generateProcessError(app,
9737                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9738                activity, shortMsg, longMsg, null);
9739        startAppProblemLocked(app);
9740        app.stopFreezingAllLocked();
9741    }
9742
9743    /**
9744     * Generate a process error record, suitable for attachment to a ProcessRecord.
9745     *
9746     * @param app The ProcessRecord in which the error occurred.
9747     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9748     *                      ActivityManager.AppErrorStateInfo
9749     * @param activity The activity associated with the crash, if known.
9750     * @param shortMsg Short message describing the crash.
9751     * @param longMsg Long message describing the crash.
9752     * @param stackTrace Full crash stack trace, may be null.
9753     *
9754     * @return Returns a fully-formed AppErrorStateInfo record.
9755     */
9756    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9757            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9758        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9759
9760        report.condition = condition;
9761        report.processName = app.processName;
9762        report.pid = app.pid;
9763        report.uid = app.info.uid;
9764        report.tag = activity;
9765        report.shortMsg = shortMsg;
9766        report.longMsg = longMsg;
9767        report.stackTrace = stackTrace;
9768
9769        return report;
9770    }
9771
9772    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9773        synchronized (this) {
9774            app.crashing = false;
9775            app.crashingReport = null;
9776            app.notResponding = false;
9777            app.notRespondingReport = null;
9778            if (app.anrDialog == fromDialog) {
9779                app.anrDialog = null;
9780            }
9781            if (app.waitDialog == fromDialog) {
9782                app.waitDialog = null;
9783            }
9784            if (app.pid > 0 && app.pid != MY_PID) {
9785                handleAppCrashLocked(app, null, null, null);
9786                killUnneededProcessLocked(app, "user request after error");
9787            }
9788        }
9789    }
9790
9791    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9792            String stackTrace) {
9793        long now = SystemClock.uptimeMillis();
9794
9795        Long crashTime;
9796        if (!app.isolated) {
9797            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9798        } else {
9799            crashTime = null;
9800        }
9801        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9802            // This process loses!
9803            Slog.w(TAG, "Process " + app.info.processName
9804                    + " has crashed too many times: killing!");
9805            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9806                    app.userId, app.info.processName, app.uid);
9807            mStackSupervisor.handleAppCrashLocked(app);
9808            if (!app.persistent) {
9809                // We don't want to start this process again until the user
9810                // explicitly does so...  but for persistent process, we really
9811                // need to keep it running.  If a persistent process is actually
9812                // repeatedly crashing, then badness for everyone.
9813                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9814                        app.info.processName);
9815                if (!app.isolated) {
9816                    // XXX We don't have a way to mark isolated processes
9817                    // as bad, since they don't have a peristent identity.
9818                    mBadProcesses.put(app.info.processName, app.uid,
9819                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9820                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9821                }
9822                app.bad = true;
9823                app.removed = true;
9824                // Don't let services in this process be restarted and potentially
9825                // annoy the user repeatedly.  Unless it is persistent, since those
9826                // processes run critical code.
9827                removeProcessLocked(app, false, false, "crash");
9828                mStackSupervisor.resumeTopActivitiesLocked();
9829                return false;
9830            }
9831            mStackSupervisor.resumeTopActivitiesLocked();
9832        } else {
9833            mStackSupervisor.finishTopRunningActivityLocked(app);
9834        }
9835
9836        // Bump up the crash count of any services currently running in the proc.
9837        for (int i=app.services.size()-1; i>=0; i--) {
9838            // Any services running in the application need to be placed
9839            // back in the pending list.
9840            ServiceRecord sr = app.services.valueAt(i);
9841            sr.crashCount++;
9842        }
9843
9844        // If the crashing process is what we consider to be the "home process" and it has been
9845        // replaced by a third-party app, clear the package preferred activities from packages
9846        // with a home activity running in the process to prevent a repeatedly crashing app
9847        // from blocking the user to manually clear the list.
9848        final ArrayList<ActivityRecord> activities = app.activities;
9849        if (app == mHomeProcess && activities.size() > 0
9850                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9851            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9852                final ActivityRecord r = activities.get(activityNdx);
9853                if (r.isHomeActivity()) {
9854                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9855                    try {
9856                        ActivityThread.getPackageManager()
9857                                .clearPackagePreferredActivities(r.packageName);
9858                    } catch (RemoteException c) {
9859                        // pm is in same process, this will never happen.
9860                    }
9861                }
9862            }
9863        }
9864
9865        if (!app.isolated) {
9866            // XXX Can't keep track of crash times for isolated processes,
9867            // because they don't have a perisistent identity.
9868            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9869        }
9870
9871        return true;
9872    }
9873
9874    void startAppProblemLocked(ProcessRecord app) {
9875        if (app.userId == mCurrentUserId) {
9876            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9877                    mContext, app.info.packageName, app.info.flags);
9878        } else {
9879            // If this app is not running under the current user, then we
9880            // can't give it a report button because that would require
9881            // launching the report UI under a different user.
9882            app.errorReportReceiver = null;
9883        }
9884        skipCurrentReceiverLocked(app);
9885    }
9886
9887    void skipCurrentReceiverLocked(ProcessRecord app) {
9888        for (BroadcastQueue queue : mBroadcastQueues) {
9889            queue.skipCurrentReceiverLocked(app);
9890        }
9891    }
9892
9893    /**
9894     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9895     * The application process will exit immediately after this call returns.
9896     * @param app object of the crashing app, null for the system server
9897     * @param crashInfo describing the exception
9898     */
9899    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9900        ProcessRecord r = findAppProcess(app, "Crash");
9901        final String processName = app == null ? "system_server"
9902                : (r == null ? "unknown" : r.processName);
9903
9904        handleApplicationCrashInner("crash", r, processName, crashInfo);
9905    }
9906
9907    /* Native crash reporting uses this inner version because it needs to be somewhat
9908     * decoupled from the AM-managed cleanup lifecycle
9909     */
9910    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
9911            ApplicationErrorReport.CrashInfo crashInfo) {
9912        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
9913                UserHandle.getUserId(Binder.getCallingUid()), processName,
9914                r == null ? -1 : r.info.flags,
9915                crashInfo.exceptionClassName,
9916                crashInfo.exceptionMessage,
9917                crashInfo.throwFileName,
9918                crashInfo.throwLineNumber);
9919
9920        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
9921
9922        crashApplication(r, crashInfo);
9923    }
9924
9925    public void handleApplicationStrictModeViolation(
9926            IBinder app,
9927            int violationMask,
9928            StrictMode.ViolationInfo info) {
9929        ProcessRecord r = findAppProcess(app, "StrictMode");
9930        if (r == null) {
9931            return;
9932        }
9933
9934        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
9935            Integer stackFingerprint = info.hashCode();
9936            boolean logIt = true;
9937            synchronized (mAlreadyLoggedViolatedStacks) {
9938                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
9939                    logIt = false;
9940                    // TODO: sub-sample into EventLog for these, with
9941                    // the info.durationMillis?  Then we'd get
9942                    // the relative pain numbers, without logging all
9943                    // the stack traces repeatedly.  We'd want to do
9944                    // likewise in the client code, which also does
9945                    // dup suppression, before the Binder call.
9946                } else {
9947                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
9948                        mAlreadyLoggedViolatedStacks.clear();
9949                    }
9950                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
9951                }
9952            }
9953            if (logIt) {
9954                logStrictModeViolationToDropBox(r, info);
9955            }
9956        }
9957
9958        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
9959            AppErrorResult result = new AppErrorResult();
9960            synchronized (this) {
9961                final long origId = Binder.clearCallingIdentity();
9962
9963                Message msg = Message.obtain();
9964                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
9965                HashMap<String, Object> data = new HashMap<String, Object>();
9966                data.put("result", result);
9967                data.put("app", r);
9968                data.put("violationMask", violationMask);
9969                data.put("info", info);
9970                msg.obj = data;
9971                mHandler.sendMessage(msg);
9972
9973                Binder.restoreCallingIdentity(origId);
9974            }
9975            int res = result.get();
9976            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
9977        }
9978    }
9979
9980    // Depending on the policy in effect, there could be a bunch of
9981    // these in quick succession so we try to batch these together to
9982    // minimize disk writes, number of dropbox entries, and maximize
9983    // compression, by having more fewer, larger records.
9984    private void logStrictModeViolationToDropBox(
9985            ProcessRecord process,
9986            StrictMode.ViolationInfo info) {
9987        if (info == null) {
9988            return;
9989        }
9990        final boolean isSystemApp = process == null ||
9991                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
9992                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
9993        final String processName = process == null ? "unknown" : process.processName;
9994        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
9995        final DropBoxManager dbox = (DropBoxManager)
9996                mContext.getSystemService(Context.DROPBOX_SERVICE);
9997
9998        // Exit early if the dropbox isn't configured to accept this report type.
9999        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10000
10001        boolean bufferWasEmpty;
10002        boolean needsFlush;
10003        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10004        synchronized (sb) {
10005            bufferWasEmpty = sb.length() == 0;
10006            appendDropBoxProcessHeaders(process, processName, sb);
10007            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10008            sb.append("System-App: ").append(isSystemApp).append("\n");
10009            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10010            if (info.violationNumThisLoop != 0) {
10011                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10012            }
10013            if (info.numAnimationsRunning != 0) {
10014                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10015            }
10016            if (info.broadcastIntentAction != null) {
10017                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10018            }
10019            if (info.durationMillis != -1) {
10020                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10021            }
10022            if (info.numInstances != -1) {
10023                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10024            }
10025            if (info.tags != null) {
10026                for (String tag : info.tags) {
10027                    sb.append("Span-Tag: ").append(tag).append("\n");
10028                }
10029            }
10030            sb.append("\n");
10031            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10032                sb.append(info.crashInfo.stackTrace);
10033            }
10034            sb.append("\n");
10035
10036            // Only buffer up to ~64k.  Various logging bits truncate
10037            // things at 128k.
10038            needsFlush = (sb.length() > 64 * 1024);
10039        }
10040
10041        // Flush immediately if the buffer's grown too large, or this
10042        // is a non-system app.  Non-system apps are isolated with a
10043        // different tag & policy and not batched.
10044        //
10045        // Batching is useful during internal testing with
10046        // StrictMode settings turned up high.  Without batching,
10047        // thousands of separate files could be created on boot.
10048        if (!isSystemApp || needsFlush) {
10049            new Thread("Error dump: " + dropboxTag) {
10050                @Override
10051                public void run() {
10052                    String report;
10053                    synchronized (sb) {
10054                        report = sb.toString();
10055                        sb.delete(0, sb.length());
10056                        sb.trimToSize();
10057                    }
10058                    if (report.length() != 0) {
10059                        dbox.addText(dropboxTag, report);
10060                    }
10061                }
10062            }.start();
10063            return;
10064        }
10065
10066        // System app batching:
10067        if (!bufferWasEmpty) {
10068            // An existing dropbox-writing thread is outstanding, so
10069            // we don't need to start it up.  The existing thread will
10070            // catch the buffer appends we just did.
10071            return;
10072        }
10073
10074        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10075        // (After this point, we shouldn't access AMS internal data structures.)
10076        new Thread("Error dump: " + dropboxTag) {
10077            @Override
10078            public void run() {
10079                // 5 second sleep to let stacks arrive and be batched together
10080                try {
10081                    Thread.sleep(5000);  // 5 seconds
10082                } catch (InterruptedException e) {}
10083
10084                String errorReport;
10085                synchronized (mStrictModeBuffer) {
10086                    errorReport = mStrictModeBuffer.toString();
10087                    if (errorReport.length() == 0) {
10088                        return;
10089                    }
10090                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10091                    mStrictModeBuffer.trimToSize();
10092                }
10093                dbox.addText(dropboxTag, errorReport);
10094            }
10095        }.start();
10096    }
10097
10098    /**
10099     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10100     * @param app object of the crashing app, null for the system server
10101     * @param tag reported by the caller
10102     * @param crashInfo describing the context of the error
10103     * @return true if the process should exit immediately (WTF is fatal)
10104     */
10105    public boolean handleApplicationWtf(IBinder app, String tag,
10106            ApplicationErrorReport.CrashInfo crashInfo) {
10107        ProcessRecord r = findAppProcess(app, "WTF");
10108        final String processName = app == null ? "system_server"
10109                : (r == null ? "unknown" : r.processName);
10110
10111        EventLog.writeEvent(EventLogTags.AM_WTF,
10112                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10113                processName,
10114                r == null ? -1 : r.info.flags,
10115                tag, crashInfo.exceptionMessage);
10116
10117        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10118
10119        if (r != null && r.pid != Process.myPid() &&
10120                Settings.Global.getInt(mContext.getContentResolver(),
10121                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10122            crashApplication(r, crashInfo);
10123            return true;
10124        } else {
10125            return false;
10126        }
10127    }
10128
10129    /**
10130     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10131     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10132     */
10133    private ProcessRecord findAppProcess(IBinder app, String reason) {
10134        if (app == null) {
10135            return null;
10136        }
10137
10138        synchronized (this) {
10139            final int NP = mProcessNames.getMap().size();
10140            for (int ip=0; ip<NP; ip++) {
10141                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10142                final int NA = apps.size();
10143                for (int ia=0; ia<NA; ia++) {
10144                    ProcessRecord p = apps.valueAt(ia);
10145                    if (p.thread != null && p.thread.asBinder() == app) {
10146                        return p;
10147                    }
10148                }
10149            }
10150
10151            Slog.w(TAG, "Can't find mystery application for " + reason
10152                    + " from pid=" + Binder.getCallingPid()
10153                    + " uid=" + Binder.getCallingUid() + ": " + app);
10154            return null;
10155        }
10156    }
10157
10158    /**
10159     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10160     * to append various headers to the dropbox log text.
10161     */
10162    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10163            StringBuilder sb) {
10164        // Watchdog thread ends up invoking this function (with
10165        // a null ProcessRecord) to add the stack file to dropbox.
10166        // Do not acquire a lock on this (am) in such cases, as it
10167        // could cause a potential deadlock, if and when watchdog
10168        // is invoked due to unavailability of lock on am and it
10169        // would prevent watchdog from killing system_server.
10170        if (process == null) {
10171            sb.append("Process: ").append(processName).append("\n");
10172            return;
10173        }
10174        // Note: ProcessRecord 'process' is guarded by the service
10175        // instance.  (notably process.pkgList, which could otherwise change
10176        // concurrently during execution of this method)
10177        synchronized (this) {
10178            sb.append("Process: ").append(processName).append("\n");
10179            int flags = process.info.flags;
10180            IPackageManager pm = AppGlobals.getPackageManager();
10181            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10182            for (int ip=0; ip<process.pkgList.size(); ip++) {
10183                String pkg = process.pkgList.keyAt(ip);
10184                sb.append("Package: ").append(pkg);
10185                try {
10186                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10187                    if (pi != null) {
10188                        sb.append(" v").append(pi.versionCode);
10189                        if (pi.versionName != null) {
10190                            sb.append(" (").append(pi.versionName).append(")");
10191                        }
10192                    }
10193                } catch (RemoteException e) {
10194                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10195                }
10196                sb.append("\n");
10197            }
10198        }
10199    }
10200
10201    private static String processClass(ProcessRecord process) {
10202        if (process == null || process.pid == MY_PID) {
10203            return "system_server";
10204        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10205            return "system_app";
10206        } else {
10207            return "data_app";
10208        }
10209    }
10210
10211    /**
10212     * Write a description of an error (crash, WTF, ANR) to the drop box.
10213     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10214     * @param process which caused the error, null means the system server
10215     * @param activity which triggered the error, null if unknown
10216     * @param parent activity related to the error, null if unknown
10217     * @param subject line related to the error, null if absent
10218     * @param report in long form describing the error, null if absent
10219     * @param logFile to include in the report, null if none
10220     * @param crashInfo giving an application stack trace, null if absent
10221     */
10222    public void addErrorToDropBox(String eventType,
10223            ProcessRecord process, String processName, ActivityRecord activity,
10224            ActivityRecord parent, String subject,
10225            final String report, final File logFile,
10226            final ApplicationErrorReport.CrashInfo crashInfo) {
10227        // NOTE -- this must never acquire the ActivityManagerService lock,
10228        // otherwise the watchdog may be prevented from resetting the system.
10229
10230        final String dropboxTag = processClass(process) + "_" + eventType;
10231        final DropBoxManager dbox = (DropBoxManager)
10232                mContext.getSystemService(Context.DROPBOX_SERVICE);
10233
10234        // Exit early if the dropbox isn't configured to accept this report type.
10235        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10236
10237        final StringBuilder sb = new StringBuilder(1024);
10238        appendDropBoxProcessHeaders(process, processName, sb);
10239        if (activity != null) {
10240            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10241        }
10242        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10243            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10244        }
10245        if (parent != null && parent != activity) {
10246            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10247        }
10248        if (subject != null) {
10249            sb.append("Subject: ").append(subject).append("\n");
10250        }
10251        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10252        if (Debug.isDebuggerConnected()) {
10253            sb.append("Debugger: Connected\n");
10254        }
10255        sb.append("\n");
10256
10257        // Do the rest in a worker thread to avoid blocking the caller on I/O
10258        // (After this point, we shouldn't access AMS internal data structures.)
10259        Thread worker = new Thread("Error dump: " + dropboxTag) {
10260            @Override
10261            public void run() {
10262                if (report != null) {
10263                    sb.append(report);
10264                }
10265                if (logFile != null) {
10266                    try {
10267                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10268                                    "\n\n[[TRUNCATED]]"));
10269                    } catch (IOException e) {
10270                        Slog.e(TAG, "Error reading " + logFile, e);
10271                    }
10272                }
10273                if (crashInfo != null && crashInfo.stackTrace != null) {
10274                    sb.append(crashInfo.stackTrace);
10275                }
10276
10277                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10278                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10279                if (lines > 0) {
10280                    sb.append("\n");
10281
10282                    // Merge several logcat streams, and take the last N lines
10283                    InputStreamReader input = null;
10284                    try {
10285                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10286                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10287                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10288
10289                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10290                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10291                        input = new InputStreamReader(logcat.getInputStream());
10292
10293                        int num;
10294                        char[] buf = new char[8192];
10295                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10296                    } catch (IOException e) {
10297                        Slog.e(TAG, "Error running logcat", e);
10298                    } finally {
10299                        if (input != null) try { input.close(); } catch (IOException e) {}
10300                    }
10301                }
10302
10303                dbox.addText(dropboxTag, sb.toString());
10304            }
10305        };
10306
10307        if (process == null) {
10308            // If process is null, we are being called from some internal code
10309            // and may be about to die -- run this synchronously.
10310            worker.run();
10311        } else {
10312            worker.start();
10313        }
10314    }
10315
10316    /**
10317     * Bring up the "unexpected error" dialog box for a crashing app.
10318     * Deal with edge cases (intercepts from instrumented applications,
10319     * ActivityController, error intent receivers, that sort of thing).
10320     * @param r the application crashing
10321     * @param crashInfo describing the failure
10322     */
10323    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10324        long timeMillis = System.currentTimeMillis();
10325        String shortMsg = crashInfo.exceptionClassName;
10326        String longMsg = crashInfo.exceptionMessage;
10327        String stackTrace = crashInfo.stackTrace;
10328        if (shortMsg != null && longMsg != null) {
10329            longMsg = shortMsg + ": " + longMsg;
10330        } else if (shortMsg != null) {
10331            longMsg = shortMsg;
10332        }
10333
10334        AppErrorResult result = new AppErrorResult();
10335        synchronized (this) {
10336            if (mController != null) {
10337                try {
10338                    String name = r != null ? r.processName : null;
10339                    int pid = r != null ? r.pid : Binder.getCallingPid();
10340                    if (!mController.appCrashed(name, pid,
10341                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10342                        Slog.w(TAG, "Force-killing crashed app " + name
10343                                + " at watcher's request");
10344                        Process.killProcess(pid);
10345                        return;
10346                    }
10347                } catch (RemoteException e) {
10348                    mController = null;
10349                    Watchdog.getInstance().setActivityController(null);
10350                }
10351            }
10352
10353            final long origId = Binder.clearCallingIdentity();
10354
10355            // If this process is running instrumentation, finish it.
10356            if (r != null && r.instrumentationClass != null) {
10357                Slog.w(TAG, "Error in app " + r.processName
10358                      + " running instrumentation " + r.instrumentationClass + ":");
10359                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10360                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10361                Bundle info = new Bundle();
10362                info.putString("shortMsg", shortMsg);
10363                info.putString("longMsg", longMsg);
10364                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10365                Binder.restoreCallingIdentity(origId);
10366                return;
10367            }
10368
10369            // If we can't identify the process or it's already exceeded its crash quota,
10370            // quit right away without showing a crash dialog.
10371            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10372                Binder.restoreCallingIdentity(origId);
10373                return;
10374            }
10375
10376            Message msg = Message.obtain();
10377            msg.what = SHOW_ERROR_MSG;
10378            HashMap data = new HashMap();
10379            data.put("result", result);
10380            data.put("app", r);
10381            msg.obj = data;
10382            mHandler.sendMessage(msg);
10383
10384            Binder.restoreCallingIdentity(origId);
10385        }
10386
10387        int res = result.get();
10388
10389        Intent appErrorIntent = null;
10390        synchronized (this) {
10391            if (r != null && !r.isolated) {
10392                // XXX Can't keep track of crash time for isolated processes,
10393                // since they don't have a persistent identity.
10394                mProcessCrashTimes.put(r.info.processName, r.uid,
10395                        SystemClock.uptimeMillis());
10396            }
10397            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10398                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10399            }
10400        }
10401
10402        if (appErrorIntent != null) {
10403            try {
10404                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10405            } catch (ActivityNotFoundException e) {
10406                Slog.w(TAG, "bug report receiver dissappeared", e);
10407            }
10408        }
10409    }
10410
10411    Intent createAppErrorIntentLocked(ProcessRecord r,
10412            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10413        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10414        if (report == null) {
10415            return null;
10416        }
10417        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10418        result.setComponent(r.errorReportReceiver);
10419        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10420        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10421        return result;
10422    }
10423
10424    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10425            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10426        if (r.errorReportReceiver == null) {
10427            return null;
10428        }
10429
10430        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10431            return null;
10432        }
10433
10434        ApplicationErrorReport report = new ApplicationErrorReport();
10435        report.packageName = r.info.packageName;
10436        report.installerPackageName = r.errorReportReceiver.getPackageName();
10437        report.processName = r.processName;
10438        report.time = timeMillis;
10439        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10440
10441        if (r.crashing || r.forceCrashReport) {
10442            report.type = ApplicationErrorReport.TYPE_CRASH;
10443            report.crashInfo = crashInfo;
10444        } else if (r.notResponding) {
10445            report.type = ApplicationErrorReport.TYPE_ANR;
10446            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10447
10448            report.anrInfo.activity = r.notRespondingReport.tag;
10449            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10450            report.anrInfo.info = r.notRespondingReport.longMsg;
10451        }
10452
10453        return report;
10454    }
10455
10456    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10457        enforceNotIsolatedCaller("getProcessesInErrorState");
10458        // assume our apps are happy - lazy create the list
10459        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10460
10461        final boolean allUsers = ActivityManager.checkUidPermission(
10462                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10463                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10464        int userId = UserHandle.getUserId(Binder.getCallingUid());
10465
10466        synchronized (this) {
10467
10468            // iterate across all processes
10469            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10470                ProcessRecord app = mLruProcesses.get(i);
10471                if (!allUsers && app.userId != userId) {
10472                    continue;
10473                }
10474                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10475                    // This one's in trouble, so we'll generate a report for it
10476                    // crashes are higher priority (in case there's a crash *and* an anr)
10477                    ActivityManager.ProcessErrorStateInfo report = null;
10478                    if (app.crashing) {
10479                        report = app.crashingReport;
10480                    } else if (app.notResponding) {
10481                        report = app.notRespondingReport;
10482                    }
10483
10484                    if (report != null) {
10485                        if (errList == null) {
10486                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10487                        }
10488                        errList.add(report);
10489                    } else {
10490                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10491                                " crashing = " + app.crashing +
10492                                " notResponding = " + app.notResponding);
10493                    }
10494                }
10495            }
10496        }
10497
10498        return errList;
10499    }
10500
10501    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10502        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10503            if (currApp != null) {
10504                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10505            }
10506            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10507        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10508            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10509        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10510            if (currApp != null) {
10511                currApp.lru = 0;
10512            }
10513            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10514        } else if (adj >= ProcessList.SERVICE_ADJ) {
10515            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10516        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10517            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10518        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10519            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10520        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10521            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10522        } else {
10523            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10524        }
10525    }
10526
10527    private void fillInProcMemInfo(ProcessRecord app,
10528            ActivityManager.RunningAppProcessInfo outInfo) {
10529        outInfo.pid = app.pid;
10530        outInfo.uid = app.info.uid;
10531        if (mHeavyWeightProcess == app) {
10532            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10533        }
10534        if (app.persistent) {
10535            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10536        }
10537        if (app.activities.size() > 0) {
10538            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10539        }
10540        outInfo.lastTrimLevel = app.trimMemoryLevel;
10541        int adj = app.curAdj;
10542        outInfo.importance = oomAdjToImportance(adj, outInfo);
10543        outInfo.importanceReasonCode = app.adjTypeCode;
10544        outInfo.processState = app.curProcState;
10545    }
10546
10547    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10548        enforceNotIsolatedCaller("getRunningAppProcesses");
10549        // Lazy instantiation of list
10550        List<ActivityManager.RunningAppProcessInfo> runList = null;
10551        final boolean allUsers = ActivityManager.checkUidPermission(
10552                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10553                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10554        int userId = UserHandle.getUserId(Binder.getCallingUid());
10555        synchronized (this) {
10556            // Iterate across all processes
10557            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10558                ProcessRecord app = mLruProcesses.get(i);
10559                if (!allUsers && app.userId != userId) {
10560                    continue;
10561                }
10562                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10563                    // Generate process state info for running application
10564                    ActivityManager.RunningAppProcessInfo currApp =
10565                        new ActivityManager.RunningAppProcessInfo(app.processName,
10566                                app.pid, app.getPackageList());
10567                    fillInProcMemInfo(app, currApp);
10568                    if (app.adjSource instanceof ProcessRecord) {
10569                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10570                        currApp.importanceReasonImportance = oomAdjToImportance(
10571                                app.adjSourceOom, null);
10572                    } else if (app.adjSource instanceof ActivityRecord) {
10573                        ActivityRecord r = (ActivityRecord)app.adjSource;
10574                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10575                    }
10576                    if (app.adjTarget instanceof ComponentName) {
10577                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10578                    }
10579                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10580                    //        + " lru=" + currApp.lru);
10581                    if (runList == null) {
10582                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10583                    }
10584                    runList.add(currApp);
10585                }
10586            }
10587        }
10588        return runList;
10589    }
10590
10591    public List<ApplicationInfo> getRunningExternalApplications() {
10592        enforceNotIsolatedCaller("getRunningExternalApplications");
10593        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10594        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10595        if (runningApps != null && runningApps.size() > 0) {
10596            Set<String> extList = new HashSet<String>();
10597            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10598                if (app.pkgList != null) {
10599                    for (String pkg : app.pkgList) {
10600                        extList.add(pkg);
10601                    }
10602                }
10603            }
10604            IPackageManager pm = AppGlobals.getPackageManager();
10605            for (String pkg : extList) {
10606                try {
10607                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10608                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10609                        retList.add(info);
10610                    }
10611                } catch (RemoteException e) {
10612                }
10613            }
10614        }
10615        return retList;
10616    }
10617
10618    @Override
10619    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10620        enforceNotIsolatedCaller("getMyMemoryState");
10621        synchronized (this) {
10622            ProcessRecord proc;
10623            synchronized (mPidsSelfLocked) {
10624                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10625            }
10626            fillInProcMemInfo(proc, outInfo);
10627        }
10628    }
10629
10630    @Override
10631    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10632        if (checkCallingPermission(android.Manifest.permission.DUMP)
10633                != PackageManager.PERMISSION_GRANTED) {
10634            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10635                    + Binder.getCallingPid()
10636                    + ", uid=" + Binder.getCallingUid()
10637                    + " without permission "
10638                    + android.Manifest.permission.DUMP);
10639            return;
10640        }
10641
10642        boolean dumpAll = false;
10643        boolean dumpClient = false;
10644        String dumpPackage = null;
10645
10646        int opti = 0;
10647        while (opti < args.length) {
10648            String opt = args[opti];
10649            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10650                break;
10651            }
10652            opti++;
10653            if ("-a".equals(opt)) {
10654                dumpAll = true;
10655            } else if ("-c".equals(opt)) {
10656                dumpClient = true;
10657            } else if ("-h".equals(opt)) {
10658                pw.println("Activity manager dump options:");
10659                pw.println("  [-a] [-c] [-h] [cmd] ...");
10660                pw.println("  cmd may be one of:");
10661                pw.println("    a[ctivities]: activity stack state");
10662                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10663                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10664                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10665                pw.println("    o[om]: out of memory management");
10666                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10667                pw.println("    provider [COMP_SPEC]: provider client-side state");
10668                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10669                pw.println("    service [COMP_SPEC]: service client-side state");
10670                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10671                pw.println("    all: dump all activities");
10672                pw.println("    top: dump the top activity");
10673                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10674                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10675                pw.println("    a partial substring in a component name, a");
10676                pw.println("    hex object identifier.");
10677                pw.println("  -a: include all available server state.");
10678                pw.println("  -c: include client state.");
10679                return;
10680            } else {
10681                pw.println("Unknown argument: " + opt + "; use -h for help");
10682            }
10683        }
10684
10685        long origId = Binder.clearCallingIdentity();
10686        boolean more = false;
10687        // Is the caller requesting to dump a particular piece of data?
10688        if (opti < args.length) {
10689            String cmd = args[opti];
10690            opti++;
10691            if ("activities".equals(cmd) || "a".equals(cmd)) {
10692                synchronized (this) {
10693                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10694                }
10695            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10696                String[] newArgs;
10697                String name;
10698                if (opti >= args.length) {
10699                    name = null;
10700                    newArgs = EMPTY_STRING_ARRAY;
10701                } else {
10702                    name = args[opti];
10703                    opti++;
10704                    newArgs = new String[args.length - opti];
10705                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10706                            args.length - opti);
10707                }
10708                synchronized (this) {
10709                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10710                }
10711            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10712                String[] newArgs;
10713                String name;
10714                if (opti >= args.length) {
10715                    name = null;
10716                    newArgs = EMPTY_STRING_ARRAY;
10717                } else {
10718                    name = args[opti];
10719                    opti++;
10720                    newArgs = new String[args.length - opti];
10721                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10722                            args.length - opti);
10723                }
10724                synchronized (this) {
10725                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10726                }
10727            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10728                String[] newArgs;
10729                String name;
10730                if (opti >= args.length) {
10731                    name = null;
10732                    newArgs = EMPTY_STRING_ARRAY;
10733                } else {
10734                    name = args[opti];
10735                    opti++;
10736                    newArgs = new String[args.length - opti];
10737                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10738                            args.length - opti);
10739                }
10740                synchronized (this) {
10741                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10742                }
10743            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10744                synchronized (this) {
10745                    dumpOomLocked(fd, pw, args, opti, true);
10746                }
10747            } else if ("provider".equals(cmd)) {
10748                String[] newArgs;
10749                String name;
10750                if (opti >= args.length) {
10751                    name = null;
10752                    newArgs = EMPTY_STRING_ARRAY;
10753                } else {
10754                    name = args[opti];
10755                    opti++;
10756                    newArgs = new String[args.length - opti];
10757                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10758                }
10759                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10760                    pw.println("No providers match: " + name);
10761                    pw.println("Use -h for help.");
10762                }
10763            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10764                synchronized (this) {
10765                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10766                }
10767            } else if ("service".equals(cmd)) {
10768                String[] newArgs;
10769                String name;
10770                if (opti >= args.length) {
10771                    name = null;
10772                    newArgs = EMPTY_STRING_ARRAY;
10773                } else {
10774                    name = args[opti];
10775                    opti++;
10776                    newArgs = new String[args.length - opti];
10777                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10778                            args.length - opti);
10779                }
10780                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10781                    pw.println("No services match: " + name);
10782                    pw.println("Use -h for help.");
10783                }
10784            } else if ("package".equals(cmd)) {
10785                String[] newArgs;
10786                if (opti >= args.length) {
10787                    pw.println("package: no package name specified");
10788                    pw.println("Use -h for help.");
10789                } else {
10790                    dumpPackage = args[opti];
10791                    opti++;
10792                    newArgs = new String[args.length - opti];
10793                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10794                            args.length - opti);
10795                    args = newArgs;
10796                    opti = 0;
10797                    more = true;
10798                }
10799            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10800                synchronized (this) {
10801                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10802                }
10803            } else {
10804                // Dumping a single activity?
10805                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10806                    pw.println("Bad activity command, or no activities match: " + cmd);
10807                    pw.println("Use -h for help.");
10808                }
10809            }
10810            if (!more) {
10811                Binder.restoreCallingIdentity(origId);
10812                return;
10813            }
10814        }
10815
10816        // No piece of data specified, dump everything.
10817        synchronized (this) {
10818            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10819            pw.println();
10820            if (dumpAll) {
10821                pw.println("-------------------------------------------------------------------------------");
10822            }
10823            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10824            pw.println();
10825            if (dumpAll) {
10826                pw.println("-------------------------------------------------------------------------------");
10827            }
10828            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10829            pw.println();
10830            if (dumpAll) {
10831                pw.println("-------------------------------------------------------------------------------");
10832            }
10833            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10834            pw.println();
10835            if (dumpAll) {
10836                pw.println("-------------------------------------------------------------------------------");
10837            }
10838            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10839            pw.println();
10840            if (dumpAll) {
10841                pw.println("-------------------------------------------------------------------------------");
10842            }
10843            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10844        }
10845        Binder.restoreCallingIdentity(origId);
10846    }
10847
10848    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10849            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10850        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10851
10852        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10853                dumpPackage);
10854        boolean needSep = printedAnything;
10855
10856        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10857                dumpPackage, needSep, "  mFocusedActivity: ");
10858        if (printed) {
10859            printedAnything = true;
10860            needSep = false;
10861        }
10862
10863        if (dumpPackage == null) {
10864            if (needSep) {
10865                pw.println();
10866            }
10867            needSep = true;
10868            printedAnything = true;
10869            mStackSupervisor.dump(pw, "  ");
10870        }
10871
10872        if (mRecentTasks.size() > 0) {
10873            boolean printedHeader = false;
10874
10875            final int N = mRecentTasks.size();
10876            for (int i=0; i<N; i++) {
10877                TaskRecord tr = mRecentTasks.get(i);
10878                if (dumpPackage != null) {
10879                    if (tr.realActivity == null ||
10880                            !dumpPackage.equals(tr.realActivity)) {
10881                        continue;
10882                    }
10883                }
10884                if (!printedHeader) {
10885                    if (needSep) {
10886                        pw.println();
10887                    }
10888                    pw.println("  Recent tasks:");
10889                    printedHeader = true;
10890                    printedAnything = true;
10891                }
10892                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10893                        pw.println(tr);
10894                if (dumpAll) {
10895                    mRecentTasks.get(i).dump(pw, "    ");
10896                }
10897            }
10898        }
10899
10900        if (!printedAnything) {
10901            pw.println("  (nothing)");
10902        }
10903    }
10904
10905    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10906            int opti, boolean dumpAll, String dumpPackage) {
10907        boolean needSep = false;
10908        boolean printedAnything = false;
10909        int numPers = 0;
10910
10911        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
10912
10913        if (dumpAll) {
10914            final int NP = mProcessNames.getMap().size();
10915            for (int ip=0; ip<NP; ip++) {
10916                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
10917                final int NA = procs.size();
10918                for (int ia=0; ia<NA; ia++) {
10919                    ProcessRecord r = procs.valueAt(ia);
10920                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10921                        continue;
10922                    }
10923                    if (!needSep) {
10924                        pw.println("  All known processes:");
10925                        needSep = true;
10926                        printedAnything = true;
10927                    }
10928                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
10929                        pw.print(" UID "); pw.print(procs.keyAt(ia));
10930                        pw.print(" "); pw.println(r);
10931                    r.dump(pw, "    ");
10932                    if (r.persistent) {
10933                        numPers++;
10934                    }
10935                }
10936            }
10937        }
10938
10939        if (mIsolatedProcesses.size() > 0) {
10940            boolean printed = false;
10941            for (int i=0; i<mIsolatedProcesses.size(); i++) {
10942                ProcessRecord r = mIsolatedProcesses.valueAt(i);
10943                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10944                    continue;
10945                }
10946                if (!printed) {
10947                    if (needSep) {
10948                        pw.println();
10949                    }
10950                    pw.println("  Isolated process list (sorted by uid):");
10951                    printedAnything = true;
10952                    printed = true;
10953                    needSep = true;
10954                }
10955                pw.println(String.format("%sIsolated #%2d: %s",
10956                        "    ", i, r.toString()));
10957            }
10958        }
10959
10960        if (mLruProcesses.size() > 0) {
10961            if (needSep) {
10962                pw.println();
10963            }
10964            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
10965                    pw.print(" total, non-act at ");
10966                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10967                    pw.print(", non-svc at ");
10968                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10969                    pw.println("):");
10970            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
10971            needSep = true;
10972            printedAnything = true;
10973        }
10974
10975        if (dumpAll || dumpPackage != null) {
10976            synchronized (mPidsSelfLocked) {
10977                boolean printed = false;
10978                for (int i=0; i<mPidsSelfLocked.size(); i++) {
10979                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
10980                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10981                        continue;
10982                    }
10983                    if (!printed) {
10984                        if (needSep) pw.println();
10985                        needSep = true;
10986                        pw.println("  PID mappings:");
10987                        printed = true;
10988                        printedAnything = true;
10989                    }
10990                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
10991                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
10992                }
10993            }
10994        }
10995
10996        if (mForegroundProcesses.size() > 0) {
10997            synchronized (mPidsSelfLocked) {
10998                boolean printed = false;
10999                for (int i=0; i<mForegroundProcesses.size(); i++) {
11000                    ProcessRecord r = mPidsSelfLocked.get(
11001                            mForegroundProcesses.valueAt(i).pid);
11002                    if (dumpPackage != null && (r == null
11003                            || !r.pkgList.containsKey(dumpPackage))) {
11004                        continue;
11005                    }
11006                    if (!printed) {
11007                        if (needSep) pw.println();
11008                        needSep = true;
11009                        pw.println("  Foreground Processes:");
11010                        printed = true;
11011                        printedAnything = true;
11012                    }
11013                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11014                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11015                }
11016            }
11017        }
11018
11019        if (mPersistentStartingProcesses.size() > 0) {
11020            if (needSep) pw.println();
11021            needSep = true;
11022            printedAnything = true;
11023            pw.println("  Persisent processes that are starting:");
11024            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11025                    "Starting Norm", "Restarting PERS", dumpPackage);
11026        }
11027
11028        if (mRemovedProcesses.size() > 0) {
11029            if (needSep) pw.println();
11030            needSep = true;
11031            printedAnything = true;
11032            pw.println("  Processes that are being removed:");
11033            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11034                    "Removed Norm", "Removed PERS", dumpPackage);
11035        }
11036
11037        if (mProcessesOnHold.size() > 0) {
11038            if (needSep) pw.println();
11039            needSep = true;
11040            printedAnything = true;
11041            pw.println("  Processes that are on old until the system is ready:");
11042            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11043                    "OnHold Norm", "OnHold PERS", dumpPackage);
11044        }
11045
11046        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11047
11048        if (mProcessCrashTimes.getMap().size() > 0) {
11049            boolean printed = false;
11050            long now = SystemClock.uptimeMillis();
11051            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11052            final int NP = pmap.size();
11053            for (int ip=0; ip<NP; ip++) {
11054                String pname = pmap.keyAt(ip);
11055                SparseArray<Long> uids = pmap.valueAt(ip);
11056                final int N = uids.size();
11057                for (int i=0; i<N; i++) {
11058                    int puid = uids.keyAt(i);
11059                    ProcessRecord r = mProcessNames.get(pname, puid);
11060                    if (dumpPackage != null && (r == null
11061                            || !r.pkgList.containsKey(dumpPackage))) {
11062                        continue;
11063                    }
11064                    if (!printed) {
11065                        if (needSep) pw.println();
11066                        needSep = true;
11067                        pw.println("  Time since processes crashed:");
11068                        printed = true;
11069                        printedAnything = true;
11070                    }
11071                    pw.print("    Process "); pw.print(pname);
11072                            pw.print(" uid "); pw.print(puid);
11073                            pw.print(": last crashed ");
11074                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11075                            pw.println(" ago");
11076                }
11077            }
11078        }
11079
11080        if (mBadProcesses.getMap().size() > 0) {
11081            boolean printed = false;
11082            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11083            final int NP = pmap.size();
11084            for (int ip=0; ip<NP; ip++) {
11085                String pname = pmap.keyAt(ip);
11086                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11087                final int N = uids.size();
11088                for (int i=0; i<N; i++) {
11089                    int puid = uids.keyAt(i);
11090                    ProcessRecord r = mProcessNames.get(pname, puid);
11091                    if (dumpPackage != null && (r == null
11092                            || !r.pkgList.containsKey(dumpPackage))) {
11093                        continue;
11094                    }
11095                    if (!printed) {
11096                        if (needSep) pw.println();
11097                        needSep = true;
11098                        pw.println("  Bad processes:");
11099                        printedAnything = true;
11100                    }
11101                    BadProcessInfo info = uids.valueAt(i);
11102                    pw.print("    Bad process "); pw.print(pname);
11103                            pw.print(" uid "); pw.print(puid);
11104                            pw.print(": crashed at time "); pw.println(info.time);
11105                    if (info.shortMsg != null) {
11106                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11107                    }
11108                    if (info.longMsg != null) {
11109                        pw.print("      Long msg: "); pw.println(info.longMsg);
11110                    }
11111                    if (info.stack != null) {
11112                        pw.println("      Stack:");
11113                        int lastPos = 0;
11114                        for (int pos=0; pos<info.stack.length(); pos++) {
11115                            if (info.stack.charAt(pos) == '\n') {
11116                                pw.print("        ");
11117                                pw.write(info.stack, lastPos, pos-lastPos);
11118                                pw.println();
11119                                lastPos = pos+1;
11120                            }
11121                        }
11122                        if (lastPos < info.stack.length()) {
11123                            pw.print("        ");
11124                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11125                            pw.println();
11126                        }
11127                    }
11128                }
11129            }
11130        }
11131
11132        if (dumpPackage == null) {
11133            pw.println();
11134            needSep = false;
11135            pw.println("  mStartedUsers:");
11136            for (int i=0; i<mStartedUsers.size(); i++) {
11137                UserStartedState uss = mStartedUsers.valueAt(i);
11138                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11139                        pw.print(": "); uss.dump("", pw);
11140            }
11141            pw.print("  mStartedUserArray: [");
11142            for (int i=0; i<mStartedUserArray.length; i++) {
11143                if (i > 0) pw.print(", ");
11144                pw.print(mStartedUserArray[i]);
11145            }
11146            pw.println("]");
11147            pw.print("  mUserLru: [");
11148            for (int i=0; i<mUserLru.size(); i++) {
11149                if (i > 0) pw.print(", ");
11150                pw.print(mUserLru.get(i));
11151            }
11152            pw.println("]");
11153            if (dumpAll) {
11154                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11155            }
11156        }
11157        if (mHomeProcess != null && (dumpPackage == null
11158                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11159            if (needSep) {
11160                pw.println();
11161                needSep = false;
11162            }
11163            pw.println("  mHomeProcess: " + mHomeProcess);
11164        }
11165        if (mPreviousProcess != null && (dumpPackage == null
11166                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11167            if (needSep) {
11168                pw.println();
11169                needSep = false;
11170            }
11171            pw.println("  mPreviousProcess: " + mPreviousProcess);
11172        }
11173        if (dumpAll) {
11174            StringBuilder sb = new StringBuilder(128);
11175            sb.append("  mPreviousProcessVisibleTime: ");
11176            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11177            pw.println(sb);
11178        }
11179        if (mHeavyWeightProcess != null && (dumpPackage == null
11180                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11181            if (needSep) {
11182                pw.println();
11183                needSep = false;
11184            }
11185            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11186        }
11187        if (dumpPackage == null) {
11188            pw.println("  mConfiguration: " + mConfiguration);
11189        }
11190        if (dumpAll) {
11191            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11192            if (mCompatModePackages.getPackages().size() > 0) {
11193                boolean printed = false;
11194                for (Map.Entry<String, Integer> entry
11195                        : mCompatModePackages.getPackages().entrySet()) {
11196                    String pkg = entry.getKey();
11197                    int mode = entry.getValue();
11198                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11199                        continue;
11200                    }
11201                    if (!printed) {
11202                        pw.println("  mScreenCompatPackages:");
11203                        printed = true;
11204                    }
11205                    pw.print("    "); pw.print(pkg); pw.print(": ");
11206                            pw.print(mode); pw.println();
11207                }
11208            }
11209        }
11210        if (dumpPackage == null) {
11211            if (mSleeping || mWentToSleep || mLockScreenShown) {
11212                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11213                        + " mLockScreenShown " + mLockScreenShown);
11214            }
11215            if (mShuttingDown || mRunningVoice) {
11216                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11217            }
11218        }
11219        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11220                || mOrigWaitForDebugger) {
11221            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11222                    || dumpPackage.equals(mOrigDebugApp)) {
11223                if (needSep) {
11224                    pw.println();
11225                    needSep = false;
11226                }
11227                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11228                        + " mDebugTransient=" + mDebugTransient
11229                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11230            }
11231        }
11232        if (mOpenGlTraceApp != null) {
11233            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11234                if (needSep) {
11235                    pw.println();
11236                    needSep = false;
11237                }
11238                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11239            }
11240        }
11241        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11242                || mProfileFd != null) {
11243            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11244                if (needSep) {
11245                    pw.println();
11246                    needSep = false;
11247                }
11248                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11249                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11250                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11251                        + mAutoStopProfiler);
11252            }
11253        }
11254        if (dumpPackage == null) {
11255            if (mAlwaysFinishActivities || mController != null) {
11256                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11257                        + " mController=" + mController);
11258            }
11259            if (dumpAll) {
11260                pw.println("  Total persistent processes: " + numPers);
11261                pw.println("  mProcessesReady=" + mProcessesReady
11262                        + " mSystemReady=" + mSystemReady);
11263                pw.println("  mBooting=" + mBooting
11264                        + " mBooted=" + mBooted
11265                        + " mFactoryTest=" + mFactoryTest);
11266                pw.print("  mLastPowerCheckRealtime=");
11267                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11268                        pw.println("");
11269                pw.print("  mLastPowerCheckUptime=");
11270                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11271                        pw.println("");
11272                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11273                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11274                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11275                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11276                        + " (" + mLruProcesses.size() + " total)"
11277                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11278                        + " mNumServiceProcs=" + mNumServiceProcs
11279                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11280                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11281                        + " mLastMemoryLevel" + mLastMemoryLevel
11282                        + " mLastNumProcesses" + mLastNumProcesses);
11283                long now = SystemClock.uptimeMillis();
11284                pw.print("  mLastIdleTime=");
11285                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11286                        pw.print(" mLowRamSinceLastIdle=");
11287                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11288                        pw.println();
11289            }
11290        }
11291
11292        if (!printedAnything) {
11293            pw.println("  (nothing)");
11294        }
11295    }
11296
11297    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11298            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11299        if (mProcessesToGc.size() > 0) {
11300            boolean printed = false;
11301            long now = SystemClock.uptimeMillis();
11302            for (int i=0; i<mProcessesToGc.size(); i++) {
11303                ProcessRecord proc = mProcessesToGc.get(i);
11304                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11305                    continue;
11306                }
11307                if (!printed) {
11308                    if (needSep) pw.println();
11309                    needSep = true;
11310                    pw.println("  Processes that are waiting to GC:");
11311                    printed = true;
11312                }
11313                pw.print("    Process "); pw.println(proc);
11314                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11315                        pw.print(", last gced=");
11316                        pw.print(now-proc.lastRequestedGc);
11317                        pw.print(" ms ago, last lowMem=");
11318                        pw.print(now-proc.lastLowMemory);
11319                        pw.println(" ms ago");
11320
11321            }
11322        }
11323        return needSep;
11324    }
11325
11326    void printOomLevel(PrintWriter pw, String name, int adj) {
11327        pw.print("    ");
11328        if (adj >= 0) {
11329            pw.print(' ');
11330            if (adj < 10) pw.print(' ');
11331        } else {
11332            if (adj > -10) pw.print(' ');
11333        }
11334        pw.print(adj);
11335        pw.print(": ");
11336        pw.print(name);
11337        pw.print(" (");
11338        pw.print(mProcessList.getMemLevel(adj)/1024);
11339        pw.println(" kB)");
11340    }
11341
11342    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11343            int opti, boolean dumpAll) {
11344        boolean needSep = false;
11345
11346        if (mLruProcesses.size() > 0) {
11347            if (needSep) pw.println();
11348            needSep = true;
11349            pw.println("  OOM levels:");
11350            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11351            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11352            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11353            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11354            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11355            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11356            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11357            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11358            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11359            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11360            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11361            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11362            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11363
11364            if (needSep) pw.println();
11365            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11366                    pw.print(" total, non-act at ");
11367                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11368                    pw.print(", non-svc at ");
11369                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11370                    pw.println("):");
11371            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11372            needSep = true;
11373        }
11374
11375        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11376
11377        pw.println();
11378        pw.println("  mHomeProcess: " + mHomeProcess);
11379        pw.println("  mPreviousProcess: " + mPreviousProcess);
11380        if (mHeavyWeightProcess != null) {
11381            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11382        }
11383
11384        return true;
11385    }
11386
11387    /**
11388     * There are three ways to call this:
11389     *  - no provider specified: dump all the providers
11390     *  - a flattened component name that matched an existing provider was specified as the
11391     *    first arg: dump that one provider
11392     *  - the first arg isn't the flattened component name of an existing provider:
11393     *    dump all providers whose component contains the first arg as a substring
11394     */
11395    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11396            int opti, boolean dumpAll) {
11397        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11398    }
11399
11400    static class ItemMatcher {
11401        ArrayList<ComponentName> components;
11402        ArrayList<String> strings;
11403        ArrayList<Integer> objects;
11404        boolean all;
11405
11406        ItemMatcher() {
11407            all = true;
11408        }
11409
11410        void build(String name) {
11411            ComponentName componentName = ComponentName.unflattenFromString(name);
11412            if (componentName != null) {
11413                if (components == null) {
11414                    components = new ArrayList<ComponentName>();
11415                }
11416                components.add(componentName);
11417                all = false;
11418            } else {
11419                int objectId = 0;
11420                // Not a '/' separated full component name; maybe an object ID?
11421                try {
11422                    objectId = Integer.parseInt(name, 16);
11423                    if (objects == null) {
11424                        objects = new ArrayList<Integer>();
11425                    }
11426                    objects.add(objectId);
11427                    all = false;
11428                } catch (RuntimeException e) {
11429                    // Not an integer; just do string match.
11430                    if (strings == null) {
11431                        strings = new ArrayList<String>();
11432                    }
11433                    strings.add(name);
11434                    all = false;
11435                }
11436            }
11437        }
11438
11439        int build(String[] args, int opti) {
11440            for (; opti<args.length; opti++) {
11441                String name = args[opti];
11442                if ("--".equals(name)) {
11443                    return opti+1;
11444                }
11445                build(name);
11446            }
11447            return opti;
11448        }
11449
11450        boolean match(Object object, ComponentName comp) {
11451            if (all) {
11452                return true;
11453            }
11454            if (components != null) {
11455                for (int i=0; i<components.size(); i++) {
11456                    if (components.get(i).equals(comp)) {
11457                        return true;
11458                    }
11459                }
11460            }
11461            if (objects != null) {
11462                for (int i=0; i<objects.size(); i++) {
11463                    if (System.identityHashCode(object) == objects.get(i)) {
11464                        return true;
11465                    }
11466                }
11467            }
11468            if (strings != null) {
11469                String flat = comp.flattenToString();
11470                for (int i=0; i<strings.size(); i++) {
11471                    if (flat.contains(strings.get(i))) {
11472                        return true;
11473                    }
11474                }
11475            }
11476            return false;
11477        }
11478    }
11479
11480    /**
11481     * There are three things that cmd can be:
11482     *  - a flattened component name that matches an existing activity
11483     *  - the cmd arg isn't the flattened component name of an existing activity:
11484     *    dump all activity whose component contains the cmd as a substring
11485     *  - A hex number of the ActivityRecord object instance.
11486     */
11487    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11488            int opti, boolean dumpAll) {
11489        ArrayList<ActivityRecord> activities;
11490
11491        synchronized (this) {
11492            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11493        }
11494
11495        if (activities.size() <= 0) {
11496            return false;
11497        }
11498
11499        String[] newArgs = new String[args.length - opti];
11500        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11501
11502        TaskRecord lastTask = null;
11503        boolean needSep = false;
11504        for (int i=activities.size()-1; i>=0; i--) {
11505            ActivityRecord r = activities.get(i);
11506            if (needSep) {
11507                pw.println();
11508            }
11509            needSep = true;
11510            synchronized (this) {
11511                if (lastTask != r.task) {
11512                    lastTask = r.task;
11513                    pw.print("TASK "); pw.print(lastTask.affinity);
11514                            pw.print(" id="); pw.println(lastTask.taskId);
11515                    if (dumpAll) {
11516                        lastTask.dump(pw, "  ");
11517                    }
11518                }
11519            }
11520            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11521        }
11522        return true;
11523    }
11524
11525    /**
11526     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11527     * there is a thread associated with the activity.
11528     */
11529    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11530            final ActivityRecord r, String[] args, boolean dumpAll) {
11531        String innerPrefix = prefix + "  ";
11532        synchronized (this) {
11533            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11534                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11535                    pw.print(" pid=");
11536                    if (r.app != null) pw.println(r.app.pid);
11537                    else pw.println("(not running)");
11538            if (dumpAll) {
11539                r.dump(pw, innerPrefix);
11540            }
11541        }
11542        if (r.app != null && r.app.thread != null) {
11543            // flush anything that is already in the PrintWriter since the thread is going
11544            // to write to the file descriptor directly
11545            pw.flush();
11546            try {
11547                TransferPipe tp = new TransferPipe();
11548                try {
11549                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11550                            r.appToken, innerPrefix, args);
11551                    tp.go(fd);
11552                } finally {
11553                    tp.kill();
11554                }
11555            } catch (IOException e) {
11556                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11557            } catch (RemoteException e) {
11558                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11559            }
11560        }
11561    }
11562
11563    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11564            int opti, boolean dumpAll, String dumpPackage) {
11565        boolean needSep = false;
11566        boolean onlyHistory = false;
11567        boolean printedAnything = false;
11568
11569        if ("history".equals(dumpPackage)) {
11570            if (opti < args.length && "-s".equals(args[opti])) {
11571                dumpAll = false;
11572            }
11573            onlyHistory = true;
11574            dumpPackage = null;
11575        }
11576
11577        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11578        if (!onlyHistory && dumpAll) {
11579            if (mRegisteredReceivers.size() > 0) {
11580                boolean printed = false;
11581                Iterator it = mRegisteredReceivers.values().iterator();
11582                while (it.hasNext()) {
11583                    ReceiverList r = (ReceiverList)it.next();
11584                    if (dumpPackage != null && (r.app == null ||
11585                            !dumpPackage.equals(r.app.info.packageName))) {
11586                        continue;
11587                    }
11588                    if (!printed) {
11589                        pw.println("  Registered Receivers:");
11590                        needSep = true;
11591                        printed = true;
11592                        printedAnything = true;
11593                    }
11594                    pw.print("  * "); pw.println(r);
11595                    r.dump(pw, "    ");
11596                }
11597            }
11598
11599            if (mReceiverResolver.dump(pw, needSep ?
11600                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11601                    "    ", dumpPackage, false)) {
11602                needSep = true;
11603                printedAnything = true;
11604            }
11605        }
11606
11607        for (BroadcastQueue q : mBroadcastQueues) {
11608            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11609            printedAnything |= needSep;
11610        }
11611
11612        needSep = true;
11613
11614        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11615            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11616                if (needSep) {
11617                    pw.println();
11618                }
11619                needSep = true;
11620                printedAnything = true;
11621                pw.print("  Sticky broadcasts for user ");
11622                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11623                StringBuilder sb = new StringBuilder(128);
11624                for (Map.Entry<String, ArrayList<Intent>> ent
11625                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11626                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11627                    if (dumpAll) {
11628                        pw.println(":");
11629                        ArrayList<Intent> intents = ent.getValue();
11630                        final int N = intents.size();
11631                        for (int i=0; i<N; i++) {
11632                            sb.setLength(0);
11633                            sb.append("    Intent: ");
11634                            intents.get(i).toShortString(sb, false, true, false, false);
11635                            pw.println(sb.toString());
11636                            Bundle bundle = intents.get(i).getExtras();
11637                            if (bundle != null) {
11638                                pw.print("      ");
11639                                pw.println(bundle.toString());
11640                            }
11641                        }
11642                    } else {
11643                        pw.println("");
11644                    }
11645                }
11646            }
11647        }
11648
11649        if (!onlyHistory && dumpAll) {
11650            pw.println();
11651            for (BroadcastQueue queue : mBroadcastQueues) {
11652                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11653                        + queue.mBroadcastsScheduled);
11654            }
11655            pw.println("  mHandler:");
11656            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11657            needSep = true;
11658            printedAnything = true;
11659        }
11660
11661        if (!printedAnything) {
11662            pw.println("  (nothing)");
11663        }
11664    }
11665
11666    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11667            int opti, boolean dumpAll, String dumpPackage) {
11668        boolean needSep;
11669        boolean printedAnything = false;
11670
11671        ItemMatcher matcher = new ItemMatcher();
11672        matcher.build(args, opti);
11673
11674        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11675
11676        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11677        printedAnything |= needSep;
11678
11679        if (mLaunchingProviders.size() > 0) {
11680            boolean printed = false;
11681            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11682                ContentProviderRecord r = mLaunchingProviders.get(i);
11683                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11684                    continue;
11685                }
11686                if (!printed) {
11687                    if (needSep) pw.println();
11688                    needSep = true;
11689                    pw.println("  Launching content providers:");
11690                    printed = true;
11691                    printedAnything = true;
11692                }
11693                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11694                        pw.println(r);
11695            }
11696        }
11697
11698        if (mGrantedUriPermissions.size() > 0) {
11699            boolean printed = false;
11700            int dumpUid = -2;
11701            if (dumpPackage != null) {
11702                try {
11703                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11704                } catch (NameNotFoundException e) {
11705                    dumpUid = -1;
11706                }
11707            }
11708            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11709                int uid = mGrantedUriPermissions.keyAt(i);
11710                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11711                    continue;
11712                }
11713                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
11714                if (!printed) {
11715                    if (needSep) pw.println();
11716                    needSep = true;
11717                    pw.println("  Granted Uri Permissions:");
11718                    printed = true;
11719                    printedAnything = true;
11720                }
11721                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
11722                for (UriPermission perm : perms.values()) {
11723                    pw.print("    "); pw.println(perm);
11724                    if (dumpAll) {
11725                        perm.dump(pw, "      ");
11726                    }
11727                }
11728            }
11729        }
11730
11731        if (!printedAnything) {
11732            pw.println("  (nothing)");
11733        }
11734    }
11735
11736    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11737            int opti, boolean dumpAll, String dumpPackage) {
11738        boolean printed = false;
11739
11740        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11741
11742        if (mIntentSenderRecords.size() > 0) {
11743            Iterator<WeakReference<PendingIntentRecord>> it
11744                    = mIntentSenderRecords.values().iterator();
11745            while (it.hasNext()) {
11746                WeakReference<PendingIntentRecord> ref = it.next();
11747                PendingIntentRecord rec = ref != null ? ref.get(): null;
11748                if (dumpPackage != null && (rec == null
11749                        || !dumpPackage.equals(rec.key.packageName))) {
11750                    continue;
11751                }
11752                printed = true;
11753                if (rec != null) {
11754                    pw.print("  * "); pw.println(rec);
11755                    if (dumpAll) {
11756                        rec.dump(pw, "    ");
11757                    }
11758                } else {
11759                    pw.print("  * "); pw.println(ref);
11760                }
11761            }
11762        }
11763
11764        if (!printed) {
11765            pw.println("  (nothing)");
11766        }
11767    }
11768
11769    private static final int dumpProcessList(PrintWriter pw,
11770            ActivityManagerService service, List list,
11771            String prefix, String normalLabel, String persistentLabel,
11772            String dumpPackage) {
11773        int numPers = 0;
11774        final int N = list.size()-1;
11775        for (int i=N; i>=0; i--) {
11776            ProcessRecord r = (ProcessRecord)list.get(i);
11777            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11778                continue;
11779            }
11780            pw.println(String.format("%s%s #%2d: %s",
11781                    prefix, (r.persistent ? persistentLabel : normalLabel),
11782                    i, r.toString()));
11783            if (r.persistent) {
11784                numPers++;
11785            }
11786        }
11787        return numPers;
11788    }
11789
11790    private static final boolean dumpProcessOomList(PrintWriter pw,
11791            ActivityManagerService service, List<ProcessRecord> origList,
11792            String prefix, String normalLabel, String persistentLabel,
11793            boolean inclDetails, String dumpPackage) {
11794
11795        ArrayList<Pair<ProcessRecord, Integer>> list
11796                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11797        for (int i=0; i<origList.size(); i++) {
11798            ProcessRecord r = origList.get(i);
11799            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11800                continue;
11801            }
11802            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11803        }
11804
11805        if (list.size() <= 0) {
11806            return false;
11807        }
11808
11809        Comparator<Pair<ProcessRecord, Integer>> comparator
11810                = new Comparator<Pair<ProcessRecord, Integer>>() {
11811            @Override
11812            public int compare(Pair<ProcessRecord, Integer> object1,
11813                    Pair<ProcessRecord, Integer> object2) {
11814                if (object1.first.setAdj != object2.first.setAdj) {
11815                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11816                }
11817                if (object1.second.intValue() != object2.second.intValue()) {
11818                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11819                }
11820                return 0;
11821            }
11822        };
11823
11824        Collections.sort(list, comparator);
11825
11826        final long curRealtime = SystemClock.elapsedRealtime();
11827        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11828        final long curUptime = SystemClock.uptimeMillis();
11829        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11830
11831        for (int i=list.size()-1; i>=0; i--) {
11832            ProcessRecord r = list.get(i).first;
11833            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11834            char schedGroup;
11835            switch (r.setSchedGroup) {
11836                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11837                    schedGroup = 'B';
11838                    break;
11839                case Process.THREAD_GROUP_DEFAULT:
11840                    schedGroup = 'F';
11841                    break;
11842                default:
11843                    schedGroup = '?';
11844                    break;
11845            }
11846            char foreground;
11847            if (r.foregroundActivities) {
11848                foreground = 'A';
11849            } else if (r.foregroundServices) {
11850                foreground = 'S';
11851            } else {
11852                foreground = ' ';
11853            }
11854            String procState = ProcessList.makeProcStateString(r.curProcState);
11855            pw.print(prefix);
11856            pw.print(r.persistent ? persistentLabel : normalLabel);
11857            pw.print(" #");
11858            int num = (origList.size()-1)-list.get(i).second;
11859            if (num < 10) pw.print(' ');
11860            pw.print(num);
11861            pw.print(": ");
11862            pw.print(oomAdj);
11863            pw.print(' ');
11864            pw.print(schedGroup);
11865            pw.print('/');
11866            pw.print(foreground);
11867            pw.print('/');
11868            pw.print(procState);
11869            pw.print(" trm:");
11870            if (r.trimMemoryLevel < 10) pw.print(' ');
11871            pw.print(r.trimMemoryLevel);
11872            pw.print(' ');
11873            pw.print(r.toShortString());
11874            pw.print(" (");
11875            pw.print(r.adjType);
11876            pw.println(')');
11877            if (r.adjSource != null || r.adjTarget != null) {
11878                pw.print(prefix);
11879                pw.print("    ");
11880                if (r.adjTarget instanceof ComponentName) {
11881                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11882                } else if (r.adjTarget != null) {
11883                    pw.print(r.adjTarget.toString());
11884                } else {
11885                    pw.print("{null}");
11886                }
11887                pw.print("<=");
11888                if (r.adjSource instanceof ProcessRecord) {
11889                    pw.print("Proc{");
11890                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11891                    pw.println("}");
11892                } else if (r.adjSource != null) {
11893                    pw.println(r.adjSource.toString());
11894                } else {
11895                    pw.println("{null}");
11896                }
11897            }
11898            if (inclDetails) {
11899                pw.print(prefix);
11900                pw.print("    ");
11901                pw.print("oom: max="); pw.print(r.maxAdj);
11902                pw.print(" curRaw="); pw.print(r.curRawAdj);
11903                pw.print(" setRaw="); pw.print(r.setRawAdj);
11904                pw.print(" cur="); pw.print(r.curAdj);
11905                pw.print(" set="); pw.println(r.setAdj);
11906                pw.print(prefix);
11907                pw.print("    ");
11908                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
11909                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
11910                pw.print(" lastPss="); pw.print(r.lastPss);
11911                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
11912                pw.print(prefix);
11913                pw.print("    ");
11914                pw.print("keeping="); pw.print(r.keeping);
11915                pw.print(" cached="); pw.print(r.cached);
11916                pw.print(" empty="); pw.print(r.empty);
11917                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
11918
11919                if (!r.keeping) {
11920                    if (r.lastWakeTime != 0) {
11921                        long wtime;
11922                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
11923                        synchronized (stats) {
11924                            wtime = stats.getProcessWakeTime(r.info.uid,
11925                                    r.pid, curRealtime);
11926                        }
11927                        long timeUsed = wtime - r.lastWakeTime;
11928                        pw.print(prefix);
11929                        pw.print("    ");
11930                        pw.print("keep awake over ");
11931                        TimeUtils.formatDuration(realtimeSince, pw);
11932                        pw.print(" used ");
11933                        TimeUtils.formatDuration(timeUsed, pw);
11934                        pw.print(" (");
11935                        pw.print((timeUsed*100)/realtimeSince);
11936                        pw.println("%)");
11937                    }
11938                    if (r.lastCpuTime != 0) {
11939                        long timeUsed = r.curCpuTime - r.lastCpuTime;
11940                        pw.print(prefix);
11941                        pw.print("    ");
11942                        pw.print("run cpu over ");
11943                        TimeUtils.formatDuration(uptimeSince, pw);
11944                        pw.print(" used ");
11945                        TimeUtils.formatDuration(timeUsed, pw);
11946                        pw.print(" (");
11947                        pw.print((timeUsed*100)/uptimeSince);
11948                        pw.println("%)");
11949                    }
11950                }
11951            }
11952        }
11953        return true;
11954    }
11955
11956    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
11957        ArrayList<ProcessRecord> procs;
11958        synchronized (this) {
11959            if (args != null && args.length > start
11960                    && args[start].charAt(0) != '-') {
11961                procs = new ArrayList<ProcessRecord>();
11962                int pid = -1;
11963                try {
11964                    pid = Integer.parseInt(args[start]);
11965                } catch (NumberFormatException e) {
11966                }
11967                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11968                    ProcessRecord proc = mLruProcesses.get(i);
11969                    if (proc.pid == pid) {
11970                        procs.add(proc);
11971                    } else if (proc.processName.equals(args[start])) {
11972                        procs.add(proc);
11973                    }
11974                }
11975                if (procs.size() <= 0) {
11976                    return null;
11977                }
11978            } else {
11979                procs = new ArrayList<ProcessRecord>(mLruProcesses);
11980            }
11981        }
11982        return procs;
11983    }
11984
11985    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
11986            PrintWriter pw, String[] args) {
11987        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11988        if (procs == null) {
11989            pw.println("No process found for: " + args[0]);
11990            return;
11991        }
11992
11993        long uptime = SystemClock.uptimeMillis();
11994        long realtime = SystemClock.elapsedRealtime();
11995        pw.println("Applications Graphics Acceleration Info:");
11996        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11997
11998        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11999            ProcessRecord r = procs.get(i);
12000            if (r.thread != null) {
12001                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12002                pw.flush();
12003                try {
12004                    TransferPipe tp = new TransferPipe();
12005                    try {
12006                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12007                        tp.go(fd);
12008                    } finally {
12009                        tp.kill();
12010                    }
12011                } catch (IOException e) {
12012                    pw.println("Failure while dumping the app: " + r);
12013                    pw.flush();
12014                } catch (RemoteException e) {
12015                    pw.println("Got a RemoteException while dumping the app " + r);
12016                    pw.flush();
12017                }
12018            }
12019        }
12020    }
12021
12022    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12023        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12024        if (procs == null) {
12025            pw.println("No process found for: " + args[0]);
12026            return;
12027        }
12028
12029        pw.println("Applications Database Info:");
12030
12031        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12032            ProcessRecord r = procs.get(i);
12033            if (r.thread != null) {
12034                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12035                pw.flush();
12036                try {
12037                    TransferPipe tp = new TransferPipe();
12038                    try {
12039                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12040                        tp.go(fd);
12041                    } finally {
12042                        tp.kill();
12043                    }
12044                } catch (IOException e) {
12045                    pw.println("Failure while dumping the app: " + r);
12046                    pw.flush();
12047                } catch (RemoteException e) {
12048                    pw.println("Got a RemoteException while dumping the app " + r);
12049                    pw.flush();
12050                }
12051            }
12052        }
12053    }
12054
12055    final static class MemItem {
12056        final boolean isProc;
12057        final String label;
12058        final String shortLabel;
12059        final long pss;
12060        final int id;
12061        final boolean hasActivities;
12062        ArrayList<MemItem> subitems;
12063
12064        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12065                boolean _hasActivities) {
12066            isProc = true;
12067            label = _label;
12068            shortLabel = _shortLabel;
12069            pss = _pss;
12070            id = _id;
12071            hasActivities = _hasActivities;
12072        }
12073
12074        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12075            isProc = false;
12076            label = _label;
12077            shortLabel = _shortLabel;
12078            pss = _pss;
12079            id = _id;
12080            hasActivities = false;
12081        }
12082    }
12083
12084    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12085            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12086        if (sort && !isCompact) {
12087            Collections.sort(items, new Comparator<MemItem>() {
12088                @Override
12089                public int compare(MemItem lhs, MemItem rhs) {
12090                    if (lhs.pss < rhs.pss) {
12091                        return 1;
12092                    } else if (lhs.pss > rhs.pss) {
12093                        return -1;
12094                    }
12095                    return 0;
12096                }
12097            });
12098        }
12099
12100        for (int i=0; i<items.size(); i++) {
12101            MemItem mi = items.get(i);
12102            if (!isCompact) {
12103                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12104            } else if (mi.isProc) {
12105                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12106                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12107                pw.println(mi.hasActivities ? ",a" : ",e");
12108            } else {
12109                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12110                pw.println(mi.pss);
12111            }
12112            if (mi.subitems != null) {
12113                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12114                        true, isCompact);
12115            }
12116        }
12117    }
12118
12119    // These are in KB.
12120    static final long[] DUMP_MEM_BUCKETS = new long[] {
12121        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12122        120*1024, 160*1024, 200*1024,
12123        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12124        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12125    };
12126
12127    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12128            boolean stackLike) {
12129        int start = label.lastIndexOf('.');
12130        if (start >= 0) start++;
12131        else start = 0;
12132        int end = label.length();
12133        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12134            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12135                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12136                out.append(bucket);
12137                out.append(stackLike ? "MB." : "MB ");
12138                out.append(label, start, end);
12139                return;
12140            }
12141        }
12142        out.append(memKB/1024);
12143        out.append(stackLike ? "MB." : "MB ");
12144        out.append(label, start, end);
12145    }
12146
12147    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12148            ProcessList.NATIVE_ADJ,
12149            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12150            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12151            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12152            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12153            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12154    };
12155    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12156            "Native",
12157            "System", "Persistent", "Foreground",
12158            "Visible", "Perceptible",
12159            "Heavy Weight", "Backup",
12160            "A Services", "Home",
12161            "Previous", "B Services", "Cached"
12162    };
12163    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12164            "native",
12165            "sys", "pers", "fore",
12166            "vis", "percept",
12167            "heavy", "backup",
12168            "servicea", "home",
12169            "prev", "serviceb", "cached"
12170    };
12171
12172    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12173            long realtime, boolean isCheckinRequest, boolean isCompact) {
12174        if (isCheckinRequest || isCompact) {
12175            // short checkin version
12176            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12177        } else {
12178            pw.println("Applications Memory Usage (kB):");
12179            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12180        }
12181    }
12182
12183    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12184            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12185        boolean dumpDetails = false;
12186        boolean dumpFullDetails = false;
12187        boolean dumpDalvik = false;
12188        boolean oomOnly = false;
12189        boolean isCompact = false;
12190        boolean localOnly = false;
12191
12192        int opti = 0;
12193        while (opti < args.length) {
12194            String opt = args[opti];
12195            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12196                break;
12197            }
12198            opti++;
12199            if ("-a".equals(opt)) {
12200                dumpDetails = true;
12201                dumpFullDetails = true;
12202                dumpDalvik = true;
12203            } else if ("-d".equals(opt)) {
12204                dumpDalvik = true;
12205            } else if ("-c".equals(opt)) {
12206                isCompact = true;
12207            } else if ("--oom".equals(opt)) {
12208                oomOnly = true;
12209            } else if ("--local".equals(opt)) {
12210                localOnly = true;
12211            } else if ("-h".equals(opt)) {
12212                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12213                pw.println("  -a: include all available information for each process.");
12214                pw.println("  -d: include dalvik details when dumping process details.");
12215                pw.println("  -c: dump in a compact machine-parseable representation.");
12216                pw.println("  --oom: only show processes organized by oom adj.");
12217                pw.println("  --local: only collect details locally, don't call process.");
12218                pw.println("If [process] is specified it can be the name or ");
12219                pw.println("pid of a specific process to dump.");
12220                return;
12221            } else {
12222                pw.println("Unknown argument: " + opt + "; use -h for help");
12223            }
12224        }
12225
12226        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12227        long uptime = SystemClock.uptimeMillis();
12228        long realtime = SystemClock.elapsedRealtime();
12229        final long[] tmpLong = new long[1];
12230
12231        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12232        if (procs == null) {
12233            // No Java processes.  Maybe they want to print a native process.
12234            if (args != null && args.length > opti
12235                    && args[opti].charAt(0) != '-') {
12236                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12237                        = new ArrayList<ProcessCpuTracker.Stats>();
12238                updateCpuStatsNow();
12239                int findPid = -1;
12240                try {
12241                    findPid = Integer.parseInt(args[opti]);
12242                } catch (NumberFormatException e) {
12243                }
12244                synchronized (mProcessCpuThread) {
12245                    final int N = mProcessCpuTracker.countStats();
12246                    for (int i=0; i<N; i++) {
12247                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12248                        if (st.pid == findPid || (st.baseName != null
12249                                && st.baseName.equals(args[opti]))) {
12250                            nativeProcs.add(st);
12251                        }
12252                    }
12253                }
12254                if (nativeProcs.size() > 0) {
12255                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12256                            isCompact);
12257                    Debug.MemoryInfo mi = null;
12258                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12259                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12260                        final int pid = r.pid;
12261                        if (!isCheckinRequest && dumpDetails) {
12262                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12263                        }
12264                        if (mi == null) {
12265                            mi = new Debug.MemoryInfo();
12266                        }
12267                        if (dumpDetails || (!brief && !oomOnly)) {
12268                            Debug.getMemoryInfo(pid, mi);
12269                        } else {
12270                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12271                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12272                        }
12273                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12274                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12275                        if (isCheckinRequest) {
12276                            pw.println();
12277                        }
12278                    }
12279                    return;
12280                }
12281            }
12282            pw.println("No process found for: " + args[opti]);
12283            return;
12284        }
12285
12286        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12287            dumpDetails = true;
12288        }
12289
12290        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12291
12292        String[] innerArgs = new String[args.length-opti];
12293        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12294
12295        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12296        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12297        long nativePss=0, dalvikPss=0, otherPss=0;
12298        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12299
12300        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12301        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12302                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12303
12304        long totalPss = 0;
12305        long cachedPss = 0;
12306
12307        Debug.MemoryInfo mi = null;
12308        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12309            final ProcessRecord r = procs.get(i);
12310            final IApplicationThread thread;
12311            final int pid;
12312            final int oomAdj;
12313            final boolean hasActivities;
12314            synchronized (this) {
12315                thread = r.thread;
12316                pid = r.pid;
12317                oomAdj = r.getSetAdjWithServices();
12318                hasActivities = r.activities.size() > 0;
12319            }
12320            if (thread != null) {
12321                if (!isCheckinRequest && dumpDetails) {
12322                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12323                }
12324                if (mi == null) {
12325                    mi = new Debug.MemoryInfo();
12326                }
12327                if (dumpDetails || (!brief && !oomOnly)) {
12328                    Debug.getMemoryInfo(pid, mi);
12329                } else {
12330                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12331                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12332                }
12333                if (dumpDetails) {
12334                    if (localOnly) {
12335                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12336                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12337                        if (isCheckinRequest) {
12338                            pw.println();
12339                        }
12340                    } else {
12341                        try {
12342                            pw.flush();
12343                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12344                                    dumpDalvik, innerArgs);
12345                        } catch (RemoteException e) {
12346                            if (!isCheckinRequest) {
12347                                pw.println("Got RemoteException!");
12348                                pw.flush();
12349                            }
12350                        }
12351                    }
12352                }
12353
12354                final long myTotalPss = mi.getTotalPss();
12355                final long myTotalUss = mi.getTotalUss();
12356
12357                synchronized (this) {
12358                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12359                        // Record this for posterity if the process has been stable.
12360                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12361                    }
12362                }
12363
12364                if (!isCheckinRequest && mi != null) {
12365                    totalPss += myTotalPss;
12366                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12367                            (hasActivities ? " / activities)" : ")"),
12368                            r.processName, myTotalPss, pid, hasActivities);
12369                    procMems.add(pssItem);
12370                    procMemsMap.put(pid, pssItem);
12371
12372                    nativePss += mi.nativePss;
12373                    dalvikPss += mi.dalvikPss;
12374                    otherPss += mi.otherPss;
12375                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12376                        long mem = mi.getOtherPss(j);
12377                        miscPss[j] += mem;
12378                        otherPss -= mem;
12379                    }
12380
12381                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12382                        cachedPss += myTotalPss;
12383                    }
12384
12385                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12386                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12387                                || oomIndex == (oomPss.length-1)) {
12388                            oomPss[oomIndex] += myTotalPss;
12389                            if (oomProcs[oomIndex] == null) {
12390                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12391                            }
12392                            oomProcs[oomIndex].add(pssItem);
12393                            break;
12394                        }
12395                    }
12396                }
12397            }
12398        }
12399
12400        if (!isCheckinRequest && procs.size() > 1) {
12401            // If we are showing aggregations, also look for native processes to
12402            // include so that our aggregations are more accurate.
12403            updateCpuStatsNow();
12404            synchronized (mProcessCpuThread) {
12405                final int N = mProcessCpuTracker.countStats();
12406                for (int i=0; i<N; i++) {
12407                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12408                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12409                        if (mi == null) {
12410                            mi = new Debug.MemoryInfo();
12411                        }
12412                        if (!brief && !oomOnly) {
12413                            Debug.getMemoryInfo(st.pid, mi);
12414                        } else {
12415                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12416                            mi.nativePrivateDirty = (int)tmpLong[0];
12417                        }
12418
12419                        final long myTotalPss = mi.getTotalPss();
12420                        totalPss += myTotalPss;
12421
12422                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12423                                st.name, myTotalPss, st.pid, false);
12424                        procMems.add(pssItem);
12425
12426                        nativePss += mi.nativePss;
12427                        dalvikPss += mi.dalvikPss;
12428                        otherPss += mi.otherPss;
12429                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12430                            long mem = mi.getOtherPss(j);
12431                            miscPss[j] += mem;
12432                            otherPss -= mem;
12433                        }
12434                        oomPss[0] += myTotalPss;
12435                        if (oomProcs[0] == null) {
12436                            oomProcs[0] = new ArrayList<MemItem>();
12437                        }
12438                        oomProcs[0].add(pssItem);
12439                    }
12440                }
12441            }
12442
12443            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12444
12445            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12446            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12447            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12448            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12449                String label = Debug.MemoryInfo.getOtherLabel(j);
12450                catMems.add(new MemItem(label, label, miscPss[j], j));
12451            }
12452
12453            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12454            for (int j=0; j<oomPss.length; j++) {
12455                if (oomPss[j] != 0) {
12456                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12457                            : DUMP_MEM_OOM_LABEL[j];
12458                    MemItem item = new MemItem(label, label, oomPss[j],
12459                            DUMP_MEM_OOM_ADJ[j]);
12460                    item.subitems = oomProcs[j];
12461                    oomMems.add(item);
12462                }
12463            }
12464
12465            if (!brief && !oomOnly && !isCompact) {
12466                pw.println();
12467                pw.println("Total PSS by process:");
12468                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12469                pw.println();
12470            }
12471            if (!isCompact) {
12472                pw.println("Total PSS by OOM adjustment:");
12473            }
12474            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12475            if (!brief && !oomOnly) {
12476                PrintWriter out = categoryPw != null ? categoryPw : pw;
12477                if (!isCompact) {
12478                    out.println();
12479                    out.println("Total PSS by category:");
12480                }
12481                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12482            }
12483            if (!isCompact) {
12484                pw.println();
12485            }
12486            MemInfoReader memInfo = new MemInfoReader();
12487            memInfo.readMemInfo();
12488            if (!brief) {
12489                if (!isCompact) {
12490                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12491                    pw.print(" kB (status ");
12492                    switch (mLastMemoryLevel) {
12493                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12494                            pw.println("normal)");
12495                            break;
12496                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12497                            pw.println("moderate)");
12498                            break;
12499                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12500                            pw.println("low)");
12501                            break;
12502                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12503                            pw.println("critical)");
12504                            break;
12505                        default:
12506                            pw.print(mLastMemoryLevel);
12507                            pw.println(")");
12508                            break;
12509                    }
12510                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12511                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12512                            pw.print(cachedPss); pw.print(" cached pss + ");
12513                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12514                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12515                } else {
12516                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12517                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12518                            + memInfo.getFreeSizeKb()); pw.print(",");
12519                    pw.println(totalPss - cachedPss);
12520                }
12521            }
12522            if (!isCompact) {
12523                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12524                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12525                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12526                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12527                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12528                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12529                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12530                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12531                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12532                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12533                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12534            }
12535            if (!brief) {
12536                if (memInfo.getZramTotalSizeKb() != 0) {
12537                    if (!isCompact) {
12538                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12539                                pw.print(" kB physical used for ");
12540                                pw.print(memInfo.getSwapTotalSizeKb()
12541                                        - memInfo.getSwapFreeSizeKb());
12542                                pw.print(" kB in swap (");
12543                                pw.print(memInfo.getSwapTotalSizeKb());
12544                                pw.println(" kB total swap)");
12545                    } else {
12546                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12547                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12548                                pw.println(memInfo.getSwapFreeSizeKb());
12549                    }
12550                }
12551                final int[] SINGLE_LONG_FORMAT = new int[] {
12552                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12553                };
12554                long[] longOut = new long[1];
12555                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12556                        SINGLE_LONG_FORMAT, null, longOut, null);
12557                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12558                longOut[0] = 0;
12559                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12560                        SINGLE_LONG_FORMAT, null, longOut, null);
12561                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12562                longOut[0] = 0;
12563                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12564                        SINGLE_LONG_FORMAT, null, longOut, null);
12565                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12566                longOut[0] = 0;
12567                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12568                        SINGLE_LONG_FORMAT, null, longOut, null);
12569                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12570                if (!isCompact) {
12571                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12572                        pw.print("      KSM: "); pw.print(sharing);
12573                                pw.print(" kB saved from shared ");
12574                                pw.print(shared); pw.println(" kB");
12575                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12576                                pw.print(voltile); pw.println(" kB volatile");
12577                    }
12578                    pw.print("   Tuning: ");
12579                    pw.print(ActivityManager.staticGetMemoryClass());
12580                    pw.print(" (large ");
12581                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12582                    pw.print("), oom ");
12583                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12584                    pw.print(" kB");
12585                    pw.print(", restore limit ");
12586                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12587                    pw.print(" kB");
12588                    if (ActivityManager.isLowRamDeviceStatic()) {
12589                        pw.print(" (low-ram)");
12590                    }
12591                    if (ActivityManager.isHighEndGfx()) {
12592                        pw.print(" (high-end-gfx)");
12593                    }
12594                    pw.println();
12595                } else {
12596                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12597                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12598                    pw.println(voltile);
12599                    pw.print("tuning,");
12600                    pw.print(ActivityManager.staticGetMemoryClass());
12601                    pw.print(',');
12602                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12603                    pw.print(',');
12604                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12605                    if (ActivityManager.isLowRamDeviceStatic()) {
12606                        pw.print(",low-ram");
12607                    }
12608                    if (ActivityManager.isHighEndGfx()) {
12609                        pw.print(",high-end-gfx");
12610                    }
12611                    pw.println();
12612                }
12613            }
12614        }
12615    }
12616
12617    /**
12618     * Searches array of arguments for the specified string
12619     * @param args array of argument strings
12620     * @param value value to search for
12621     * @return true if the value is contained in the array
12622     */
12623    private static boolean scanArgs(String[] args, String value) {
12624        if (args != null) {
12625            for (String arg : args) {
12626                if (value.equals(arg)) {
12627                    return true;
12628                }
12629            }
12630        }
12631        return false;
12632    }
12633
12634    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12635            ContentProviderRecord cpr, boolean always) {
12636        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12637
12638        if (!inLaunching || always) {
12639            synchronized (cpr) {
12640                cpr.launchingApp = null;
12641                cpr.notifyAll();
12642            }
12643            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12644            String names[] = cpr.info.authority.split(";");
12645            for (int j = 0; j < names.length; j++) {
12646                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12647            }
12648        }
12649
12650        for (int i=0; i<cpr.connections.size(); i++) {
12651            ContentProviderConnection conn = cpr.connections.get(i);
12652            if (conn.waiting) {
12653                // If this connection is waiting for the provider, then we don't
12654                // need to mess with its process unless we are always removing
12655                // or for some reason the provider is not currently launching.
12656                if (inLaunching && !always) {
12657                    continue;
12658                }
12659            }
12660            ProcessRecord capp = conn.client;
12661            conn.dead = true;
12662            if (conn.stableCount > 0) {
12663                if (!capp.persistent && capp.thread != null
12664                        && capp.pid != 0
12665                        && capp.pid != MY_PID) {
12666                    killUnneededProcessLocked(capp, "depends on provider "
12667                            + cpr.name.flattenToShortString()
12668                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12669                }
12670            } else if (capp.thread != null && conn.provider.provider != null) {
12671                try {
12672                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12673                } catch (RemoteException e) {
12674                }
12675                // In the protocol here, we don't expect the client to correctly
12676                // clean up this connection, we'll just remove it.
12677                cpr.connections.remove(i);
12678                conn.client.conProviders.remove(conn);
12679            }
12680        }
12681
12682        if (inLaunching && always) {
12683            mLaunchingProviders.remove(cpr);
12684        }
12685        return inLaunching;
12686    }
12687
12688    /**
12689     * Main code for cleaning up a process when it has gone away.  This is
12690     * called both as a result of the process dying, or directly when stopping
12691     * a process when running in single process mode.
12692     */
12693    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12694            boolean restarting, boolean allowRestart, int index) {
12695        if (index >= 0) {
12696            removeLruProcessLocked(app);
12697            ProcessList.remove(app.pid);
12698        }
12699
12700        mProcessesToGc.remove(app);
12701        mPendingPssProcesses.remove(app);
12702
12703        // Dismiss any open dialogs.
12704        if (app.crashDialog != null && !app.forceCrashReport) {
12705            app.crashDialog.dismiss();
12706            app.crashDialog = null;
12707        }
12708        if (app.anrDialog != null) {
12709            app.anrDialog.dismiss();
12710            app.anrDialog = null;
12711        }
12712        if (app.waitDialog != null) {
12713            app.waitDialog.dismiss();
12714            app.waitDialog = null;
12715        }
12716
12717        app.crashing = false;
12718        app.notResponding = false;
12719
12720        app.resetPackageList(mProcessStats);
12721        app.unlinkDeathRecipient();
12722        app.makeInactive(mProcessStats);
12723        app.forcingToForeground = null;
12724        updateProcessForegroundLocked(app, false, false);
12725        app.foregroundActivities = false;
12726        app.hasShownUi = false;
12727        app.treatLikeActivity = false;
12728        app.hasAboveClient = false;
12729        app.hasClientActivities = false;
12730
12731        mServices.killServicesLocked(app, allowRestart);
12732
12733        boolean restart = false;
12734
12735        // Remove published content providers.
12736        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12737            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12738            final boolean always = app.bad || !allowRestart;
12739            if (removeDyingProviderLocked(app, cpr, always) || always) {
12740                // We left the provider in the launching list, need to
12741                // restart it.
12742                restart = true;
12743            }
12744
12745            cpr.provider = null;
12746            cpr.proc = null;
12747        }
12748        app.pubProviders.clear();
12749
12750        // Take care of any launching providers waiting for this process.
12751        if (checkAppInLaunchingProvidersLocked(app, false)) {
12752            restart = true;
12753        }
12754
12755        // Unregister from connected content providers.
12756        if (!app.conProviders.isEmpty()) {
12757            for (int i=0; i<app.conProviders.size(); i++) {
12758                ContentProviderConnection conn = app.conProviders.get(i);
12759                conn.provider.connections.remove(conn);
12760            }
12761            app.conProviders.clear();
12762        }
12763
12764        // At this point there may be remaining entries in mLaunchingProviders
12765        // where we were the only one waiting, so they are no longer of use.
12766        // Look for these and clean up if found.
12767        // XXX Commented out for now.  Trying to figure out a way to reproduce
12768        // the actual situation to identify what is actually going on.
12769        if (false) {
12770            for (int i=0; i<mLaunchingProviders.size(); i++) {
12771                ContentProviderRecord cpr = (ContentProviderRecord)
12772                        mLaunchingProviders.get(i);
12773                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12774                    synchronized (cpr) {
12775                        cpr.launchingApp = null;
12776                        cpr.notifyAll();
12777                    }
12778                }
12779            }
12780        }
12781
12782        skipCurrentReceiverLocked(app);
12783
12784        // Unregister any receivers.
12785        for (int i=app.receivers.size()-1; i>=0; i--) {
12786            removeReceiverLocked(app.receivers.valueAt(i));
12787        }
12788        app.receivers.clear();
12789
12790        // If the app is undergoing backup, tell the backup manager about it
12791        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12792            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12793                    + mBackupTarget.appInfo + " died during backup");
12794            try {
12795                IBackupManager bm = IBackupManager.Stub.asInterface(
12796                        ServiceManager.getService(Context.BACKUP_SERVICE));
12797                bm.agentDisconnected(app.info.packageName);
12798            } catch (RemoteException e) {
12799                // can't happen; backup manager is local
12800            }
12801        }
12802
12803        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12804            ProcessChangeItem item = mPendingProcessChanges.get(i);
12805            if (item.pid == app.pid) {
12806                mPendingProcessChanges.remove(i);
12807                mAvailProcessChanges.add(item);
12808            }
12809        }
12810        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12811
12812        // If the caller is restarting this app, then leave it in its
12813        // current lists and let the caller take care of it.
12814        if (restarting) {
12815            return;
12816        }
12817
12818        if (!app.persistent || app.isolated) {
12819            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12820                    "Removing non-persistent process during cleanup: " + app);
12821            mProcessNames.remove(app.processName, app.uid);
12822            mIsolatedProcesses.remove(app.uid);
12823            if (mHeavyWeightProcess == app) {
12824                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12825                        mHeavyWeightProcess.userId, 0));
12826                mHeavyWeightProcess = null;
12827            }
12828        } else if (!app.removed) {
12829            // This app is persistent, so we need to keep its record around.
12830            // If it is not already on the pending app list, add it there
12831            // and start a new process for it.
12832            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12833                mPersistentStartingProcesses.add(app);
12834                restart = true;
12835            }
12836        }
12837        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12838                "Clean-up removing on hold: " + app);
12839        mProcessesOnHold.remove(app);
12840
12841        if (app == mHomeProcess) {
12842            mHomeProcess = null;
12843        }
12844        if (app == mPreviousProcess) {
12845            mPreviousProcess = null;
12846        }
12847
12848        if (restart && !app.isolated) {
12849            // We have components that still need to be running in the
12850            // process, so re-launch it.
12851            mProcessNames.put(app.processName, app.uid, app);
12852            startProcessLocked(app, "restart", app.processName);
12853        } else if (app.pid > 0 && app.pid != MY_PID) {
12854            // Goodbye!
12855            boolean removed;
12856            synchronized (mPidsSelfLocked) {
12857                mPidsSelfLocked.remove(app.pid);
12858                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12859            }
12860            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
12861                    app.processName, app.info.uid);
12862            if (app.isolated) {
12863                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
12864            }
12865            app.setPid(0);
12866        }
12867    }
12868
12869    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12870        // Look through the content providers we are waiting to have launched,
12871        // and if any run in this process then either schedule a restart of
12872        // the process or kill the client waiting for it if this process has
12873        // gone bad.
12874        int NL = mLaunchingProviders.size();
12875        boolean restart = false;
12876        for (int i=0; i<NL; i++) {
12877            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12878            if (cpr.launchingApp == app) {
12879                if (!alwaysBad && !app.bad) {
12880                    restart = true;
12881                } else {
12882                    removeDyingProviderLocked(app, cpr, true);
12883                    // cpr should have been removed from mLaunchingProviders
12884                    NL = mLaunchingProviders.size();
12885                    i--;
12886                }
12887            }
12888        }
12889        return restart;
12890    }
12891
12892    // =========================================================
12893    // SERVICES
12894    // =========================================================
12895
12896    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12897            int flags) {
12898        enforceNotIsolatedCaller("getServices");
12899        synchronized (this) {
12900            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12901        }
12902    }
12903
12904    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12905        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12906        synchronized (this) {
12907            return mServices.getRunningServiceControlPanelLocked(name);
12908        }
12909    }
12910
12911    public ComponentName startService(IApplicationThread caller, Intent service,
12912            String resolvedType, int userId) {
12913        enforceNotIsolatedCaller("startService");
12914        // Refuse possible leaked file descriptors
12915        if (service != null && service.hasFileDescriptors() == true) {
12916            throw new IllegalArgumentException("File descriptors passed in Intent");
12917        }
12918
12919        if (DEBUG_SERVICE)
12920            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
12921        synchronized(this) {
12922            final int callingPid = Binder.getCallingPid();
12923            final int callingUid = Binder.getCallingUid();
12924            final long origId = Binder.clearCallingIdentity();
12925            ComponentName res = mServices.startServiceLocked(caller, service,
12926                    resolvedType, callingPid, callingUid, userId);
12927            Binder.restoreCallingIdentity(origId);
12928            return res;
12929        }
12930    }
12931
12932    ComponentName startServiceInPackage(int uid,
12933            Intent service, String resolvedType, int userId) {
12934        synchronized(this) {
12935            if (DEBUG_SERVICE)
12936                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
12937            final long origId = Binder.clearCallingIdentity();
12938            ComponentName res = mServices.startServiceLocked(null, service,
12939                    resolvedType, -1, uid, userId);
12940            Binder.restoreCallingIdentity(origId);
12941            return res;
12942        }
12943    }
12944
12945    public int stopService(IApplicationThread caller, Intent service,
12946            String resolvedType, int userId) {
12947        enforceNotIsolatedCaller("stopService");
12948        // Refuse possible leaked file descriptors
12949        if (service != null && service.hasFileDescriptors() == true) {
12950            throw new IllegalArgumentException("File descriptors passed in Intent");
12951        }
12952
12953        synchronized(this) {
12954            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
12955        }
12956    }
12957
12958    public IBinder peekService(Intent service, String resolvedType) {
12959        enforceNotIsolatedCaller("peekService");
12960        // Refuse possible leaked file descriptors
12961        if (service != null && service.hasFileDescriptors() == true) {
12962            throw new IllegalArgumentException("File descriptors passed in Intent");
12963        }
12964        synchronized(this) {
12965            return mServices.peekServiceLocked(service, resolvedType);
12966        }
12967    }
12968
12969    public boolean stopServiceToken(ComponentName className, IBinder token,
12970            int startId) {
12971        synchronized(this) {
12972            return mServices.stopServiceTokenLocked(className, token, startId);
12973        }
12974    }
12975
12976    public void setServiceForeground(ComponentName className, IBinder token,
12977            int id, Notification notification, boolean removeNotification) {
12978        synchronized(this) {
12979            mServices.setServiceForegroundLocked(className, token, id, notification,
12980                    removeNotification);
12981        }
12982    }
12983
12984    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
12985            boolean requireFull, String name, String callerPackage) {
12986        final int callingUserId = UserHandle.getUserId(callingUid);
12987        if (callingUserId != userId) {
12988            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
12989                if ((requireFull || checkComponentPermission(
12990                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12991                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
12992                        && checkComponentPermission(
12993                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
12994                                callingPid, callingUid, -1, true)
12995                                != PackageManager.PERMISSION_GRANTED) {
12996                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
12997                        // In this case, they would like to just execute as their
12998                        // owner user instead of failing.
12999                        userId = callingUserId;
13000                    } else {
13001                        StringBuilder builder = new StringBuilder(128);
13002                        builder.append("Permission Denial: ");
13003                        builder.append(name);
13004                        if (callerPackage != null) {
13005                            builder.append(" from ");
13006                            builder.append(callerPackage);
13007                        }
13008                        builder.append(" asks to run as user ");
13009                        builder.append(userId);
13010                        builder.append(" but is calling from user ");
13011                        builder.append(UserHandle.getUserId(callingUid));
13012                        builder.append("; this requires ");
13013                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
13014                        if (!requireFull) {
13015                            builder.append(" or ");
13016                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
13017                        }
13018                        String msg = builder.toString();
13019                        Slog.w(TAG, msg);
13020                        throw new SecurityException(msg);
13021                    }
13022                }
13023            }
13024            if (userId == UserHandle.USER_CURRENT
13025                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
13026                // Note that we may be accessing this outside of a lock...
13027                // shouldn't be a big deal, if this is being called outside
13028                // of a locked context there is intrinsically a race with
13029                // the value the caller will receive and someone else changing it.
13030                userId = mCurrentUserId;
13031            }
13032            if (!allowAll && userId < 0) {
13033                throw new IllegalArgumentException(
13034                        "Call does not support special user #" + userId);
13035            }
13036        }
13037        return userId;
13038    }
13039
13040    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13041            String className, int flags) {
13042        boolean result = false;
13043        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13044            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
13045                if (ActivityManager.checkUidPermission(
13046                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13047                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13048                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13049                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13050                            + " requests FLAG_SINGLE_USER, but app does not hold "
13051                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
13052                    Slog.w(TAG, msg);
13053                    throw new SecurityException(msg);
13054                }
13055                result = true;
13056            }
13057        } else if (componentProcessName == aInfo.packageName) {
13058            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13059        } else if ("system".equals(componentProcessName)) {
13060            result = true;
13061        }
13062        if (DEBUG_MU) {
13063            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13064                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13065        }
13066        return result;
13067    }
13068
13069    public int bindService(IApplicationThread caller, IBinder token,
13070            Intent service, String resolvedType,
13071            IServiceConnection connection, int flags, int userId) {
13072        enforceNotIsolatedCaller("bindService");
13073        // Refuse possible leaked file descriptors
13074        if (service != null && service.hasFileDescriptors() == true) {
13075            throw new IllegalArgumentException("File descriptors passed in Intent");
13076        }
13077
13078        synchronized(this) {
13079            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13080                    connection, flags, userId);
13081        }
13082    }
13083
13084    public boolean unbindService(IServiceConnection connection) {
13085        synchronized (this) {
13086            return mServices.unbindServiceLocked(connection);
13087        }
13088    }
13089
13090    public void publishService(IBinder token, Intent intent, IBinder service) {
13091        // Refuse possible leaked file descriptors
13092        if (intent != null && intent.hasFileDescriptors() == true) {
13093            throw new IllegalArgumentException("File descriptors passed in Intent");
13094        }
13095
13096        synchronized(this) {
13097            if (!(token instanceof ServiceRecord)) {
13098                throw new IllegalArgumentException("Invalid service token");
13099            }
13100            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13101        }
13102    }
13103
13104    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13105        // Refuse possible leaked file descriptors
13106        if (intent != null && intent.hasFileDescriptors() == true) {
13107            throw new IllegalArgumentException("File descriptors passed in Intent");
13108        }
13109
13110        synchronized(this) {
13111            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13112        }
13113    }
13114
13115    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13116        synchronized(this) {
13117            if (!(token instanceof ServiceRecord)) {
13118                throw new IllegalArgumentException("Invalid service token");
13119            }
13120            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13121        }
13122    }
13123
13124    // =========================================================
13125    // BACKUP AND RESTORE
13126    // =========================================================
13127
13128    // Cause the target app to be launched if necessary and its backup agent
13129    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13130    // activity manager to announce its creation.
13131    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13132        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13133        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
13134
13135        synchronized(this) {
13136            // !!! TODO: currently no check here that we're already bound
13137            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13138            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13139            synchronized (stats) {
13140                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13141            }
13142
13143            // Backup agent is now in use, its package can't be stopped.
13144            try {
13145                AppGlobals.getPackageManager().setPackageStoppedState(
13146                        app.packageName, false, UserHandle.getUserId(app.uid));
13147            } catch (RemoteException e) {
13148            } catch (IllegalArgumentException e) {
13149                Slog.w(TAG, "Failed trying to unstop package "
13150                        + app.packageName + ": " + e);
13151            }
13152
13153            BackupRecord r = new BackupRecord(ss, app, backupMode);
13154            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13155                    ? new ComponentName(app.packageName, app.backupAgentName)
13156                    : new ComponentName("android", "FullBackupAgent");
13157            // startProcessLocked() returns existing proc's record if it's already running
13158            ProcessRecord proc = startProcessLocked(app.processName, app,
13159                    false, 0, "backup", hostingName, false, false, false);
13160            if (proc == null) {
13161                Slog.e(TAG, "Unable to start backup agent process " + r);
13162                return false;
13163            }
13164
13165            r.app = proc;
13166            mBackupTarget = r;
13167            mBackupAppName = app.packageName;
13168
13169            // Try not to kill the process during backup
13170            updateOomAdjLocked(proc);
13171
13172            // If the process is already attached, schedule the creation of the backup agent now.
13173            // If it is not yet live, this will be done when it attaches to the framework.
13174            if (proc.thread != null) {
13175                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13176                try {
13177                    proc.thread.scheduleCreateBackupAgent(app,
13178                            compatibilityInfoForPackageLocked(app), backupMode);
13179                } catch (RemoteException e) {
13180                    // Will time out on the backup manager side
13181                }
13182            } else {
13183                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13184            }
13185            // Invariants: at this point, the target app process exists and the application
13186            // is either already running or in the process of coming up.  mBackupTarget and
13187            // mBackupAppName describe the app, so that when it binds back to the AM we
13188            // know that it's scheduled for a backup-agent operation.
13189        }
13190
13191        return true;
13192    }
13193
13194    @Override
13195    public void clearPendingBackup() {
13196        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13197        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13198
13199        synchronized (this) {
13200            mBackupTarget = null;
13201            mBackupAppName = null;
13202        }
13203    }
13204
13205    // A backup agent has just come up
13206    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13207        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13208                + " = " + agent);
13209
13210        synchronized(this) {
13211            if (!agentPackageName.equals(mBackupAppName)) {
13212                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13213                return;
13214            }
13215        }
13216
13217        long oldIdent = Binder.clearCallingIdentity();
13218        try {
13219            IBackupManager bm = IBackupManager.Stub.asInterface(
13220                    ServiceManager.getService(Context.BACKUP_SERVICE));
13221            bm.agentConnected(agentPackageName, agent);
13222        } catch (RemoteException e) {
13223            // can't happen; the backup manager service is local
13224        } catch (Exception e) {
13225            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13226            e.printStackTrace();
13227        } finally {
13228            Binder.restoreCallingIdentity(oldIdent);
13229        }
13230    }
13231
13232    // done with this agent
13233    public void unbindBackupAgent(ApplicationInfo appInfo) {
13234        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13235        if (appInfo == null) {
13236            Slog.w(TAG, "unbind backup agent for null app");
13237            return;
13238        }
13239
13240        synchronized(this) {
13241            try {
13242                if (mBackupAppName == null) {
13243                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13244                    return;
13245                }
13246
13247                if (!mBackupAppName.equals(appInfo.packageName)) {
13248                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13249                    return;
13250                }
13251
13252                // Not backing this app up any more; reset its OOM adjustment
13253                final ProcessRecord proc = mBackupTarget.app;
13254                updateOomAdjLocked(proc);
13255
13256                // If the app crashed during backup, 'thread' will be null here
13257                if (proc.thread != null) {
13258                    try {
13259                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13260                                compatibilityInfoForPackageLocked(appInfo));
13261                    } catch (Exception e) {
13262                        Slog.e(TAG, "Exception when unbinding backup agent:");
13263                        e.printStackTrace();
13264                    }
13265                }
13266            } finally {
13267                mBackupTarget = null;
13268                mBackupAppName = null;
13269            }
13270        }
13271    }
13272    // =========================================================
13273    // BROADCASTS
13274    // =========================================================
13275
13276    private final List getStickiesLocked(String action, IntentFilter filter,
13277            List cur, int userId) {
13278        final ContentResolver resolver = mContext.getContentResolver();
13279        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13280        if (stickies == null) {
13281            return cur;
13282        }
13283        final ArrayList<Intent> list = stickies.get(action);
13284        if (list == null) {
13285            return cur;
13286        }
13287        int N = list.size();
13288        for (int i=0; i<N; i++) {
13289            Intent intent = list.get(i);
13290            if (filter.match(resolver, intent, true, TAG) >= 0) {
13291                if (cur == null) {
13292                    cur = new ArrayList<Intent>();
13293                }
13294                cur.add(intent);
13295            }
13296        }
13297        return cur;
13298    }
13299
13300    boolean isPendingBroadcastProcessLocked(int pid) {
13301        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13302                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13303    }
13304
13305    void skipPendingBroadcastLocked(int pid) {
13306            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13307            for (BroadcastQueue queue : mBroadcastQueues) {
13308                queue.skipPendingBroadcastLocked(pid);
13309            }
13310    }
13311
13312    // The app just attached; send any pending broadcasts that it should receive
13313    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13314        boolean didSomething = false;
13315        for (BroadcastQueue queue : mBroadcastQueues) {
13316            didSomething |= queue.sendPendingBroadcastsLocked(app);
13317        }
13318        return didSomething;
13319    }
13320
13321    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13322            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13323        enforceNotIsolatedCaller("registerReceiver");
13324        int callingUid;
13325        int callingPid;
13326        synchronized(this) {
13327            ProcessRecord callerApp = null;
13328            if (caller != null) {
13329                callerApp = getRecordForAppLocked(caller);
13330                if (callerApp == null) {
13331                    throw new SecurityException(
13332                            "Unable to find app for caller " + caller
13333                            + " (pid=" + Binder.getCallingPid()
13334                            + ") when registering receiver " + receiver);
13335                }
13336                if (callerApp.info.uid != Process.SYSTEM_UID &&
13337                        !callerApp.pkgList.containsKey(callerPackage) &&
13338                        !"android".equals(callerPackage)) {
13339                    throw new SecurityException("Given caller package " + callerPackage
13340                            + " is not running in process " + callerApp);
13341                }
13342                callingUid = callerApp.info.uid;
13343                callingPid = callerApp.pid;
13344            } else {
13345                callerPackage = null;
13346                callingUid = Binder.getCallingUid();
13347                callingPid = Binder.getCallingPid();
13348            }
13349
13350            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13351                    true, true, "registerReceiver", callerPackage);
13352
13353            List allSticky = null;
13354
13355            // Look for any matching sticky broadcasts...
13356            Iterator actions = filter.actionsIterator();
13357            if (actions != null) {
13358                while (actions.hasNext()) {
13359                    String action = (String)actions.next();
13360                    allSticky = getStickiesLocked(action, filter, allSticky,
13361                            UserHandle.USER_ALL);
13362                    allSticky = getStickiesLocked(action, filter, allSticky,
13363                            UserHandle.getUserId(callingUid));
13364                }
13365            } else {
13366                allSticky = getStickiesLocked(null, filter, allSticky,
13367                        UserHandle.USER_ALL);
13368                allSticky = getStickiesLocked(null, filter, allSticky,
13369                        UserHandle.getUserId(callingUid));
13370            }
13371
13372            // The first sticky in the list is returned directly back to
13373            // the client.
13374            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13375
13376            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13377                    + ": " + sticky);
13378
13379            if (receiver == null) {
13380                return sticky;
13381            }
13382
13383            ReceiverList rl
13384                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13385            if (rl == null) {
13386                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13387                        userId, receiver);
13388                if (rl.app != null) {
13389                    rl.app.receivers.add(rl);
13390                } else {
13391                    try {
13392                        receiver.asBinder().linkToDeath(rl, 0);
13393                    } catch (RemoteException e) {
13394                        return sticky;
13395                    }
13396                    rl.linkedToDeath = true;
13397                }
13398                mRegisteredReceivers.put(receiver.asBinder(), rl);
13399            } else if (rl.uid != callingUid) {
13400                throw new IllegalArgumentException(
13401                        "Receiver requested to register for uid " + callingUid
13402                        + " was previously registered for uid " + rl.uid);
13403            } else if (rl.pid != callingPid) {
13404                throw new IllegalArgumentException(
13405                        "Receiver requested to register for pid " + callingPid
13406                        + " was previously registered for pid " + rl.pid);
13407            } else if (rl.userId != userId) {
13408                throw new IllegalArgumentException(
13409                        "Receiver requested to register for user " + userId
13410                        + " was previously registered for user " + rl.userId);
13411            }
13412            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13413                    permission, callingUid, userId);
13414            rl.add(bf);
13415            if (!bf.debugCheck()) {
13416                Slog.w(TAG, "==> For Dynamic broadast");
13417            }
13418            mReceiverResolver.addFilter(bf);
13419
13420            // Enqueue broadcasts for all existing stickies that match
13421            // this filter.
13422            if (allSticky != null) {
13423                ArrayList receivers = new ArrayList();
13424                receivers.add(bf);
13425
13426                int N = allSticky.size();
13427                for (int i=0; i<N; i++) {
13428                    Intent intent = (Intent)allSticky.get(i);
13429                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13430                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13431                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13432                            null, null, false, true, true, -1);
13433                    queue.enqueueParallelBroadcastLocked(r);
13434                    queue.scheduleBroadcastsLocked();
13435                }
13436            }
13437
13438            return sticky;
13439        }
13440    }
13441
13442    public void unregisterReceiver(IIntentReceiver receiver) {
13443        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13444
13445        final long origId = Binder.clearCallingIdentity();
13446        try {
13447            boolean doTrim = false;
13448
13449            synchronized(this) {
13450                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13451                if (rl != null) {
13452                    if (rl.curBroadcast != null) {
13453                        BroadcastRecord r = rl.curBroadcast;
13454                        final boolean doNext = finishReceiverLocked(
13455                                receiver.asBinder(), r.resultCode, r.resultData,
13456                                r.resultExtras, r.resultAbort);
13457                        if (doNext) {
13458                            doTrim = true;
13459                            r.queue.processNextBroadcast(false);
13460                        }
13461                    }
13462
13463                    if (rl.app != null) {
13464                        rl.app.receivers.remove(rl);
13465                    }
13466                    removeReceiverLocked(rl);
13467                    if (rl.linkedToDeath) {
13468                        rl.linkedToDeath = false;
13469                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13470                    }
13471                }
13472            }
13473
13474            // If we actually concluded any broadcasts, we might now be able
13475            // to trim the recipients' apps from our working set
13476            if (doTrim) {
13477                trimApplications();
13478                return;
13479            }
13480
13481        } finally {
13482            Binder.restoreCallingIdentity(origId);
13483        }
13484    }
13485
13486    void removeReceiverLocked(ReceiverList rl) {
13487        mRegisteredReceivers.remove(rl.receiver.asBinder());
13488        int N = rl.size();
13489        for (int i=0; i<N; i++) {
13490            mReceiverResolver.removeFilter(rl.get(i));
13491        }
13492    }
13493
13494    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13495        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13496            ProcessRecord r = mLruProcesses.get(i);
13497            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13498                try {
13499                    r.thread.dispatchPackageBroadcast(cmd, packages);
13500                } catch (RemoteException ex) {
13501                }
13502            }
13503        }
13504    }
13505
13506    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13507            int[] users) {
13508        List<ResolveInfo> receivers = null;
13509        try {
13510            HashSet<ComponentName> singleUserReceivers = null;
13511            boolean scannedFirstReceivers = false;
13512            for (int user : users) {
13513                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13514                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13515                if (user != 0 && newReceivers != null) {
13516                    // If this is not the primary user, we need to check for
13517                    // any receivers that should be filtered out.
13518                    for (int i=0; i<newReceivers.size(); i++) {
13519                        ResolveInfo ri = newReceivers.get(i);
13520                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13521                            newReceivers.remove(i);
13522                            i--;
13523                        }
13524                    }
13525                }
13526                if (newReceivers != null && newReceivers.size() == 0) {
13527                    newReceivers = null;
13528                }
13529                if (receivers == null) {
13530                    receivers = newReceivers;
13531                } else if (newReceivers != null) {
13532                    // We need to concatenate the additional receivers
13533                    // found with what we have do far.  This would be easy,
13534                    // but we also need to de-dup any receivers that are
13535                    // singleUser.
13536                    if (!scannedFirstReceivers) {
13537                        // Collect any single user receivers we had already retrieved.
13538                        scannedFirstReceivers = true;
13539                        for (int i=0; i<receivers.size(); i++) {
13540                            ResolveInfo ri = receivers.get(i);
13541                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13542                                ComponentName cn = new ComponentName(
13543                                        ri.activityInfo.packageName, ri.activityInfo.name);
13544                                if (singleUserReceivers == null) {
13545                                    singleUserReceivers = new HashSet<ComponentName>();
13546                                }
13547                                singleUserReceivers.add(cn);
13548                            }
13549                        }
13550                    }
13551                    // Add the new results to the existing results, tracking
13552                    // and de-dupping single user receivers.
13553                    for (int i=0; i<newReceivers.size(); i++) {
13554                        ResolveInfo ri = newReceivers.get(i);
13555                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13556                            ComponentName cn = new ComponentName(
13557                                    ri.activityInfo.packageName, ri.activityInfo.name);
13558                            if (singleUserReceivers == null) {
13559                                singleUserReceivers = new HashSet<ComponentName>();
13560                            }
13561                            if (!singleUserReceivers.contains(cn)) {
13562                                singleUserReceivers.add(cn);
13563                                receivers.add(ri);
13564                            }
13565                        } else {
13566                            receivers.add(ri);
13567                        }
13568                    }
13569                }
13570            }
13571        } catch (RemoteException ex) {
13572            // pm is in same process, this will never happen.
13573        }
13574        return receivers;
13575    }
13576
13577    private final int broadcastIntentLocked(ProcessRecord callerApp,
13578            String callerPackage, Intent intent, String resolvedType,
13579            IIntentReceiver resultTo, int resultCode, String resultData,
13580            Bundle map, String requiredPermission, int appOp,
13581            boolean ordered, boolean sticky, int callingPid, int callingUid,
13582            int userId) {
13583        intent = new Intent(intent);
13584
13585        // By default broadcasts do not go to stopped apps.
13586        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13587
13588        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13589            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13590            + " ordered=" + ordered + " userid=" + userId);
13591        if ((resultTo != null) && !ordered) {
13592            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13593        }
13594
13595        userId = handleIncomingUser(callingPid, callingUid, userId,
13596                true, false, "broadcast", callerPackage);
13597
13598        // Make sure that the user who is receiving this broadcast is started.
13599        // If not, we will just skip it.
13600        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13601            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13602                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13603                Slog.w(TAG, "Skipping broadcast of " + intent
13604                        + ": user " + userId + " is stopped");
13605                return ActivityManager.BROADCAST_SUCCESS;
13606            }
13607        }
13608
13609        /*
13610         * Prevent non-system code (defined here to be non-persistent
13611         * processes) from sending protected broadcasts.
13612         */
13613        int callingAppId = UserHandle.getAppId(callingUid);
13614        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13615            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13616            callingUid == 0) {
13617            // Always okay.
13618        } else if (callerApp == null || !callerApp.persistent) {
13619            try {
13620                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13621                        intent.getAction())) {
13622                    String msg = "Permission Denial: not allowed to send broadcast "
13623                            + intent.getAction() + " from pid="
13624                            + callingPid + ", uid=" + callingUid;
13625                    Slog.w(TAG, msg);
13626                    throw new SecurityException(msg);
13627                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13628                    // Special case for compatibility: we don't want apps to send this,
13629                    // but historically it has not been protected and apps may be using it
13630                    // to poke their own app widget.  So, instead of making it protected,
13631                    // just limit it to the caller.
13632                    if (callerApp == null) {
13633                        String msg = "Permission Denial: not allowed to send broadcast "
13634                                + intent.getAction() + " from unknown caller.";
13635                        Slog.w(TAG, msg);
13636                        throw new SecurityException(msg);
13637                    } else if (intent.getComponent() != null) {
13638                        // They are good enough to send to an explicit component...  verify
13639                        // it is being sent to the calling app.
13640                        if (!intent.getComponent().getPackageName().equals(
13641                                callerApp.info.packageName)) {
13642                            String msg = "Permission Denial: not allowed to send broadcast "
13643                                    + intent.getAction() + " to "
13644                                    + intent.getComponent().getPackageName() + " from "
13645                                    + callerApp.info.packageName;
13646                            Slog.w(TAG, msg);
13647                            throw new SecurityException(msg);
13648                        }
13649                    } else {
13650                        // Limit broadcast to their own package.
13651                        intent.setPackage(callerApp.info.packageName);
13652                    }
13653                }
13654            } catch (RemoteException e) {
13655                Slog.w(TAG, "Remote exception", e);
13656                return ActivityManager.BROADCAST_SUCCESS;
13657            }
13658        }
13659
13660        // Handle special intents: if this broadcast is from the package
13661        // manager about a package being removed, we need to remove all of
13662        // its activities from the history stack.
13663        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13664                intent.getAction());
13665        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13666                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13667                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13668                || uidRemoved) {
13669            if (checkComponentPermission(
13670                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13671                    callingPid, callingUid, -1, true)
13672                    == PackageManager.PERMISSION_GRANTED) {
13673                if (uidRemoved) {
13674                    final Bundle intentExtras = intent.getExtras();
13675                    final int uid = intentExtras != null
13676                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13677                    if (uid >= 0) {
13678                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13679                        synchronized (bs) {
13680                            bs.removeUidStatsLocked(uid);
13681                        }
13682                        mAppOpsService.uidRemoved(uid);
13683                    }
13684                } else {
13685                    // If resources are unavailable just force stop all
13686                    // those packages and flush the attribute cache as well.
13687                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13688                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13689                        if (list != null && (list.length > 0)) {
13690                            for (String pkg : list) {
13691                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13692                                        "storage unmount");
13693                            }
13694                            sendPackageBroadcastLocked(
13695                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13696                        }
13697                    } else {
13698                        Uri data = intent.getData();
13699                        String ssp;
13700                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13701                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13702                                    intent.getAction());
13703                            boolean fullUninstall = removed &&
13704                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13705                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13706                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13707                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13708                                        false, fullUninstall, userId,
13709                                        removed ? "pkg removed" : "pkg changed");
13710                            }
13711                            if (removed) {
13712                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13713                                        new String[] {ssp}, userId);
13714                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13715                                    mAppOpsService.packageRemoved(
13716                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13717
13718                                    // Remove all permissions granted from/to this package
13719                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13720                                }
13721                            }
13722                        }
13723                    }
13724                }
13725            } else {
13726                String msg = "Permission Denial: " + intent.getAction()
13727                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13728                        + ", uid=" + callingUid + ")"
13729                        + " requires "
13730                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13731                Slog.w(TAG, msg);
13732                throw new SecurityException(msg);
13733            }
13734
13735        // Special case for adding a package: by default turn on compatibility
13736        // mode.
13737        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13738            Uri data = intent.getData();
13739            String ssp;
13740            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13741                mCompatModePackages.handlePackageAddedLocked(ssp,
13742                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13743            }
13744        }
13745
13746        /*
13747         * If this is the time zone changed action, queue up a message that will reset the timezone
13748         * of all currently running processes. This message will get queued up before the broadcast
13749         * happens.
13750         */
13751        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13752            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13753        }
13754
13755        /*
13756         * If the user set the time, let all running processes know.
13757         */
13758        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
13759            final int is24Hour = intent.getBooleanExtra(
13760                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
13761            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
13762        }
13763
13764        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13765            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13766        }
13767
13768        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13769            ProxyInfo proxy = intent.getParcelableExtra("proxy");
13770            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13771        }
13772
13773        // Add to the sticky list if requested.
13774        if (sticky) {
13775            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13776                    callingPid, callingUid)
13777                    != PackageManager.PERMISSION_GRANTED) {
13778                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13779                        + callingPid + ", uid=" + callingUid
13780                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13781                Slog.w(TAG, msg);
13782                throw new SecurityException(msg);
13783            }
13784            if (requiredPermission != null) {
13785                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13786                        + " and enforce permission " + requiredPermission);
13787                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13788            }
13789            if (intent.getComponent() != null) {
13790                throw new SecurityException(
13791                        "Sticky broadcasts can't target a specific component");
13792            }
13793            // We use userId directly here, since the "all" target is maintained
13794            // as a separate set of sticky broadcasts.
13795            if (userId != UserHandle.USER_ALL) {
13796                // But first, if this is not a broadcast to all users, then
13797                // make sure it doesn't conflict with an existing broadcast to
13798                // all users.
13799                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13800                        UserHandle.USER_ALL);
13801                if (stickies != null) {
13802                    ArrayList<Intent> list = stickies.get(intent.getAction());
13803                    if (list != null) {
13804                        int N = list.size();
13805                        int i;
13806                        for (i=0; i<N; i++) {
13807                            if (intent.filterEquals(list.get(i))) {
13808                                throw new IllegalArgumentException(
13809                                        "Sticky broadcast " + intent + " for user "
13810                                        + userId + " conflicts with existing global broadcast");
13811                            }
13812                        }
13813                    }
13814                }
13815            }
13816            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13817            if (stickies == null) {
13818                stickies = new ArrayMap<String, ArrayList<Intent>>();
13819                mStickyBroadcasts.put(userId, stickies);
13820            }
13821            ArrayList<Intent> list = stickies.get(intent.getAction());
13822            if (list == null) {
13823                list = new ArrayList<Intent>();
13824                stickies.put(intent.getAction(), list);
13825            }
13826            int N = list.size();
13827            int i;
13828            for (i=0; i<N; i++) {
13829                if (intent.filterEquals(list.get(i))) {
13830                    // This sticky already exists, replace it.
13831                    list.set(i, new Intent(intent));
13832                    break;
13833                }
13834            }
13835            if (i >= N) {
13836                list.add(new Intent(intent));
13837            }
13838        }
13839
13840        int[] users;
13841        if (userId == UserHandle.USER_ALL) {
13842            // Caller wants broadcast to go to all started users.
13843            users = mStartedUserArray;
13844        } else {
13845            // Caller wants broadcast to go to one specific user.
13846            users = new int[] {userId};
13847        }
13848
13849        // Figure out who all will receive this broadcast.
13850        List receivers = null;
13851        List<BroadcastFilter> registeredReceivers = null;
13852        // Need to resolve the intent to interested receivers...
13853        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13854                 == 0) {
13855            receivers = collectReceiverComponents(intent, resolvedType, users);
13856        }
13857        if (intent.getComponent() == null) {
13858            registeredReceivers = mReceiverResolver.queryIntent(intent,
13859                    resolvedType, false, userId);
13860        }
13861
13862        final boolean replacePending =
13863                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13864
13865        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13866                + " replacePending=" + replacePending);
13867
13868        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13869        if (!ordered && NR > 0) {
13870            // If we are not serializing this broadcast, then send the
13871            // registered receivers separately so they don't wait for the
13872            // components to be launched.
13873            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13874            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13875                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13876                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13877                    ordered, sticky, false, userId);
13878            if (DEBUG_BROADCAST) Slog.v(
13879                    TAG, "Enqueueing parallel broadcast " + r);
13880            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13881            if (!replaced) {
13882                queue.enqueueParallelBroadcastLocked(r);
13883                queue.scheduleBroadcastsLocked();
13884            }
13885            registeredReceivers = null;
13886            NR = 0;
13887        }
13888
13889        // Merge into one list.
13890        int ir = 0;
13891        if (receivers != null) {
13892            // A special case for PACKAGE_ADDED: do not allow the package
13893            // being added to see this broadcast.  This prevents them from
13894            // using this as a back door to get run as soon as they are
13895            // installed.  Maybe in the future we want to have a special install
13896            // broadcast or such for apps, but we'd like to deliberately make
13897            // this decision.
13898            String skipPackages[] = null;
13899            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13900                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13901                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13902                Uri data = intent.getData();
13903                if (data != null) {
13904                    String pkgName = data.getSchemeSpecificPart();
13905                    if (pkgName != null) {
13906                        skipPackages = new String[] { pkgName };
13907                    }
13908                }
13909            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13910                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13911            }
13912            if (skipPackages != null && (skipPackages.length > 0)) {
13913                for (String skipPackage : skipPackages) {
13914                    if (skipPackage != null) {
13915                        int NT = receivers.size();
13916                        for (int it=0; it<NT; it++) {
13917                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
13918                            if (curt.activityInfo.packageName.equals(skipPackage)) {
13919                                receivers.remove(it);
13920                                it--;
13921                                NT--;
13922                            }
13923                        }
13924                    }
13925                }
13926            }
13927
13928            int NT = receivers != null ? receivers.size() : 0;
13929            int it = 0;
13930            ResolveInfo curt = null;
13931            BroadcastFilter curr = null;
13932            while (it < NT && ir < NR) {
13933                if (curt == null) {
13934                    curt = (ResolveInfo)receivers.get(it);
13935                }
13936                if (curr == null) {
13937                    curr = registeredReceivers.get(ir);
13938                }
13939                if (curr.getPriority() >= curt.priority) {
13940                    // Insert this broadcast record into the final list.
13941                    receivers.add(it, curr);
13942                    ir++;
13943                    curr = null;
13944                    it++;
13945                    NT++;
13946                } else {
13947                    // Skip to the next ResolveInfo in the final list.
13948                    it++;
13949                    curt = null;
13950                }
13951            }
13952        }
13953        while (ir < NR) {
13954            if (receivers == null) {
13955                receivers = new ArrayList();
13956            }
13957            receivers.add(registeredReceivers.get(ir));
13958            ir++;
13959        }
13960
13961        if ((receivers != null && receivers.size() > 0)
13962                || resultTo != null) {
13963            BroadcastQueue queue = broadcastQueueForIntent(intent);
13964            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13965                    callerPackage, callingPid, callingUid, resolvedType,
13966                    requiredPermission, appOp, receivers, resultTo, resultCode,
13967                    resultData, map, ordered, sticky, false, userId);
13968            if (DEBUG_BROADCAST) Slog.v(
13969                    TAG, "Enqueueing ordered broadcast " + r
13970                    + ": prev had " + queue.mOrderedBroadcasts.size());
13971            if (DEBUG_BROADCAST) {
13972                int seq = r.intent.getIntExtra("seq", -1);
13973                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
13974            }
13975            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
13976            if (!replaced) {
13977                queue.enqueueOrderedBroadcastLocked(r);
13978                queue.scheduleBroadcastsLocked();
13979            }
13980        }
13981
13982        return ActivityManager.BROADCAST_SUCCESS;
13983    }
13984
13985    final Intent verifyBroadcastLocked(Intent intent) {
13986        // Refuse possible leaked file descriptors
13987        if (intent != null && intent.hasFileDescriptors() == true) {
13988            throw new IllegalArgumentException("File descriptors passed in Intent");
13989        }
13990
13991        int flags = intent.getFlags();
13992
13993        if (!mProcessesReady) {
13994            // if the caller really truly claims to know what they're doing, go
13995            // ahead and allow the broadcast without launching any receivers
13996            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
13997                intent = new Intent(intent);
13998                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13999            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14000                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14001                        + " before boot completion");
14002                throw new IllegalStateException("Cannot broadcast before boot completed");
14003            }
14004        }
14005
14006        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14007            throw new IllegalArgumentException(
14008                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14009        }
14010
14011        return intent;
14012    }
14013
14014    public final int broadcastIntent(IApplicationThread caller,
14015            Intent intent, String resolvedType, IIntentReceiver resultTo,
14016            int resultCode, String resultData, Bundle map,
14017            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14018        enforceNotIsolatedCaller("broadcastIntent");
14019        synchronized(this) {
14020            intent = verifyBroadcastLocked(intent);
14021
14022            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14023            final int callingPid = Binder.getCallingPid();
14024            final int callingUid = Binder.getCallingUid();
14025            final long origId = Binder.clearCallingIdentity();
14026            int res = broadcastIntentLocked(callerApp,
14027                    callerApp != null ? callerApp.info.packageName : null,
14028                    intent, resolvedType, resultTo,
14029                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14030                    callingPid, callingUid, userId);
14031            Binder.restoreCallingIdentity(origId);
14032            return res;
14033        }
14034    }
14035
14036    int broadcastIntentInPackage(String packageName, int uid,
14037            Intent intent, String resolvedType, IIntentReceiver resultTo,
14038            int resultCode, String resultData, Bundle map,
14039            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14040        synchronized(this) {
14041            intent = verifyBroadcastLocked(intent);
14042
14043            final long origId = Binder.clearCallingIdentity();
14044            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14045                    resultTo, resultCode, resultData, map, requiredPermission,
14046                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14047            Binder.restoreCallingIdentity(origId);
14048            return res;
14049        }
14050    }
14051
14052    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14053        // Refuse possible leaked file descriptors
14054        if (intent != null && intent.hasFileDescriptors() == true) {
14055            throw new IllegalArgumentException("File descriptors passed in Intent");
14056        }
14057
14058        userId = handleIncomingUser(Binder.getCallingPid(),
14059                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
14060
14061        synchronized(this) {
14062            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14063                    != PackageManager.PERMISSION_GRANTED) {
14064                String msg = "Permission Denial: unbroadcastIntent() from pid="
14065                        + Binder.getCallingPid()
14066                        + ", uid=" + Binder.getCallingUid()
14067                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14068                Slog.w(TAG, msg);
14069                throw new SecurityException(msg);
14070            }
14071            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14072            if (stickies != null) {
14073                ArrayList<Intent> list = stickies.get(intent.getAction());
14074                if (list != null) {
14075                    int N = list.size();
14076                    int i;
14077                    for (i=0; i<N; i++) {
14078                        if (intent.filterEquals(list.get(i))) {
14079                            list.remove(i);
14080                            break;
14081                        }
14082                    }
14083                    if (list.size() <= 0) {
14084                        stickies.remove(intent.getAction());
14085                    }
14086                }
14087                if (stickies.size() <= 0) {
14088                    mStickyBroadcasts.remove(userId);
14089                }
14090            }
14091        }
14092    }
14093
14094    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14095            String resultData, Bundle resultExtras, boolean resultAbort) {
14096        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14097        if (r == null) {
14098            Slog.w(TAG, "finishReceiver called but not found on queue");
14099            return false;
14100        }
14101
14102        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14103    }
14104
14105    void backgroundServicesFinishedLocked(int userId) {
14106        for (BroadcastQueue queue : mBroadcastQueues) {
14107            queue.backgroundServicesFinishedLocked(userId);
14108        }
14109    }
14110
14111    public void finishReceiver(IBinder who, int resultCode, String resultData,
14112            Bundle resultExtras, boolean resultAbort) {
14113        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14114
14115        // Refuse possible leaked file descriptors
14116        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14117            throw new IllegalArgumentException("File descriptors passed in Bundle");
14118        }
14119
14120        final long origId = Binder.clearCallingIdentity();
14121        try {
14122            boolean doNext = false;
14123            BroadcastRecord r;
14124
14125            synchronized(this) {
14126                r = broadcastRecordForReceiverLocked(who);
14127                if (r != null) {
14128                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14129                        resultData, resultExtras, resultAbort, true);
14130                }
14131            }
14132
14133            if (doNext) {
14134                r.queue.processNextBroadcast(false);
14135            }
14136            trimApplications();
14137        } finally {
14138            Binder.restoreCallingIdentity(origId);
14139        }
14140    }
14141
14142    // =========================================================
14143    // INSTRUMENTATION
14144    // =========================================================
14145
14146    public boolean startInstrumentation(ComponentName className,
14147            String profileFile, int flags, Bundle arguments,
14148            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14149            int userId) {
14150        enforceNotIsolatedCaller("startInstrumentation");
14151        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14152                userId, false, true, "startInstrumentation", null);
14153        // Refuse possible leaked file descriptors
14154        if (arguments != null && arguments.hasFileDescriptors()) {
14155            throw new IllegalArgumentException("File descriptors passed in Bundle");
14156        }
14157
14158        synchronized(this) {
14159            InstrumentationInfo ii = null;
14160            ApplicationInfo ai = null;
14161            try {
14162                ii = mContext.getPackageManager().getInstrumentationInfo(
14163                    className, STOCK_PM_FLAGS);
14164                ai = AppGlobals.getPackageManager().getApplicationInfo(
14165                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14166            } catch (PackageManager.NameNotFoundException e) {
14167            } catch (RemoteException e) {
14168            }
14169            if (ii == null) {
14170                reportStartInstrumentationFailure(watcher, className,
14171                        "Unable to find instrumentation info for: " + className);
14172                return false;
14173            }
14174            if (ai == null) {
14175                reportStartInstrumentationFailure(watcher, className,
14176                        "Unable to find instrumentation target package: " + ii.targetPackage);
14177                return false;
14178            }
14179
14180            int match = mContext.getPackageManager().checkSignatures(
14181                    ii.targetPackage, ii.packageName);
14182            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14183                String msg = "Permission Denial: starting instrumentation "
14184                        + className + " from pid="
14185                        + Binder.getCallingPid()
14186                        + ", uid=" + Binder.getCallingPid()
14187                        + " not allowed because package " + ii.packageName
14188                        + " does not have a signature matching the target "
14189                        + ii.targetPackage;
14190                reportStartInstrumentationFailure(watcher, className, msg);
14191                throw new SecurityException(msg);
14192            }
14193
14194            final long origId = Binder.clearCallingIdentity();
14195            // Instrumentation can kill and relaunch even persistent processes
14196            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14197                    "start instr");
14198            ProcessRecord app = addAppLocked(ai, false);
14199            app.instrumentationClass = className;
14200            app.instrumentationInfo = ai;
14201            app.instrumentationProfileFile = profileFile;
14202            app.instrumentationArguments = arguments;
14203            app.instrumentationWatcher = watcher;
14204            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14205            app.instrumentationResultClass = className;
14206            Binder.restoreCallingIdentity(origId);
14207        }
14208
14209        return true;
14210    }
14211
14212    /**
14213     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14214     * error to the logs, but if somebody is watching, send the report there too.  This enables
14215     * the "am" command to report errors with more information.
14216     *
14217     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14218     * @param cn The component name of the instrumentation.
14219     * @param report The error report.
14220     */
14221    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14222            ComponentName cn, String report) {
14223        Slog.w(TAG, report);
14224        try {
14225            if (watcher != null) {
14226                Bundle results = new Bundle();
14227                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14228                results.putString("Error", report);
14229                watcher.instrumentationStatus(cn, -1, results);
14230            }
14231        } catch (RemoteException e) {
14232            Slog.w(TAG, e);
14233        }
14234    }
14235
14236    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14237        if (app.instrumentationWatcher != null) {
14238            try {
14239                // NOTE:  IInstrumentationWatcher *must* be oneway here
14240                app.instrumentationWatcher.instrumentationFinished(
14241                    app.instrumentationClass,
14242                    resultCode,
14243                    results);
14244            } catch (RemoteException e) {
14245            }
14246        }
14247        if (app.instrumentationUiAutomationConnection != null) {
14248            try {
14249                app.instrumentationUiAutomationConnection.shutdown();
14250            } catch (RemoteException re) {
14251                /* ignore */
14252            }
14253            // Only a UiAutomation can set this flag and now that
14254            // it is finished we make sure it is reset to its default.
14255            mUserIsMonkey = false;
14256        }
14257        app.instrumentationWatcher = null;
14258        app.instrumentationUiAutomationConnection = null;
14259        app.instrumentationClass = null;
14260        app.instrumentationInfo = null;
14261        app.instrumentationProfileFile = null;
14262        app.instrumentationArguments = null;
14263
14264        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14265                "finished inst");
14266    }
14267
14268    public void finishInstrumentation(IApplicationThread target,
14269            int resultCode, Bundle results) {
14270        int userId = UserHandle.getCallingUserId();
14271        // Refuse possible leaked file descriptors
14272        if (results != null && results.hasFileDescriptors()) {
14273            throw new IllegalArgumentException("File descriptors passed in Intent");
14274        }
14275
14276        synchronized(this) {
14277            ProcessRecord app = getRecordForAppLocked(target);
14278            if (app == null) {
14279                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14280                return;
14281            }
14282            final long origId = Binder.clearCallingIdentity();
14283            finishInstrumentationLocked(app, resultCode, results);
14284            Binder.restoreCallingIdentity(origId);
14285        }
14286    }
14287
14288    // =========================================================
14289    // CONFIGURATION
14290    // =========================================================
14291
14292    public ConfigurationInfo getDeviceConfigurationInfo() {
14293        ConfigurationInfo config = new ConfigurationInfo();
14294        synchronized (this) {
14295            config.reqTouchScreen = mConfiguration.touchscreen;
14296            config.reqKeyboardType = mConfiguration.keyboard;
14297            config.reqNavigation = mConfiguration.navigation;
14298            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14299                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14300                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14301            }
14302            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14303                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14304                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14305            }
14306            config.reqGlEsVersion = GL_ES_VERSION;
14307        }
14308        return config;
14309    }
14310
14311    ActivityStack getFocusedStack() {
14312        return mStackSupervisor.getFocusedStack();
14313    }
14314
14315    public Configuration getConfiguration() {
14316        Configuration ci;
14317        synchronized(this) {
14318            ci = new Configuration(mConfiguration);
14319        }
14320        return ci;
14321    }
14322
14323    public void updatePersistentConfiguration(Configuration values) {
14324        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14325                "updateConfiguration()");
14326        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14327                "updateConfiguration()");
14328        if (values == null) {
14329            throw new NullPointerException("Configuration must not be null");
14330        }
14331
14332        synchronized(this) {
14333            final long origId = Binder.clearCallingIdentity();
14334            updateConfigurationLocked(values, null, true, false);
14335            Binder.restoreCallingIdentity(origId);
14336        }
14337    }
14338
14339    public void updateConfiguration(Configuration values) {
14340        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14341                "updateConfiguration()");
14342
14343        synchronized(this) {
14344            if (values == null && mWindowManager != null) {
14345                // sentinel: fetch the current configuration from the window manager
14346                values = mWindowManager.computeNewConfiguration();
14347            }
14348
14349            if (mWindowManager != null) {
14350                mProcessList.applyDisplaySize(mWindowManager);
14351            }
14352
14353            final long origId = Binder.clearCallingIdentity();
14354            if (values != null) {
14355                Settings.System.clearConfiguration(values);
14356            }
14357            updateConfigurationLocked(values, null, false, false);
14358            Binder.restoreCallingIdentity(origId);
14359        }
14360    }
14361
14362    /**
14363     * Do either or both things: (1) change the current configuration, and (2)
14364     * make sure the given activity is running with the (now) current
14365     * configuration.  Returns true if the activity has been left running, or
14366     * false if <var>starting</var> is being destroyed to match the new
14367     * configuration.
14368     * @param persistent TODO
14369     */
14370    boolean updateConfigurationLocked(Configuration values,
14371            ActivityRecord starting, boolean persistent, boolean initLocale) {
14372        int changes = 0;
14373
14374        if (values != null) {
14375            Configuration newConfig = new Configuration(mConfiguration);
14376            changes = newConfig.updateFrom(values);
14377            if (changes != 0) {
14378                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14379                    Slog.i(TAG, "Updating configuration to: " + values);
14380                }
14381
14382                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14383
14384                if (values.locale != null && !initLocale) {
14385                    saveLocaleLocked(values.locale,
14386                                     !values.locale.equals(mConfiguration.locale),
14387                                     values.userSetLocale);
14388                }
14389
14390                mConfigurationSeq++;
14391                if (mConfigurationSeq <= 0) {
14392                    mConfigurationSeq = 1;
14393                }
14394                newConfig.seq = mConfigurationSeq;
14395                mConfiguration = newConfig;
14396                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14397                mUsageStatsService.noteStartConfig(newConfig);
14398
14399                final Configuration configCopy = new Configuration(mConfiguration);
14400
14401                // TODO: If our config changes, should we auto dismiss any currently
14402                // showing dialogs?
14403                mShowDialogs = shouldShowDialogs(newConfig);
14404
14405                AttributeCache ac = AttributeCache.instance();
14406                if (ac != null) {
14407                    ac.updateConfiguration(configCopy);
14408                }
14409
14410                // Make sure all resources in our process are updated
14411                // right now, so that anyone who is going to retrieve
14412                // resource values after we return will be sure to get
14413                // the new ones.  This is especially important during
14414                // boot, where the first config change needs to guarantee
14415                // all resources have that config before following boot
14416                // code is executed.
14417                mSystemThread.applyConfigurationToResources(configCopy);
14418
14419                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14420                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14421                    msg.obj = new Configuration(configCopy);
14422                    mHandler.sendMessage(msg);
14423                }
14424
14425                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14426                    ProcessRecord app = mLruProcesses.get(i);
14427                    try {
14428                        if (app.thread != null) {
14429                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14430                                    + app.processName + " new config " + mConfiguration);
14431                            app.thread.scheduleConfigurationChanged(configCopy);
14432                        }
14433                    } catch (Exception e) {
14434                    }
14435                }
14436                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14437                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14438                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14439                        | Intent.FLAG_RECEIVER_FOREGROUND);
14440                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14441                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14442                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14443                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14444                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14445                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14446                    broadcastIntentLocked(null, null, intent,
14447                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14448                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14449                }
14450            }
14451        }
14452
14453        boolean kept = true;
14454        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14455        // mainStack is null during startup.
14456        if (mainStack != null) {
14457            if (changes != 0 && starting == null) {
14458                // If the configuration changed, and the caller is not already
14459                // in the process of starting an activity, then find the top
14460                // activity to check if its configuration needs to change.
14461                starting = mainStack.topRunningActivityLocked(null);
14462            }
14463
14464            if (starting != null) {
14465                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14466                // And we need to make sure at this point that all other activities
14467                // are made visible with the correct configuration.
14468                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14469            }
14470        }
14471
14472        if (values != null && mWindowManager != null) {
14473            mWindowManager.setNewConfiguration(mConfiguration);
14474        }
14475
14476        return kept;
14477    }
14478
14479    /**
14480     * Decide based on the configuration whether we should shouw the ANR,
14481     * crash, etc dialogs.  The idea is that if there is no affordnace to
14482     * press the on-screen buttons, we shouldn't show the dialog.
14483     *
14484     * A thought: SystemUI might also want to get told about this, the Power
14485     * dialog / global actions also might want different behaviors.
14486     */
14487    private static final boolean shouldShowDialogs(Configuration config) {
14488        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14489                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14490    }
14491
14492    /**
14493     * Save the locale.  You must be inside a synchronized (this) block.
14494     */
14495    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14496        if(isDiff) {
14497            SystemProperties.set("user.language", l.getLanguage());
14498            SystemProperties.set("user.region", l.getCountry());
14499        }
14500
14501        if(isPersist) {
14502            SystemProperties.set("persist.sys.language", l.getLanguage());
14503            SystemProperties.set("persist.sys.country", l.getCountry());
14504            SystemProperties.set("persist.sys.localevar", l.getVariant());
14505        }
14506    }
14507
14508    @Override
14509    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14510        ActivityRecord srec = ActivityRecord.forToken(token);
14511        return srec != null && srec.task.affinity != null &&
14512                srec.task.affinity.equals(destAffinity);
14513    }
14514
14515    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14516            Intent resultData) {
14517
14518        synchronized (this) {
14519            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14520            if (stack != null) {
14521                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14522            }
14523            return false;
14524        }
14525    }
14526
14527    public int getLaunchedFromUid(IBinder activityToken) {
14528        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14529        if (srec == null) {
14530            return -1;
14531        }
14532        return srec.launchedFromUid;
14533    }
14534
14535    public String getLaunchedFromPackage(IBinder activityToken) {
14536        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14537        if (srec == null) {
14538            return null;
14539        }
14540        return srec.launchedFromPackage;
14541    }
14542
14543    // =========================================================
14544    // LIFETIME MANAGEMENT
14545    // =========================================================
14546
14547    // Returns which broadcast queue the app is the current [or imminent] receiver
14548    // on, or 'null' if the app is not an active broadcast recipient.
14549    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14550        BroadcastRecord r = app.curReceiver;
14551        if (r != null) {
14552            return r.queue;
14553        }
14554
14555        // It's not the current receiver, but it might be starting up to become one
14556        synchronized (this) {
14557            for (BroadcastQueue queue : mBroadcastQueues) {
14558                r = queue.mPendingBroadcast;
14559                if (r != null && r.curApp == app) {
14560                    // found it; report which queue it's in
14561                    return queue;
14562                }
14563            }
14564        }
14565
14566        return null;
14567    }
14568
14569    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14570            boolean doingAll, long now) {
14571        if (mAdjSeq == app.adjSeq) {
14572            // This adjustment has already been computed.
14573            return app.curRawAdj;
14574        }
14575
14576        if (app.thread == null) {
14577            app.adjSeq = mAdjSeq;
14578            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14579            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14580            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14581        }
14582
14583        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14584        app.adjSource = null;
14585        app.adjTarget = null;
14586        app.empty = false;
14587        app.cached = false;
14588
14589        final int activitiesSize = app.activities.size();
14590
14591        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14592            // The max adjustment doesn't allow this app to be anything
14593            // below foreground, so it is not worth doing work for it.
14594            app.adjType = "fixed";
14595            app.adjSeq = mAdjSeq;
14596            app.curRawAdj = app.maxAdj;
14597            app.foregroundActivities = false;
14598            app.keeping = true;
14599            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14600            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14601            // System processes can do UI, and when they do we want to have
14602            // them trim their memory after the user leaves the UI.  To
14603            // facilitate this, here we need to determine whether or not it
14604            // is currently showing UI.
14605            app.systemNoUi = true;
14606            if (app == TOP_APP) {
14607                app.systemNoUi = false;
14608            } else if (activitiesSize > 0) {
14609                for (int j = 0; j < activitiesSize; j++) {
14610                    final ActivityRecord r = app.activities.get(j);
14611                    if (r.visible) {
14612                        app.systemNoUi = false;
14613                    }
14614                }
14615            }
14616            if (!app.systemNoUi) {
14617                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14618            }
14619            return (app.curAdj=app.maxAdj);
14620        }
14621
14622        app.keeping = false;
14623        app.systemNoUi = false;
14624
14625        // Determine the importance of the process, starting with most
14626        // important to least, and assign an appropriate OOM adjustment.
14627        int adj;
14628        int schedGroup;
14629        int procState;
14630        boolean foregroundActivities = false;
14631        boolean interesting = false;
14632        BroadcastQueue queue;
14633        if (app == TOP_APP) {
14634            // The last app on the list is the foreground app.
14635            adj = ProcessList.FOREGROUND_APP_ADJ;
14636            schedGroup = Process.THREAD_GROUP_DEFAULT;
14637            app.adjType = "top-activity";
14638            foregroundActivities = true;
14639            interesting = true;
14640            procState = ActivityManager.PROCESS_STATE_TOP;
14641        } else if (app.instrumentationClass != null) {
14642            // Don't want to kill running instrumentation.
14643            adj = ProcessList.FOREGROUND_APP_ADJ;
14644            schedGroup = Process.THREAD_GROUP_DEFAULT;
14645            app.adjType = "instrumentation";
14646            interesting = true;
14647            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14648        } else if ((queue = isReceivingBroadcast(app)) != null) {
14649            // An app that is currently receiving a broadcast also
14650            // counts as being in the foreground for OOM killer purposes.
14651            // It's placed in a sched group based on the nature of the
14652            // broadcast as reflected by which queue it's active in.
14653            adj = ProcessList.FOREGROUND_APP_ADJ;
14654            schedGroup = (queue == mFgBroadcastQueue)
14655                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14656            app.adjType = "broadcast";
14657            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14658        } else if (app.executingServices.size() > 0) {
14659            // An app that is currently executing a service callback also
14660            // counts as being in the foreground.
14661            adj = ProcessList.FOREGROUND_APP_ADJ;
14662            schedGroup = app.execServicesFg ?
14663                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14664            app.adjType = "exec-service";
14665            procState = ActivityManager.PROCESS_STATE_SERVICE;
14666            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14667        } else {
14668            // As far as we know the process is empty.  We may change our mind later.
14669            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14670            // At this point we don't actually know the adjustment.  Use the cached adj
14671            // value that the caller wants us to.
14672            adj = cachedAdj;
14673            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14674            app.cached = true;
14675            app.empty = true;
14676            app.adjType = "cch-empty";
14677        }
14678
14679        // Examine all activities if not already foreground.
14680        if (!foregroundActivities && activitiesSize > 0) {
14681            for (int j = 0; j < activitiesSize; j++) {
14682                final ActivityRecord r = app.activities.get(j);
14683                if (r.app != app) {
14684                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14685                            + app + "?!?");
14686                    continue;
14687                }
14688                if (r.visible) {
14689                    // App has a visible activity; only upgrade adjustment.
14690                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14691                        adj = ProcessList.VISIBLE_APP_ADJ;
14692                        app.adjType = "visible";
14693                    }
14694                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14695                        procState = ActivityManager.PROCESS_STATE_TOP;
14696                    }
14697                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14698                    app.cached = false;
14699                    app.empty = false;
14700                    foregroundActivities = true;
14701                    break;
14702                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14703                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14704                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14705                        app.adjType = "pausing";
14706                    }
14707                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14708                        procState = ActivityManager.PROCESS_STATE_TOP;
14709                    }
14710                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14711                    app.cached = false;
14712                    app.empty = false;
14713                    foregroundActivities = true;
14714                } else if (r.state == ActivityState.STOPPING) {
14715                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14716                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14717                        app.adjType = "stopping";
14718                    }
14719                    // For the process state, we will at this point consider the
14720                    // process to be cached.  It will be cached either as an activity
14721                    // or empty depending on whether the activity is finishing.  We do
14722                    // this so that we can treat the process as cached for purposes of
14723                    // memory trimming (determing current memory level, trim command to
14724                    // send to process) since there can be an arbitrary number of stopping
14725                    // processes and they should soon all go into the cached state.
14726                    if (!r.finishing) {
14727                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14728                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14729                        }
14730                    }
14731                    app.cached = false;
14732                    app.empty = false;
14733                    foregroundActivities = true;
14734                } else {
14735                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14736                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14737                        app.adjType = "cch-act";
14738                    }
14739                }
14740            }
14741        }
14742
14743        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14744            if (app.foregroundServices) {
14745                // The user is aware of this app, so make it visible.
14746                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14747                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14748                app.cached = false;
14749                app.adjType = "fg-service";
14750                schedGroup = Process.THREAD_GROUP_DEFAULT;
14751            } else if (app.forcingToForeground != null) {
14752                // The user is aware of this app, so make it visible.
14753                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14754                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14755                app.cached = false;
14756                app.adjType = "force-fg";
14757                app.adjSource = app.forcingToForeground;
14758                schedGroup = Process.THREAD_GROUP_DEFAULT;
14759            }
14760        }
14761
14762        if (app.foregroundServices) {
14763            interesting = true;
14764        }
14765
14766        if (app == mHeavyWeightProcess) {
14767            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14768                // We don't want to kill the current heavy-weight process.
14769                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14770                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14771                app.cached = false;
14772                app.adjType = "heavy";
14773            }
14774            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14775                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14776            }
14777        }
14778
14779        if (app == mHomeProcess) {
14780            if (adj > ProcessList.HOME_APP_ADJ) {
14781                // This process is hosting what we currently consider to be the
14782                // home app, so we don't want to let it go into the background.
14783                adj = ProcessList.HOME_APP_ADJ;
14784                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14785                app.cached = false;
14786                app.adjType = "home";
14787            }
14788            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14789                procState = ActivityManager.PROCESS_STATE_HOME;
14790            }
14791        }
14792
14793        if (app == mPreviousProcess && app.activities.size() > 0) {
14794            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14795                // This was the previous process that showed UI to the user.
14796                // We want to try to keep it around more aggressively, to give
14797                // a good experience around switching between two apps.
14798                adj = ProcessList.PREVIOUS_APP_ADJ;
14799                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14800                app.cached = false;
14801                app.adjType = "previous";
14802            }
14803            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14804                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14805            }
14806        }
14807
14808        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14809                + " reason=" + app.adjType);
14810
14811        // By default, we use the computed adjustment.  It may be changed if
14812        // there are applications dependent on our services or providers, but
14813        // this gives us a baseline and makes sure we don't get into an
14814        // infinite recursion.
14815        app.adjSeq = mAdjSeq;
14816        app.curRawAdj = adj;
14817        app.hasStartedServices = false;
14818
14819        if (mBackupTarget != null && app == mBackupTarget.app) {
14820            // If possible we want to avoid killing apps while they're being backed up
14821            if (adj > ProcessList.BACKUP_APP_ADJ) {
14822                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14823                adj = ProcessList.BACKUP_APP_ADJ;
14824                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14825                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14826                }
14827                app.adjType = "backup";
14828                app.cached = false;
14829            }
14830            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14831                procState = ActivityManager.PROCESS_STATE_BACKUP;
14832            }
14833        }
14834
14835        boolean mayBeTop = false;
14836
14837        for (int is = app.services.size()-1;
14838                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14839                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14840                        || procState > ActivityManager.PROCESS_STATE_TOP);
14841                is--) {
14842            ServiceRecord s = app.services.valueAt(is);
14843            if (s.startRequested) {
14844                app.hasStartedServices = true;
14845                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14846                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14847                }
14848                if (app.hasShownUi && app != mHomeProcess) {
14849                    // If this process has shown some UI, let it immediately
14850                    // go to the LRU list because it may be pretty heavy with
14851                    // UI stuff.  We'll tag it with a label just to help
14852                    // debug and understand what is going on.
14853                    if (adj > ProcessList.SERVICE_ADJ) {
14854                        app.adjType = "cch-started-ui-services";
14855                    }
14856                } else {
14857                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14858                        // This service has seen some activity within
14859                        // recent memory, so we will keep its process ahead
14860                        // of the background processes.
14861                        if (adj > ProcessList.SERVICE_ADJ) {
14862                            adj = ProcessList.SERVICE_ADJ;
14863                            app.adjType = "started-services";
14864                            app.cached = false;
14865                        }
14866                    }
14867                    // If we have let the service slide into the background
14868                    // state, still have some text describing what it is doing
14869                    // even though the service no longer has an impact.
14870                    if (adj > ProcessList.SERVICE_ADJ) {
14871                        app.adjType = "cch-started-services";
14872                    }
14873                }
14874                // Don't kill this process because it is doing work; it
14875                // has said it is doing work.
14876                app.keeping = true;
14877            }
14878            for (int conni = s.connections.size()-1;
14879                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14880                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14881                            || procState > ActivityManager.PROCESS_STATE_TOP);
14882                    conni--) {
14883                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14884                for (int i = 0;
14885                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14886                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14887                                || procState > ActivityManager.PROCESS_STATE_TOP);
14888                        i++) {
14889                    // XXX should compute this based on the max of
14890                    // all connected clients.
14891                    ConnectionRecord cr = clist.get(i);
14892                    if (cr.binding.client == app) {
14893                        // Binding to ourself is not interesting.
14894                        continue;
14895                    }
14896                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14897                        ProcessRecord client = cr.binding.client;
14898                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14899                                TOP_APP, doingAll, now);
14900                        int clientProcState = client.curProcState;
14901                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14902                            // If the other app is cached for any reason, for purposes here
14903                            // we are going to consider it empty.  The specific cached state
14904                            // doesn't propagate except under certain conditions.
14905                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14906                        }
14907                        String adjType = null;
14908                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14909                            // Not doing bind OOM management, so treat
14910                            // this guy more like a started service.
14911                            if (app.hasShownUi && app != mHomeProcess) {
14912                                // If this process has shown some UI, let it immediately
14913                                // go to the LRU list because it may be pretty heavy with
14914                                // UI stuff.  We'll tag it with a label just to help
14915                                // debug and understand what is going on.
14916                                if (adj > clientAdj) {
14917                                    adjType = "cch-bound-ui-services";
14918                                }
14919                                app.cached = false;
14920                                clientAdj = adj;
14921                                clientProcState = procState;
14922                            } else {
14923                                if (now >= (s.lastActivity
14924                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14925                                    // This service has not seen activity within
14926                                    // recent memory, so allow it to drop to the
14927                                    // LRU list if there is no other reason to keep
14928                                    // it around.  We'll also tag it with a label just
14929                                    // to help debug and undertand what is going on.
14930                                    if (adj > clientAdj) {
14931                                        adjType = "cch-bound-services";
14932                                    }
14933                                    clientAdj = adj;
14934                                }
14935                            }
14936                        }
14937                        if (adj > clientAdj) {
14938                            // If this process has recently shown UI, and
14939                            // the process that is binding to it is less
14940                            // important than being visible, then we don't
14941                            // care about the binding as much as we care
14942                            // about letting this process get into the LRU
14943                            // list to be killed and restarted if needed for
14944                            // memory.
14945                            if (app.hasShownUi && app != mHomeProcess
14946                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14947                                adjType = "cch-bound-ui-services";
14948                            } else {
14949                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14950                                        |Context.BIND_IMPORTANT)) != 0) {
14951                                    adj = clientAdj;
14952                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14953                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14954                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14955                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14956                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
14957                                    adj = clientAdj;
14958                                } else {
14959                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14960                                        adj = ProcessList.VISIBLE_APP_ADJ;
14961                                    }
14962                                }
14963                                if (!client.cached) {
14964                                    app.cached = false;
14965                                }
14966                                if (client.keeping) {
14967                                    app.keeping = true;
14968                                }
14969                                adjType = "service";
14970                            }
14971                        }
14972                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14973                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14974                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14975                            }
14976                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14977                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14978                                    // Special handling of clients who are in the top state.
14979                                    // We *may* want to consider this process to be in the
14980                                    // top state as well, but only if there is not another
14981                                    // reason for it to be running.  Being on the top is a
14982                                    // special state, meaning you are specifically running
14983                                    // for the current top app.  If the process is already
14984                                    // running in the background for some other reason, it
14985                                    // is more important to continue considering it to be
14986                                    // in the background state.
14987                                    mayBeTop = true;
14988                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14989                                } else {
14990                                    // Special handling for above-top states (persistent
14991                                    // processes).  These should not bring the current process
14992                                    // into the top state, since they are not on top.  Instead
14993                                    // give them the best state after that.
14994                                    clientProcState =
14995                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14996                                }
14997                            }
14998                        } else {
14999                            if (clientProcState <
15000                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15001                                clientProcState =
15002                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15003                            }
15004                        }
15005                        if (procState > clientProcState) {
15006                            procState = clientProcState;
15007                        }
15008                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15009                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15010                            app.pendingUiClean = true;
15011                        }
15012                        if (adjType != null) {
15013                            app.adjType = adjType;
15014                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15015                                    .REASON_SERVICE_IN_USE;
15016                            app.adjSource = cr.binding.client;
15017                            app.adjSourceOom = clientAdj;
15018                            app.adjTarget = s.name;
15019                        }
15020                    }
15021                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15022                        app.treatLikeActivity = true;
15023                    }
15024                    final ActivityRecord a = cr.activity;
15025                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15026                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15027                                (a.visible || a.state == ActivityState.RESUMED
15028                                 || a.state == ActivityState.PAUSING)) {
15029                            adj = ProcessList.FOREGROUND_APP_ADJ;
15030                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15031                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15032                            }
15033                            app.cached = false;
15034                            app.adjType = "service";
15035                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15036                                    .REASON_SERVICE_IN_USE;
15037                            app.adjSource = a;
15038                            app.adjSourceOom = adj;
15039                            app.adjTarget = s.name;
15040                        }
15041                    }
15042                }
15043            }
15044        }
15045
15046        for (int provi = app.pubProviders.size()-1;
15047                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15048                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15049                        || procState > ActivityManager.PROCESS_STATE_TOP);
15050                provi--) {
15051            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15052            for (int i = cpr.connections.size()-1;
15053                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15054                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15055                            || procState > ActivityManager.PROCESS_STATE_TOP);
15056                    i--) {
15057                ContentProviderConnection conn = cpr.connections.get(i);
15058                ProcessRecord client = conn.client;
15059                if (client == app) {
15060                    // Being our own client is not interesting.
15061                    continue;
15062                }
15063                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15064                int clientProcState = client.curProcState;
15065                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15066                    // If the other app is cached for any reason, for purposes here
15067                    // we are going to consider it empty.
15068                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15069                }
15070                if (adj > clientAdj) {
15071                    if (app.hasShownUi && app != mHomeProcess
15072                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15073                        app.adjType = "cch-ui-provider";
15074                    } else {
15075                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15076                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15077                        app.adjType = "provider";
15078                    }
15079                    app.cached &= client.cached;
15080                    app.keeping |= client.keeping;
15081                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15082                            .REASON_PROVIDER_IN_USE;
15083                    app.adjSource = client;
15084                    app.adjSourceOom = clientAdj;
15085                    app.adjTarget = cpr.name;
15086                }
15087                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15088                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15089                        // Special handling of clients who are in the top state.
15090                        // We *may* want to consider this process to be in the
15091                        // top state as well, but only if there is not another
15092                        // reason for it to be running.  Being on the top is a
15093                        // special state, meaning you are specifically running
15094                        // for the current top app.  If the process is already
15095                        // running in the background for some other reason, it
15096                        // is more important to continue considering it to be
15097                        // in the background state.
15098                        mayBeTop = true;
15099                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15100                    } else {
15101                        // Special handling for above-top states (persistent
15102                        // processes).  These should not bring the current process
15103                        // into the top state, since they are not on top.  Instead
15104                        // give them the best state after that.
15105                        clientProcState =
15106                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15107                    }
15108                }
15109                if (procState > clientProcState) {
15110                    procState = clientProcState;
15111                }
15112                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15113                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15114                }
15115            }
15116            // If the provider has external (non-framework) process
15117            // dependencies, ensure that its adjustment is at least
15118            // FOREGROUND_APP_ADJ.
15119            if (cpr.hasExternalProcessHandles()) {
15120                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15121                    adj = ProcessList.FOREGROUND_APP_ADJ;
15122                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15123                    app.cached = false;
15124                    app.keeping = true;
15125                    app.adjType = "provider";
15126                    app.adjTarget = cpr.name;
15127                }
15128                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15129                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15130                }
15131            }
15132        }
15133
15134        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15135            // A client of one of our services or providers is in the top state.  We
15136            // *may* want to be in the top state, but not if we are already running in
15137            // the background for some other reason.  For the decision here, we are going
15138            // to pick out a few specific states that we want to remain in when a client
15139            // is top (states that tend to be longer-term) and otherwise allow it to go
15140            // to the top state.
15141            switch (procState) {
15142                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15143                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15144                case ActivityManager.PROCESS_STATE_SERVICE:
15145                    // These all are longer-term states, so pull them up to the top
15146                    // of the background states, but not all the way to the top state.
15147                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15148                    break;
15149                default:
15150                    // Otherwise, top is a better choice, so take it.
15151                    procState = ActivityManager.PROCESS_STATE_TOP;
15152                    break;
15153            }
15154        }
15155
15156        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15157            if (app.hasClientActivities) {
15158                // This is a cached process, but with client activities.  Mark it so.
15159                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15160                app.adjType = "cch-client-act";
15161            } else if (app.treatLikeActivity) {
15162                // This is a cached process, but somebody wants us to treat it like it has
15163                // an activity, okay!
15164                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15165                app.adjType = "cch-as-act";
15166            }
15167        }
15168
15169        if (adj == ProcessList.SERVICE_ADJ) {
15170            if (doingAll) {
15171                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15172                mNewNumServiceProcs++;
15173                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15174                if (!app.serviceb) {
15175                    // This service isn't far enough down on the LRU list to
15176                    // normally be a B service, but if we are low on RAM and it
15177                    // is large we want to force it down since we would prefer to
15178                    // keep launcher over it.
15179                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15180                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15181                        app.serviceHighRam = true;
15182                        app.serviceb = true;
15183                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15184                    } else {
15185                        mNewNumAServiceProcs++;
15186                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15187                    }
15188                } else {
15189                    app.serviceHighRam = false;
15190                }
15191            }
15192            if (app.serviceb) {
15193                adj = ProcessList.SERVICE_B_ADJ;
15194            }
15195        }
15196
15197        app.curRawAdj = adj;
15198
15199        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15200        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15201        if (adj > app.maxAdj) {
15202            adj = app.maxAdj;
15203            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15204                schedGroup = Process.THREAD_GROUP_DEFAULT;
15205            }
15206        }
15207        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15208            app.keeping = true;
15209        }
15210
15211        // Do final modification to adj.  Everything we do between here and applying
15212        // the final setAdj must be done in this function, because we will also use
15213        // it when computing the final cached adj later.  Note that we don't need to
15214        // worry about this for max adj above, since max adj will always be used to
15215        // keep it out of the cached vaues.
15216        app.curAdj = app.modifyRawOomAdj(adj);
15217        app.curSchedGroup = schedGroup;
15218        app.curProcState = procState;
15219        app.foregroundActivities = foregroundActivities;
15220
15221        return app.curRawAdj;
15222    }
15223
15224    /**
15225     * Schedule PSS collection of a process.
15226     */
15227    void requestPssLocked(ProcessRecord proc, int procState) {
15228        if (mPendingPssProcesses.contains(proc)) {
15229            return;
15230        }
15231        if (mPendingPssProcesses.size() == 0) {
15232            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15233        }
15234        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15235        proc.pssProcState = procState;
15236        mPendingPssProcesses.add(proc);
15237    }
15238
15239    /**
15240     * Schedule PSS collection of all processes.
15241     */
15242    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15243        if (!always) {
15244            if (now < (mLastFullPssTime +
15245                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15246                return;
15247            }
15248        }
15249        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15250        mLastFullPssTime = now;
15251        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15252        mPendingPssProcesses.clear();
15253        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15254            ProcessRecord app = mLruProcesses.get(i);
15255            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15256                app.pssProcState = app.setProcState;
15257                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15258                        isSleeping(), now);
15259                mPendingPssProcesses.add(app);
15260            }
15261        }
15262        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15263    }
15264
15265    /**
15266     * Ask a given process to GC right now.
15267     */
15268    final void performAppGcLocked(ProcessRecord app) {
15269        try {
15270            app.lastRequestedGc = SystemClock.uptimeMillis();
15271            if (app.thread != null) {
15272                if (app.reportLowMemory) {
15273                    app.reportLowMemory = false;
15274                    app.thread.scheduleLowMemory();
15275                } else {
15276                    app.thread.processInBackground();
15277                }
15278            }
15279        } catch (Exception e) {
15280            // whatever.
15281        }
15282    }
15283
15284    /**
15285     * Returns true if things are idle enough to perform GCs.
15286     */
15287    private final boolean canGcNowLocked() {
15288        boolean processingBroadcasts = false;
15289        for (BroadcastQueue q : mBroadcastQueues) {
15290            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15291                processingBroadcasts = true;
15292            }
15293        }
15294        return !processingBroadcasts
15295                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15296    }
15297
15298    /**
15299     * Perform GCs on all processes that are waiting for it, but only
15300     * if things are idle.
15301     */
15302    final void performAppGcsLocked() {
15303        final int N = mProcessesToGc.size();
15304        if (N <= 0) {
15305            return;
15306        }
15307        if (canGcNowLocked()) {
15308            while (mProcessesToGc.size() > 0) {
15309                ProcessRecord proc = mProcessesToGc.remove(0);
15310                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15311                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15312                            <= SystemClock.uptimeMillis()) {
15313                        // To avoid spamming the system, we will GC processes one
15314                        // at a time, waiting a few seconds between each.
15315                        performAppGcLocked(proc);
15316                        scheduleAppGcsLocked();
15317                        return;
15318                    } else {
15319                        // It hasn't been long enough since we last GCed this
15320                        // process...  put it in the list to wait for its time.
15321                        addProcessToGcListLocked(proc);
15322                        break;
15323                    }
15324                }
15325            }
15326
15327            scheduleAppGcsLocked();
15328        }
15329    }
15330
15331    /**
15332     * If all looks good, perform GCs on all processes waiting for them.
15333     */
15334    final void performAppGcsIfAppropriateLocked() {
15335        if (canGcNowLocked()) {
15336            performAppGcsLocked();
15337            return;
15338        }
15339        // Still not idle, wait some more.
15340        scheduleAppGcsLocked();
15341    }
15342
15343    /**
15344     * Schedule the execution of all pending app GCs.
15345     */
15346    final void scheduleAppGcsLocked() {
15347        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15348
15349        if (mProcessesToGc.size() > 0) {
15350            // Schedule a GC for the time to the next process.
15351            ProcessRecord proc = mProcessesToGc.get(0);
15352            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15353
15354            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15355            long now = SystemClock.uptimeMillis();
15356            if (when < (now+GC_TIMEOUT)) {
15357                when = now + GC_TIMEOUT;
15358            }
15359            mHandler.sendMessageAtTime(msg, when);
15360        }
15361    }
15362
15363    /**
15364     * Add a process to the array of processes waiting to be GCed.  Keeps the
15365     * list in sorted order by the last GC time.  The process can't already be
15366     * on the list.
15367     */
15368    final void addProcessToGcListLocked(ProcessRecord proc) {
15369        boolean added = false;
15370        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15371            if (mProcessesToGc.get(i).lastRequestedGc <
15372                    proc.lastRequestedGc) {
15373                added = true;
15374                mProcessesToGc.add(i+1, proc);
15375                break;
15376            }
15377        }
15378        if (!added) {
15379            mProcessesToGc.add(0, proc);
15380        }
15381    }
15382
15383    /**
15384     * Set up to ask a process to GC itself.  This will either do it
15385     * immediately, or put it on the list of processes to gc the next
15386     * time things are idle.
15387     */
15388    final void scheduleAppGcLocked(ProcessRecord app) {
15389        long now = SystemClock.uptimeMillis();
15390        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15391            return;
15392        }
15393        if (!mProcessesToGc.contains(app)) {
15394            addProcessToGcListLocked(app);
15395            scheduleAppGcsLocked();
15396        }
15397    }
15398
15399    final void checkExcessivePowerUsageLocked(boolean doKills) {
15400        updateCpuStatsNow();
15401
15402        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15403        boolean doWakeKills = doKills;
15404        boolean doCpuKills = doKills;
15405        if (mLastPowerCheckRealtime == 0) {
15406            doWakeKills = false;
15407        }
15408        if (mLastPowerCheckUptime == 0) {
15409            doCpuKills = false;
15410        }
15411        if (stats.isScreenOn()) {
15412            doWakeKills = false;
15413        }
15414        final long curRealtime = SystemClock.elapsedRealtime();
15415        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15416        final long curUptime = SystemClock.uptimeMillis();
15417        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15418        mLastPowerCheckRealtime = curRealtime;
15419        mLastPowerCheckUptime = curUptime;
15420        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15421            doWakeKills = false;
15422        }
15423        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15424            doCpuKills = false;
15425        }
15426        int i = mLruProcesses.size();
15427        while (i > 0) {
15428            i--;
15429            ProcessRecord app = mLruProcesses.get(i);
15430            if (!app.keeping) {
15431                long wtime;
15432                synchronized (stats) {
15433                    wtime = stats.getProcessWakeTime(app.info.uid,
15434                            app.pid, curRealtime);
15435                }
15436                long wtimeUsed = wtime - app.lastWakeTime;
15437                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15438                if (DEBUG_POWER) {
15439                    StringBuilder sb = new StringBuilder(128);
15440                    sb.append("Wake for ");
15441                    app.toShortString(sb);
15442                    sb.append(": over ");
15443                    TimeUtils.formatDuration(realtimeSince, sb);
15444                    sb.append(" used ");
15445                    TimeUtils.formatDuration(wtimeUsed, sb);
15446                    sb.append(" (");
15447                    sb.append((wtimeUsed*100)/realtimeSince);
15448                    sb.append("%)");
15449                    Slog.i(TAG, sb.toString());
15450                    sb.setLength(0);
15451                    sb.append("CPU for ");
15452                    app.toShortString(sb);
15453                    sb.append(": over ");
15454                    TimeUtils.formatDuration(uptimeSince, sb);
15455                    sb.append(" used ");
15456                    TimeUtils.formatDuration(cputimeUsed, sb);
15457                    sb.append(" (");
15458                    sb.append((cputimeUsed*100)/uptimeSince);
15459                    sb.append("%)");
15460                    Slog.i(TAG, sb.toString());
15461                }
15462                // If a process has held a wake lock for more
15463                // than 50% of the time during this period,
15464                // that sounds bad.  Kill!
15465                if (doWakeKills && realtimeSince > 0
15466                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15467                    synchronized (stats) {
15468                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15469                                realtimeSince, wtimeUsed);
15470                    }
15471                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15472                            + " during " + realtimeSince);
15473                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15474                } else if (doCpuKills && uptimeSince > 0
15475                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15476                    synchronized (stats) {
15477                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15478                                uptimeSince, cputimeUsed);
15479                    }
15480                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15481                            + " during " + uptimeSince);
15482                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15483                } else {
15484                    app.lastWakeTime = wtime;
15485                    app.lastCpuTime = app.curCpuTime;
15486                }
15487            }
15488        }
15489    }
15490
15491    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15492            ProcessRecord TOP_APP, boolean doingAll, long now) {
15493        boolean success = true;
15494
15495        if (app.curRawAdj != app.setRawAdj) {
15496            if (wasKeeping && !app.keeping) {
15497                // This app is no longer something we want to keep.  Note
15498                // its current wake lock time to later know to kill it if
15499                // it is not behaving well.
15500                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15501                synchronized (stats) {
15502                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15503                            app.pid, SystemClock.elapsedRealtime());
15504                }
15505                app.lastCpuTime = app.curCpuTime;
15506            }
15507
15508            app.setRawAdj = app.curRawAdj;
15509        }
15510
15511        int changes = 0;
15512
15513        if (app.curAdj != app.setAdj) {
15514            ProcessList.setOomAdj(app.pid, app.curAdj);
15515            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15516                TAG, "Set " + app.pid + " " + app.processName +
15517                " adj " + app.curAdj + ": " + app.adjType);
15518            app.setAdj = app.curAdj;
15519        }
15520
15521        if (app.setSchedGroup != app.curSchedGroup) {
15522            app.setSchedGroup = app.curSchedGroup;
15523            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15524                    "Setting process group of " + app.processName
15525                    + " to " + app.curSchedGroup);
15526            if (app.waitingToKill != null &&
15527                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15528                killUnneededProcessLocked(app, app.waitingToKill);
15529                success = false;
15530            } else {
15531                if (true) {
15532                    long oldId = Binder.clearCallingIdentity();
15533                    try {
15534                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15535                    } catch (Exception e) {
15536                        Slog.w(TAG, "Failed setting process group of " + app.pid
15537                                + " to " + app.curSchedGroup);
15538                        e.printStackTrace();
15539                    } finally {
15540                        Binder.restoreCallingIdentity(oldId);
15541                    }
15542                } else {
15543                    if (app.thread != null) {
15544                        try {
15545                            app.thread.setSchedulingGroup(app.curSchedGroup);
15546                        } catch (RemoteException e) {
15547                        }
15548                    }
15549                }
15550                Process.setSwappiness(app.pid,
15551                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15552            }
15553        }
15554        if (app.repForegroundActivities != app.foregroundActivities) {
15555            app.repForegroundActivities = app.foregroundActivities;
15556            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15557        }
15558        if (app.repProcState != app.curProcState) {
15559            app.repProcState = app.curProcState;
15560            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
15561            if (app.thread != null) {
15562                try {
15563                    if (false) {
15564                        //RuntimeException h = new RuntimeException("here");
15565                        Slog.i(TAG, "Sending new process state " + app.repProcState
15566                                + " to " + app /*, h*/);
15567                    }
15568                    app.thread.setProcessState(app.repProcState);
15569                } catch (RemoteException e) {
15570                }
15571            }
15572        }
15573        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15574                app.setProcState)) {
15575            app.lastStateTime = now;
15576            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15577                    isSleeping(), now);
15578            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15579                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15580                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15581                    + (app.nextPssTime-now) + ": " + app);
15582        } else {
15583            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15584                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15585                requestPssLocked(app, app.setProcState);
15586                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15587                        isSleeping(), now);
15588            } else if (false && DEBUG_PSS) {
15589                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15590            }
15591        }
15592        if (app.setProcState != app.curProcState) {
15593            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15594                    "Proc state change of " + app.processName
15595                    + " to " + app.curProcState);
15596            app.setProcState = app.curProcState;
15597            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15598                app.notCachedSinceIdle = false;
15599            }
15600            if (!doingAll) {
15601                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15602            } else {
15603                app.procStateChanged = true;
15604            }
15605        }
15606
15607        if (changes != 0) {
15608            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15609            int i = mPendingProcessChanges.size()-1;
15610            ProcessChangeItem item = null;
15611            while (i >= 0) {
15612                item = mPendingProcessChanges.get(i);
15613                if (item.pid == app.pid) {
15614                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15615                    break;
15616                }
15617                i--;
15618            }
15619            if (i < 0) {
15620                // No existing item in pending changes; need a new one.
15621                final int NA = mAvailProcessChanges.size();
15622                if (NA > 0) {
15623                    item = mAvailProcessChanges.remove(NA-1);
15624                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15625                } else {
15626                    item = new ProcessChangeItem();
15627                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15628                }
15629                item.changes = 0;
15630                item.pid = app.pid;
15631                item.uid = app.info.uid;
15632                if (mPendingProcessChanges.size() == 0) {
15633                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15634                            "*** Enqueueing dispatch processes changed!");
15635                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15636                }
15637                mPendingProcessChanges.add(item);
15638            }
15639            item.changes |= changes;
15640            item.processState = app.repProcState;
15641            item.foregroundActivities = app.repForegroundActivities;
15642            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
15643                    + Integer.toHexString(System.identityHashCode(item))
15644                    + " " + app.toShortString() + ": changes=" + item.changes
15645                    + " procState=" + item.processState
15646                    + " foreground=" + item.foregroundActivities
15647                    + " type=" + app.adjType + " source=" + app.adjSource
15648                    + " target=" + app.adjTarget);
15649        }
15650
15651        return success;
15652    }
15653
15654    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15655        if (proc.thread != null && proc.baseProcessTracker != null) {
15656            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15657        }
15658    }
15659
15660    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15661            ProcessRecord TOP_APP, boolean doingAll, long now) {
15662        if (app.thread == null) {
15663            return false;
15664        }
15665
15666        final boolean wasKeeping = app.keeping;
15667
15668        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15669
15670        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now);
15671    }
15672
15673    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15674            boolean oomAdj) {
15675        if (isForeground != proc.foregroundServices) {
15676            proc.foregroundServices = isForeground;
15677            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15678                    proc.info.uid);
15679            if (isForeground) {
15680                if (curProcs == null) {
15681                    curProcs = new ArrayList<ProcessRecord>();
15682                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15683                }
15684                if (!curProcs.contains(proc)) {
15685                    curProcs.add(proc);
15686                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15687                            proc.info.packageName, proc.info.uid);
15688                }
15689            } else {
15690                if (curProcs != null) {
15691                    if (curProcs.remove(proc)) {
15692                        mBatteryStatsService.noteEvent(
15693                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15694                                proc.info.packageName, proc.info.uid);
15695                        if (curProcs.size() <= 0) {
15696                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15697                        }
15698                    }
15699                }
15700            }
15701            if (oomAdj) {
15702                updateOomAdjLocked();
15703            }
15704        }
15705    }
15706
15707    private final ActivityRecord resumedAppLocked() {
15708        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15709        String pkg;
15710        int uid;
15711        if (act != null && !act.sleeping) {
15712            pkg = act.packageName;
15713            uid = act.info.applicationInfo.uid;
15714        } else {
15715            pkg = null;
15716            uid = -1;
15717        }
15718        // Has the UID or resumed package name changed?
15719        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15720                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15721            if (mCurResumedPackage != null) {
15722                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15723                        mCurResumedPackage, mCurResumedUid);
15724            }
15725            mCurResumedPackage = pkg;
15726            mCurResumedUid = uid;
15727            if (mCurResumedPackage != null) {
15728                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15729                        mCurResumedPackage, mCurResumedUid);
15730            }
15731        }
15732        return act;
15733    }
15734
15735    final boolean updateOomAdjLocked(ProcessRecord app) {
15736        final ActivityRecord TOP_ACT = resumedAppLocked();
15737        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15738        final boolean wasCached = app.cached;
15739
15740        mAdjSeq++;
15741
15742        // This is the desired cached adjusment we want to tell it to use.
15743        // If our app is currently cached, we know it, and that is it.  Otherwise,
15744        // we don't know it yet, and it needs to now be cached we will then
15745        // need to do a complete oom adj.
15746        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15747                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15748        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
15749                SystemClock.uptimeMillis());
15750        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15751            // Changed to/from cached state, so apps after it in the LRU
15752            // list may also be changed.
15753            updateOomAdjLocked();
15754        }
15755        return success;
15756    }
15757
15758    final void updateOomAdjLocked() {
15759        final ActivityRecord TOP_ACT = resumedAppLocked();
15760        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15761        final long now = SystemClock.uptimeMillis();
15762        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15763        final int N = mLruProcesses.size();
15764
15765        if (false) {
15766            RuntimeException e = new RuntimeException();
15767            e.fillInStackTrace();
15768            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15769        }
15770
15771        mAdjSeq++;
15772        mNewNumServiceProcs = 0;
15773        mNewNumAServiceProcs = 0;
15774
15775        final int emptyProcessLimit;
15776        final int cachedProcessLimit;
15777        if (mProcessLimit <= 0) {
15778            emptyProcessLimit = cachedProcessLimit = 0;
15779        } else if (mProcessLimit == 1) {
15780            emptyProcessLimit = 1;
15781            cachedProcessLimit = 0;
15782        } else {
15783            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15784            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15785        }
15786
15787        // Let's determine how many processes we have running vs.
15788        // how many slots we have for background processes; we may want
15789        // to put multiple processes in a slot of there are enough of
15790        // them.
15791        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15792                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15793        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15794        if (numEmptyProcs > cachedProcessLimit) {
15795            // If there are more empty processes than our limit on cached
15796            // processes, then use the cached process limit for the factor.
15797            // This ensures that the really old empty processes get pushed
15798            // down to the bottom, so if we are running low on memory we will
15799            // have a better chance at keeping around more cached processes
15800            // instead of a gazillion empty processes.
15801            numEmptyProcs = cachedProcessLimit;
15802        }
15803        int emptyFactor = numEmptyProcs/numSlots;
15804        if (emptyFactor < 1) emptyFactor = 1;
15805        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15806        if (cachedFactor < 1) cachedFactor = 1;
15807        int stepCached = 0;
15808        int stepEmpty = 0;
15809        int numCached = 0;
15810        int numEmpty = 0;
15811        int numTrimming = 0;
15812
15813        mNumNonCachedProcs = 0;
15814        mNumCachedHiddenProcs = 0;
15815
15816        // First update the OOM adjustment for each of the
15817        // application processes based on their current state.
15818        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15819        int nextCachedAdj = curCachedAdj+1;
15820        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15821        int nextEmptyAdj = curEmptyAdj+2;
15822        for (int i=N-1; i>=0; i--) {
15823            ProcessRecord app = mLruProcesses.get(i);
15824            if (!app.killedByAm && app.thread != null) {
15825                app.procStateChanged = false;
15826                final boolean wasKeeping = app.keeping;
15827                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15828
15829                // If we haven't yet assigned the final cached adj
15830                // to the process, do that now.
15831                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15832                    switch (app.curProcState) {
15833                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15834                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15835                            // This process is a cached process holding activities...
15836                            // assign it the next cached value for that type, and then
15837                            // step that cached level.
15838                            app.curRawAdj = curCachedAdj;
15839                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15840                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15841                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15842                                    + ")");
15843                            if (curCachedAdj != nextCachedAdj) {
15844                                stepCached++;
15845                                if (stepCached >= cachedFactor) {
15846                                    stepCached = 0;
15847                                    curCachedAdj = nextCachedAdj;
15848                                    nextCachedAdj += 2;
15849                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15850                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15851                                    }
15852                                }
15853                            }
15854                            break;
15855                        default:
15856                            // For everything else, assign next empty cached process
15857                            // level and bump that up.  Note that this means that
15858                            // long-running services that have dropped down to the
15859                            // cached level will be treated as empty (since their process
15860                            // state is still as a service), which is what we want.
15861                            app.curRawAdj = curEmptyAdj;
15862                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15863                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15864                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15865                                    + ")");
15866                            if (curEmptyAdj != nextEmptyAdj) {
15867                                stepEmpty++;
15868                                if (stepEmpty >= emptyFactor) {
15869                                    stepEmpty = 0;
15870                                    curEmptyAdj = nextEmptyAdj;
15871                                    nextEmptyAdj += 2;
15872                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15873                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15874                                    }
15875                                }
15876                            }
15877                            break;
15878                    }
15879                }
15880
15881                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now);
15882
15883                // Count the number of process types.
15884                switch (app.curProcState) {
15885                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15886                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15887                        mNumCachedHiddenProcs++;
15888                        numCached++;
15889                        if (numCached > cachedProcessLimit) {
15890                            killUnneededProcessLocked(app, "cached #" + numCached);
15891                        }
15892                        break;
15893                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15894                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15895                                && app.lastActivityTime < oldTime) {
15896                            killUnneededProcessLocked(app, "empty for "
15897                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15898                                    / 1000) + "s");
15899                        } else {
15900                            numEmpty++;
15901                            if (numEmpty > emptyProcessLimit) {
15902                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15903                            }
15904                        }
15905                        break;
15906                    default:
15907                        mNumNonCachedProcs++;
15908                        break;
15909                }
15910
15911                if (app.isolated && app.services.size() <= 0) {
15912                    // If this is an isolated process, and there are no
15913                    // services running in it, then the process is no longer
15914                    // needed.  We agressively kill these because we can by
15915                    // definition not re-use the same process again, and it is
15916                    // good to avoid having whatever code was running in them
15917                    // left sitting around after no longer needed.
15918                    killUnneededProcessLocked(app, "isolated not needed");
15919                }
15920
15921                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15922                        && !app.killedByAm) {
15923                    numTrimming++;
15924                }
15925            }
15926        }
15927
15928        mNumServiceProcs = mNewNumServiceProcs;
15929
15930        // Now determine the memory trimming level of background processes.
15931        // Unfortunately we need to start at the back of the list to do this
15932        // properly.  We only do this if the number of background apps we
15933        // are managing to keep around is less than half the maximum we desire;
15934        // if we are keeping a good number around, we'll let them use whatever
15935        // memory they want.
15936        final int numCachedAndEmpty = numCached + numEmpty;
15937        int memFactor;
15938        if (numCached <= ProcessList.TRIM_CACHED_APPS
15939                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
15940            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
15941                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
15942            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
15943                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
15944            } else {
15945                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
15946            }
15947        } else {
15948            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
15949        }
15950        // We always allow the memory level to go up (better).  We only allow it to go
15951        // down if we are in a state where that is allowed, *and* the total number of processes
15952        // has gone down since last time.
15953        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
15954                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
15955                + " last=" + mLastNumProcesses);
15956        if (memFactor > mLastMemoryLevel) {
15957            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
15958                memFactor = mLastMemoryLevel;
15959                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
15960            }
15961        }
15962        mLastMemoryLevel = memFactor;
15963        mLastNumProcesses = mLruProcesses.size();
15964        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
15965        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
15966        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
15967            if (mLowRamStartTime == 0) {
15968                mLowRamStartTime = now;
15969            }
15970            int step = 0;
15971            int fgTrimLevel;
15972            switch (memFactor) {
15973                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15974                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
15975                    break;
15976                case ProcessStats.ADJ_MEM_FACTOR_LOW:
15977                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
15978                    break;
15979                default:
15980                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
15981                    break;
15982            }
15983            int factor = numTrimming/3;
15984            int minFactor = 2;
15985            if (mHomeProcess != null) minFactor++;
15986            if (mPreviousProcess != null) minFactor++;
15987            if (factor < minFactor) factor = minFactor;
15988            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
15989            for (int i=N-1; i>=0; i--) {
15990                ProcessRecord app = mLruProcesses.get(i);
15991                if (allChanged || app.procStateChanged) {
15992                    setProcessTrackerState(app, trackerMemFactor, now);
15993                    app.procStateChanged = false;
15994                }
15995                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15996                        && !app.killedByAm) {
15997                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
15998                        try {
15999                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16000                                    "Trimming memory of " + app.processName
16001                                    + " to " + curLevel);
16002                            app.thread.scheduleTrimMemory(curLevel);
16003                        } catch (RemoteException e) {
16004                        }
16005                        if (false) {
16006                            // For now we won't do this; our memory trimming seems
16007                            // to be good enough at this point that destroying
16008                            // activities causes more harm than good.
16009                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16010                                    && app != mHomeProcess && app != mPreviousProcess) {
16011                                // Need to do this on its own message because the stack may not
16012                                // be in a consistent state at this point.
16013                                // For these apps we will also finish their activities
16014                                // to help them free memory.
16015                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16016                            }
16017                        }
16018                    }
16019                    app.trimMemoryLevel = curLevel;
16020                    step++;
16021                    if (step >= factor) {
16022                        step = 0;
16023                        switch (curLevel) {
16024                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16025                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16026                                break;
16027                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16028                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16029                                break;
16030                        }
16031                    }
16032                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16033                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16034                            && app.thread != null) {
16035                        try {
16036                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16037                                    "Trimming memory of heavy-weight " + app.processName
16038                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16039                            app.thread.scheduleTrimMemory(
16040                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16041                        } catch (RemoteException e) {
16042                        }
16043                    }
16044                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16045                } else {
16046                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16047                            || app.systemNoUi) && app.pendingUiClean) {
16048                        // If this application is now in the background and it
16049                        // had done UI, then give it the special trim level to
16050                        // have it free UI resources.
16051                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16052                        if (app.trimMemoryLevel < level && app.thread != null) {
16053                            try {
16054                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16055                                        "Trimming memory of bg-ui " + app.processName
16056                                        + " to " + level);
16057                                app.thread.scheduleTrimMemory(level);
16058                            } catch (RemoteException e) {
16059                            }
16060                        }
16061                        app.pendingUiClean = false;
16062                    }
16063                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16064                        try {
16065                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16066                                    "Trimming memory of fg " + app.processName
16067                                    + " to " + fgTrimLevel);
16068                            app.thread.scheduleTrimMemory(fgTrimLevel);
16069                        } catch (RemoteException e) {
16070                        }
16071                    }
16072                    app.trimMemoryLevel = fgTrimLevel;
16073                }
16074            }
16075        } else {
16076            if (mLowRamStartTime != 0) {
16077                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16078                mLowRamStartTime = 0;
16079            }
16080            for (int i=N-1; i>=0; i--) {
16081                ProcessRecord app = mLruProcesses.get(i);
16082                if (allChanged || app.procStateChanged) {
16083                    setProcessTrackerState(app, trackerMemFactor, now);
16084                    app.procStateChanged = false;
16085                }
16086                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16087                        || app.systemNoUi) && app.pendingUiClean) {
16088                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16089                            && app.thread != null) {
16090                        try {
16091                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16092                                    "Trimming memory of ui hidden " + app.processName
16093                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16094                            app.thread.scheduleTrimMemory(
16095                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16096                        } catch (RemoteException e) {
16097                        }
16098                    }
16099                    app.pendingUiClean = false;
16100                }
16101                app.trimMemoryLevel = 0;
16102            }
16103        }
16104
16105        if (mAlwaysFinishActivities) {
16106            // Need to do this on its own message because the stack may not
16107            // be in a consistent state at this point.
16108            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16109        }
16110
16111        if (allChanged) {
16112            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16113        }
16114
16115        if (mProcessStats.shouldWriteNowLocked(now)) {
16116            mHandler.post(new Runnable() {
16117                @Override public void run() {
16118                    synchronized (ActivityManagerService.this) {
16119                        mProcessStats.writeStateAsyncLocked();
16120                    }
16121                }
16122            });
16123        }
16124
16125        if (DEBUG_OOM_ADJ) {
16126            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16127        }
16128    }
16129
16130    final void trimApplications() {
16131        synchronized (this) {
16132            int i;
16133
16134            // First remove any unused application processes whose package
16135            // has been removed.
16136            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16137                final ProcessRecord app = mRemovedProcesses.get(i);
16138                if (app.activities.size() == 0
16139                        && app.curReceiver == null && app.services.size() == 0) {
16140                    Slog.i(
16141                        TAG, "Exiting empty application process "
16142                        + app.processName + " ("
16143                        + (app.thread != null ? app.thread.asBinder() : null)
16144                        + ")\n");
16145                    if (app.pid > 0 && app.pid != MY_PID) {
16146                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16147                                app.processName, app.setAdj, "empty");
16148                        app.killedByAm = true;
16149                        Process.killProcessQuiet(app.pid);
16150                    } else {
16151                        try {
16152                            app.thread.scheduleExit();
16153                        } catch (Exception e) {
16154                            // Ignore exceptions.
16155                        }
16156                    }
16157                    cleanUpApplicationRecordLocked(app, false, true, -1);
16158                    mRemovedProcesses.remove(i);
16159
16160                    if (app.persistent) {
16161                        if (app.persistent) {
16162                            addAppLocked(app.info, false);
16163                        }
16164                    }
16165                }
16166            }
16167
16168            // Now update the oom adj for all processes.
16169            updateOomAdjLocked();
16170        }
16171    }
16172
16173    /** This method sends the specified signal to each of the persistent apps */
16174    public void signalPersistentProcesses(int sig) throws RemoteException {
16175        if (sig != Process.SIGNAL_USR1) {
16176            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16177        }
16178
16179        synchronized (this) {
16180            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16181                    != PackageManager.PERMISSION_GRANTED) {
16182                throw new SecurityException("Requires permission "
16183                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16184            }
16185
16186            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16187                ProcessRecord r = mLruProcesses.get(i);
16188                if (r.thread != null && r.persistent) {
16189                    Process.sendSignal(r.pid, sig);
16190                }
16191            }
16192        }
16193    }
16194
16195    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16196        if (proc == null || proc == mProfileProc) {
16197            proc = mProfileProc;
16198            path = mProfileFile;
16199            profileType = mProfileType;
16200            clearProfilerLocked();
16201        }
16202        if (proc == null) {
16203            return;
16204        }
16205        try {
16206            proc.thread.profilerControl(false, path, null, profileType);
16207        } catch (RemoteException e) {
16208            throw new IllegalStateException("Process disappeared");
16209        }
16210    }
16211
16212    private void clearProfilerLocked() {
16213        if (mProfileFd != null) {
16214            try {
16215                mProfileFd.close();
16216            } catch (IOException e) {
16217            }
16218        }
16219        mProfileApp = null;
16220        mProfileProc = null;
16221        mProfileFile = null;
16222        mProfileType = 0;
16223        mAutoStopProfiler = false;
16224    }
16225
16226    public boolean profileControl(String process, int userId, boolean start,
16227            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16228
16229        try {
16230            synchronized (this) {
16231                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16232                // its own permission.
16233                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16234                        != PackageManager.PERMISSION_GRANTED) {
16235                    throw new SecurityException("Requires permission "
16236                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16237                }
16238
16239                if (start && fd == null) {
16240                    throw new IllegalArgumentException("null fd");
16241                }
16242
16243                ProcessRecord proc = null;
16244                if (process != null) {
16245                    proc = findProcessLocked(process, userId, "profileControl");
16246                }
16247
16248                if (start && (proc == null || proc.thread == null)) {
16249                    throw new IllegalArgumentException("Unknown process: " + process);
16250                }
16251
16252                if (start) {
16253                    stopProfilerLocked(null, null, 0);
16254                    setProfileApp(proc.info, proc.processName, path, fd, false);
16255                    mProfileProc = proc;
16256                    mProfileType = profileType;
16257                    try {
16258                        fd = fd.dup();
16259                    } catch (IOException e) {
16260                        fd = null;
16261                    }
16262                    proc.thread.profilerControl(start, path, fd, profileType);
16263                    fd = null;
16264                    mProfileFd = null;
16265                } else {
16266                    stopProfilerLocked(proc, path, profileType);
16267                    if (fd != null) {
16268                        try {
16269                            fd.close();
16270                        } catch (IOException e) {
16271                        }
16272                    }
16273                }
16274
16275                return true;
16276            }
16277        } catch (RemoteException e) {
16278            throw new IllegalStateException("Process disappeared");
16279        } finally {
16280            if (fd != null) {
16281                try {
16282                    fd.close();
16283                } catch (IOException e) {
16284                }
16285            }
16286        }
16287    }
16288
16289    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16290        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16291                userId, true, true, callName, null);
16292        ProcessRecord proc = null;
16293        try {
16294            int pid = Integer.parseInt(process);
16295            synchronized (mPidsSelfLocked) {
16296                proc = mPidsSelfLocked.get(pid);
16297            }
16298        } catch (NumberFormatException e) {
16299        }
16300
16301        if (proc == null) {
16302            ArrayMap<String, SparseArray<ProcessRecord>> all
16303                    = mProcessNames.getMap();
16304            SparseArray<ProcessRecord> procs = all.get(process);
16305            if (procs != null && procs.size() > 0) {
16306                proc = procs.valueAt(0);
16307                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16308                    for (int i=1; i<procs.size(); i++) {
16309                        ProcessRecord thisProc = procs.valueAt(i);
16310                        if (thisProc.userId == userId) {
16311                            proc = thisProc;
16312                            break;
16313                        }
16314                    }
16315                }
16316            }
16317        }
16318
16319        return proc;
16320    }
16321
16322    public boolean dumpHeap(String process, int userId, boolean managed,
16323            String path, ParcelFileDescriptor fd) throws RemoteException {
16324
16325        try {
16326            synchronized (this) {
16327                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16328                // its own permission (same as profileControl).
16329                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16330                        != PackageManager.PERMISSION_GRANTED) {
16331                    throw new SecurityException("Requires permission "
16332                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16333                }
16334
16335                if (fd == null) {
16336                    throw new IllegalArgumentException("null fd");
16337                }
16338
16339                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16340                if (proc == null || proc.thread == null) {
16341                    throw new IllegalArgumentException("Unknown process: " + process);
16342                }
16343
16344                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16345                if (!isDebuggable) {
16346                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16347                        throw new SecurityException("Process not debuggable: " + proc);
16348                    }
16349                }
16350
16351                proc.thread.dumpHeap(managed, path, fd);
16352                fd = null;
16353                return true;
16354            }
16355        } catch (RemoteException e) {
16356            throw new IllegalStateException("Process disappeared");
16357        } finally {
16358            if (fd != null) {
16359                try {
16360                    fd.close();
16361                } catch (IOException e) {
16362                }
16363            }
16364        }
16365    }
16366
16367    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16368    public void monitor() {
16369        synchronized (this) { }
16370    }
16371
16372    void onCoreSettingsChange(Bundle settings) {
16373        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16374            ProcessRecord processRecord = mLruProcesses.get(i);
16375            try {
16376                if (processRecord.thread != null) {
16377                    processRecord.thread.setCoreSettings(settings);
16378                }
16379            } catch (RemoteException re) {
16380                /* ignore */
16381            }
16382        }
16383    }
16384
16385    // Multi-user methods
16386
16387    /**
16388     * Start user, if its not already running, but don't bring it to foreground.
16389     */
16390    @Override
16391    public boolean startUserInBackground(final int userId) {
16392        return startUser(userId, /* foreground */ false);
16393    }
16394
16395    /**
16396     * Refreshes the list of users related to the current user when either a
16397     * user switch happens or when a new related user is started in the
16398     * background.
16399     */
16400    private void updateCurrentProfileIdsLocked() {
16401        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16402                mCurrentUserId, false /* enabledOnly */);
16403        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16404        for (int i = 0; i < currentProfileIds.length; i++) {
16405            currentProfileIds[i] = profiles.get(i).id;
16406        }
16407        mCurrentProfileIds = currentProfileIds;
16408    }
16409
16410    private Set getProfileIdsLocked(int userId) {
16411        Set userIds = new HashSet<Integer>();
16412        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16413                userId, false /* enabledOnly */);
16414        for (UserInfo user : profiles) {
16415            userIds.add(Integer.valueOf(user.id));
16416        }
16417        return userIds;
16418    }
16419
16420    @Override
16421    public boolean switchUser(final int userId) {
16422        return startUser(userId, /* foregound */ true);
16423    }
16424
16425    private boolean startUser(final int userId, boolean foreground) {
16426        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16427                != PackageManager.PERMISSION_GRANTED) {
16428            String msg = "Permission Denial: switchUser() from pid="
16429                    + Binder.getCallingPid()
16430                    + ", uid=" + Binder.getCallingUid()
16431                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16432            Slog.w(TAG, msg);
16433            throw new SecurityException(msg);
16434        }
16435
16436        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16437
16438        final long ident = Binder.clearCallingIdentity();
16439        try {
16440            synchronized (this) {
16441                final int oldUserId = mCurrentUserId;
16442                if (oldUserId == userId) {
16443                    return true;
16444                }
16445
16446                mStackSupervisor.setLockTaskModeLocked(null);
16447
16448                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16449                if (userInfo == null) {
16450                    Slog.w(TAG, "No user info for user #" + userId);
16451                    return false;
16452                }
16453
16454                if (foreground) {
16455                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16456                            R.anim.screen_user_enter);
16457                }
16458
16459                boolean needStart = false;
16460
16461                // If the user we are switching to is not currently started, then
16462                // we need to start it now.
16463                if (mStartedUsers.get(userId) == null) {
16464                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16465                    updateStartedUserArrayLocked();
16466                    needStart = true;
16467                }
16468
16469                final Integer userIdInt = Integer.valueOf(userId);
16470                mUserLru.remove(userIdInt);
16471                mUserLru.add(userIdInt);
16472
16473                if (foreground) {
16474                    mCurrentUserId = userId;
16475                    updateCurrentProfileIdsLocked();
16476                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16477                    // Once the internal notion of the active user has switched, we lock the device
16478                    // with the option to show the user switcher on the keyguard.
16479                    mWindowManager.lockNow(null);
16480                } else {
16481                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16482                    updateCurrentProfileIdsLocked();
16483                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16484                    mUserLru.remove(currentUserIdInt);
16485                    mUserLru.add(currentUserIdInt);
16486                }
16487
16488                final UserStartedState uss = mStartedUsers.get(userId);
16489
16490                // Make sure user is in the started state.  If it is currently
16491                // stopping, we need to knock that off.
16492                if (uss.mState == UserStartedState.STATE_STOPPING) {
16493                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16494                    // so we can just fairly silently bring the user back from
16495                    // the almost-dead.
16496                    uss.mState = UserStartedState.STATE_RUNNING;
16497                    updateStartedUserArrayLocked();
16498                    needStart = true;
16499                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16500                    // This means ACTION_SHUTDOWN has been sent, so we will
16501                    // need to treat this as a new boot of the user.
16502                    uss.mState = UserStartedState.STATE_BOOTING;
16503                    updateStartedUserArrayLocked();
16504                    needStart = true;
16505                }
16506
16507                if (uss.mState == UserStartedState.STATE_BOOTING) {
16508                    // Booting up a new user, need to tell system services about it.
16509                    // Note that this is on the same handler as scheduling of broadcasts,
16510                    // which is important because it needs to go first.
16511                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
16512                }
16513
16514                if (foreground) {
16515                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId));
16516                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16517                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16518                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16519                            oldUserId, userId, uss));
16520                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16521                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16522                }
16523
16524                if (needStart) {
16525                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16526                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16527                            | Intent.FLAG_RECEIVER_FOREGROUND);
16528                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16529                    broadcastIntentLocked(null, null, intent,
16530                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16531                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16532                }
16533
16534                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16535                    if (userId != UserHandle.USER_OWNER) {
16536                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16537                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16538                        broadcastIntentLocked(null, null, intent, null,
16539                                new IIntentReceiver.Stub() {
16540                                    public void performReceive(Intent intent, int resultCode,
16541                                            String data, Bundle extras, boolean ordered,
16542                                            boolean sticky, int sendingUser) {
16543                                        userInitialized(uss, userId);
16544                                    }
16545                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16546                                true, false, MY_PID, Process.SYSTEM_UID,
16547                                userId);
16548                        uss.initializing = true;
16549                    } else {
16550                        getUserManagerLocked().makeInitialized(userInfo.id);
16551                    }
16552                }
16553
16554                if (foreground) {
16555                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16556                    if (homeInFront) {
16557                        startHomeActivityLocked(userId);
16558                    } else {
16559                        mStackSupervisor.resumeTopActivitiesLocked();
16560                    }
16561                    EventLogTags.writeAmSwitchUser(userId);
16562                    getUserManagerLocked().userForeground(userId);
16563                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16564                } else {
16565                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
16566                }
16567
16568                if (needStart) {
16569                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16570                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16571                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16572                    broadcastIntentLocked(null, null, intent,
16573                            null, new IIntentReceiver.Stub() {
16574                                @Override
16575                                public void performReceive(Intent intent, int resultCode, String data,
16576                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16577                                        throws RemoteException {
16578                                }
16579                            }, 0, null, null,
16580                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16581                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16582                }
16583            }
16584        } finally {
16585            Binder.restoreCallingIdentity(ident);
16586        }
16587
16588        return true;
16589    }
16590
16591    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16592        long ident = Binder.clearCallingIdentity();
16593        try {
16594            Intent intent;
16595            if (oldUserId >= 0) {
16596                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16597                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16598                        | Intent.FLAG_RECEIVER_FOREGROUND);
16599                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16600                broadcastIntentLocked(null, null, intent,
16601                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16602                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16603            }
16604            if (newUserId >= 0) {
16605                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16606                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16607                        | Intent.FLAG_RECEIVER_FOREGROUND);
16608                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16609                broadcastIntentLocked(null, null, intent,
16610                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16611                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16612                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16613                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16614                        | Intent.FLAG_RECEIVER_FOREGROUND);
16615                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16616                broadcastIntentLocked(null, null, intent,
16617                        null, null, 0, null, null,
16618                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16619                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16620            }
16621        } finally {
16622            Binder.restoreCallingIdentity(ident);
16623        }
16624    }
16625
16626    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16627            final int newUserId) {
16628        final int N = mUserSwitchObservers.beginBroadcast();
16629        if (N > 0) {
16630            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16631                int mCount = 0;
16632                @Override
16633                public void sendResult(Bundle data) throws RemoteException {
16634                    synchronized (ActivityManagerService.this) {
16635                        if (mCurUserSwitchCallback == this) {
16636                            mCount++;
16637                            if (mCount == N) {
16638                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16639                            }
16640                        }
16641                    }
16642                }
16643            };
16644            synchronized (this) {
16645                uss.switching = true;
16646                mCurUserSwitchCallback = callback;
16647            }
16648            for (int i=0; i<N; i++) {
16649                try {
16650                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16651                            newUserId, callback);
16652                } catch (RemoteException e) {
16653                }
16654            }
16655        } else {
16656            synchronized (this) {
16657                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16658            }
16659        }
16660        mUserSwitchObservers.finishBroadcast();
16661    }
16662
16663    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16664        synchronized (this) {
16665            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16666            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16667        }
16668    }
16669
16670    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16671        mCurUserSwitchCallback = null;
16672        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16673        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16674                oldUserId, newUserId, uss));
16675    }
16676
16677    void userInitialized(UserStartedState uss, int newUserId) {
16678        completeSwitchAndInitalize(uss, newUserId, true, false);
16679    }
16680
16681    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16682        completeSwitchAndInitalize(uss, newUserId, false, true);
16683    }
16684
16685    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16686            boolean clearInitializing, boolean clearSwitching) {
16687        boolean unfrozen = false;
16688        synchronized (this) {
16689            if (clearInitializing) {
16690                uss.initializing = false;
16691                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16692            }
16693            if (clearSwitching) {
16694                uss.switching = false;
16695            }
16696            if (!uss.switching && !uss.initializing) {
16697                mWindowManager.stopFreezingScreen();
16698                unfrozen = true;
16699            }
16700        }
16701        if (unfrozen) {
16702            final int N = mUserSwitchObservers.beginBroadcast();
16703            for (int i=0; i<N; i++) {
16704                try {
16705                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16706                } catch (RemoteException e) {
16707                }
16708            }
16709            mUserSwitchObservers.finishBroadcast();
16710        }
16711    }
16712
16713    void scheduleStartProfilesLocked() {
16714        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
16715            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
16716                    DateUtils.SECOND_IN_MILLIS);
16717        }
16718    }
16719
16720    void startProfilesLocked() {
16721        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
16722        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16723                mCurrentUserId, false /* enabledOnly */);
16724        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
16725        for (UserInfo user : profiles) {
16726            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
16727                    && user.id != mCurrentUserId) {
16728                toStart.add(user);
16729            }
16730        }
16731        final int n = toStart.size();
16732        int i = 0;
16733        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
16734            startUserInBackground(toStart.get(i).id);
16735        }
16736        if (i < n) {
16737            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
16738        }
16739    }
16740
16741    void finishUserBoot(UserStartedState uss) {
16742        synchronized (this) {
16743            if (uss.mState == UserStartedState.STATE_BOOTING
16744                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16745                uss.mState = UserStartedState.STATE_RUNNING;
16746                final int userId = uss.mHandle.getIdentifier();
16747                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16748                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16749                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16750                broadcastIntentLocked(null, null, intent,
16751                        null, null, 0, null, null,
16752                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16753                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16754            }
16755        }
16756    }
16757
16758    void finishUserSwitch(UserStartedState uss) {
16759        synchronized (this) {
16760            finishUserBoot(uss);
16761
16762            startProfilesLocked();
16763
16764            int num = mUserLru.size();
16765            int i = 0;
16766            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16767                Integer oldUserId = mUserLru.get(i);
16768                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16769                if (oldUss == null) {
16770                    // Shouldn't happen, but be sane if it does.
16771                    mUserLru.remove(i);
16772                    num--;
16773                    continue;
16774                }
16775                if (oldUss.mState == UserStartedState.STATE_STOPPING
16776                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16777                    // This user is already stopping, doesn't count.
16778                    num--;
16779                    i++;
16780                    continue;
16781                }
16782                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16783                    // Owner and current can't be stopped, but count as running.
16784                    i++;
16785                    continue;
16786                }
16787                // This is a user to be stopped.
16788                stopUserLocked(oldUserId, null);
16789                num--;
16790                i++;
16791            }
16792        }
16793    }
16794
16795    @Override
16796    public int stopUser(final int userId, final IStopUserCallback callback) {
16797        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16798                != PackageManager.PERMISSION_GRANTED) {
16799            String msg = "Permission Denial: switchUser() from pid="
16800                    + Binder.getCallingPid()
16801                    + ", uid=" + Binder.getCallingUid()
16802                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16803            Slog.w(TAG, msg);
16804            throw new SecurityException(msg);
16805        }
16806        if (userId <= 0) {
16807            throw new IllegalArgumentException("Can't stop primary user " + userId);
16808        }
16809        synchronized (this) {
16810            return stopUserLocked(userId, callback);
16811        }
16812    }
16813
16814    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16815        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
16816        if (mCurrentUserId == userId) {
16817            return ActivityManager.USER_OP_IS_CURRENT;
16818        }
16819
16820        final UserStartedState uss = mStartedUsers.get(userId);
16821        if (uss == null) {
16822            // User is not started, nothing to do...  but we do need to
16823            // callback if requested.
16824            if (callback != null) {
16825                mHandler.post(new Runnable() {
16826                    @Override
16827                    public void run() {
16828                        try {
16829                            callback.userStopped(userId);
16830                        } catch (RemoteException e) {
16831                        }
16832                    }
16833                });
16834            }
16835            return ActivityManager.USER_OP_SUCCESS;
16836        }
16837
16838        if (callback != null) {
16839            uss.mStopCallbacks.add(callback);
16840        }
16841
16842        if (uss.mState != UserStartedState.STATE_STOPPING
16843                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16844            uss.mState = UserStartedState.STATE_STOPPING;
16845            updateStartedUserArrayLocked();
16846
16847            long ident = Binder.clearCallingIdentity();
16848            try {
16849                // We are going to broadcast ACTION_USER_STOPPING and then
16850                // once that is done send a final ACTION_SHUTDOWN and then
16851                // stop the user.
16852                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16853                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16854                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16855                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16856                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16857                // This is the result receiver for the final shutdown broadcast.
16858                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16859                    @Override
16860                    public void performReceive(Intent intent, int resultCode, String data,
16861                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16862                        finishUserStop(uss);
16863                    }
16864                };
16865                // This is the result receiver for the initial stopping broadcast.
16866                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16867                    @Override
16868                    public void performReceive(Intent intent, int resultCode, String data,
16869                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16870                        // On to the next.
16871                        synchronized (ActivityManagerService.this) {
16872                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16873                                // Whoops, we are being started back up.  Abort, abort!
16874                                return;
16875                            }
16876                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16877                        }
16878                        mSystemServiceManager.stopUser(userId);
16879                        broadcastIntentLocked(null, null, shutdownIntent,
16880                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16881                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16882                    }
16883                };
16884                // Kick things off.
16885                broadcastIntentLocked(null, null, stoppingIntent,
16886                        null, stoppingReceiver, 0, null, null,
16887                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16888                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16889            } finally {
16890                Binder.restoreCallingIdentity(ident);
16891            }
16892        }
16893
16894        return ActivityManager.USER_OP_SUCCESS;
16895    }
16896
16897    void finishUserStop(UserStartedState uss) {
16898        final int userId = uss.mHandle.getIdentifier();
16899        boolean stopped;
16900        ArrayList<IStopUserCallback> callbacks;
16901        synchronized (this) {
16902            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16903            if (mStartedUsers.get(userId) != uss) {
16904                stopped = false;
16905            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16906                stopped = false;
16907            } else {
16908                stopped = true;
16909                // User can no longer run.
16910                mStartedUsers.remove(userId);
16911                mUserLru.remove(Integer.valueOf(userId));
16912                updateStartedUserArrayLocked();
16913
16914                // Clean up all state and processes associated with the user.
16915                // Kill all the processes for the user.
16916                forceStopUserLocked(userId, "finish user");
16917            }
16918        }
16919
16920        for (int i=0; i<callbacks.size(); i++) {
16921            try {
16922                if (stopped) callbacks.get(i).userStopped(userId);
16923                else callbacks.get(i).userStopAborted(userId);
16924            } catch (RemoteException e) {
16925            }
16926        }
16927
16928        if (stopped) {
16929            mSystemServiceManager.cleanupUser(userId);
16930            synchronized (this) {
16931                mStackSupervisor.removeUserLocked(userId);
16932            }
16933        }
16934    }
16935
16936    @Override
16937    public UserInfo getCurrentUser() {
16938        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16939                != PackageManager.PERMISSION_GRANTED) && (
16940                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16941                != PackageManager.PERMISSION_GRANTED)) {
16942            String msg = "Permission Denial: getCurrentUser() from pid="
16943                    + Binder.getCallingPid()
16944                    + ", uid=" + Binder.getCallingUid()
16945                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16946            Slog.w(TAG, msg);
16947            throw new SecurityException(msg);
16948        }
16949        synchronized (this) {
16950            return getUserManagerLocked().getUserInfo(mCurrentUserId);
16951        }
16952    }
16953
16954    int getCurrentUserIdLocked() {
16955        return mCurrentUserId;
16956    }
16957
16958    @Override
16959    public boolean isUserRunning(int userId, boolean orStopped) {
16960        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16961                != PackageManager.PERMISSION_GRANTED) {
16962            String msg = "Permission Denial: isUserRunning() from pid="
16963                    + Binder.getCallingPid()
16964                    + ", uid=" + Binder.getCallingUid()
16965                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16966            Slog.w(TAG, msg);
16967            throw new SecurityException(msg);
16968        }
16969        synchronized (this) {
16970            return isUserRunningLocked(userId, orStopped);
16971        }
16972    }
16973
16974    boolean isUserRunningLocked(int userId, boolean orStopped) {
16975        UserStartedState state = mStartedUsers.get(userId);
16976        if (state == null) {
16977            return false;
16978        }
16979        if (orStopped) {
16980            return true;
16981        }
16982        return state.mState != UserStartedState.STATE_STOPPING
16983                && state.mState != UserStartedState.STATE_SHUTDOWN;
16984    }
16985
16986    @Override
16987    public int[] getRunningUserIds() {
16988        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16989                != PackageManager.PERMISSION_GRANTED) {
16990            String msg = "Permission Denial: isUserRunning() from pid="
16991                    + Binder.getCallingPid()
16992                    + ", uid=" + Binder.getCallingUid()
16993                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16994            Slog.w(TAG, msg);
16995            throw new SecurityException(msg);
16996        }
16997        synchronized (this) {
16998            return mStartedUserArray;
16999        }
17000    }
17001
17002    private void updateStartedUserArrayLocked() {
17003        int num = 0;
17004        for (int i=0; i<mStartedUsers.size();  i++) {
17005            UserStartedState uss = mStartedUsers.valueAt(i);
17006            // This list does not include stopping users.
17007            if (uss.mState != UserStartedState.STATE_STOPPING
17008                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17009                num++;
17010            }
17011        }
17012        mStartedUserArray = new int[num];
17013        num = 0;
17014        for (int i=0; i<mStartedUsers.size();  i++) {
17015            UserStartedState uss = mStartedUsers.valueAt(i);
17016            if (uss.mState != UserStartedState.STATE_STOPPING
17017                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17018                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17019                num++;
17020            }
17021        }
17022    }
17023
17024    @Override
17025    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17026        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
17027                != PackageManager.PERMISSION_GRANTED) {
17028            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17029                    + Binder.getCallingPid()
17030                    + ", uid=" + Binder.getCallingUid()
17031                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
17032            Slog.w(TAG, msg);
17033            throw new SecurityException(msg);
17034        }
17035
17036        mUserSwitchObservers.register(observer);
17037    }
17038
17039    @Override
17040    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17041        mUserSwitchObservers.unregister(observer);
17042    }
17043
17044    private boolean userExists(int userId) {
17045        if (userId == 0) {
17046            return true;
17047        }
17048        UserManagerService ums = getUserManagerLocked();
17049        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17050    }
17051
17052    int[] getUsersLocked() {
17053        UserManagerService ums = getUserManagerLocked();
17054        return ums != null ? ums.getUserIds() : new int[] { 0 };
17055    }
17056
17057    UserManagerService getUserManagerLocked() {
17058        if (mUserManager == null) {
17059            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17060            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17061        }
17062        return mUserManager;
17063    }
17064
17065    private int applyUserId(int uid, int userId) {
17066        return UserHandle.getUid(userId, uid);
17067    }
17068
17069    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17070        if (info == null) return null;
17071        ApplicationInfo newInfo = new ApplicationInfo(info);
17072        newInfo.uid = applyUserId(info.uid, userId);
17073        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17074                + info.packageName;
17075        return newInfo;
17076    }
17077
17078    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17079        if (aInfo == null
17080                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17081            return aInfo;
17082        }
17083
17084        ActivityInfo info = new ActivityInfo(aInfo);
17085        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17086        return info;
17087    }
17088
17089    private final class LocalService extends ActivityManagerInternal {
17090        @Override
17091        public void goingToSleep() {
17092            ActivityManagerService.this.goingToSleep();
17093        }
17094
17095        @Override
17096        public void wakingUp() {
17097            ActivityManagerService.this.wakingUp();
17098        }
17099    }
17100}
17101