ActivityManagerService.java revision 233ceeebab7efe6ad4783371003c4cf29b896436
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.requiredCpuAbi;
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, ActivityOptions options) {
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, options);
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 ActivityOptions getActivityOptions(IBinder token) {
9054        final long origId = Binder.clearCallingIdentity();
9055        try {
9056            synchronized (this) {
9057                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9058                if (r != null) {
9059                    final ActivityOptions activityOptions = r.pendingOptions;
9060                    r.pendingOptions = null;
9061                    return activityOptions;
9062                }
9063                return null;
9064            }
9065        } finally {
9066            Binder.restoreCallingIdentity(origId);
9067        }
9068    }
9069
9070    @Override
9071    public void setImmersive(IBinder token, boolean immersive) {
9072        synchronized(this) {
9073            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9074            if (r == null) {
9075                throw new IllegalArgumentException();
9076            }
9077            r.immersive = immersive;
9078
9079            // update associated state if we're frontmost
9080            if (r == mFocusedActivity) {
9081                if (DEBUG_IMMERSIVE) {
9082                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9083                }
9084                applyUpdateLockStateLocked(r);
9085            }
9086        }
9087    }
9088
9089    @Override
9090    public boolean isImmersive(IBinder token) {
9091        synchronized (this) {
9092            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9093            if (r == null) {
9094                throw new IllegalArgumentException();
9095            }
9096            return r.immersive;
9097        }
9098    }
9099
9100    public boolean isTopActivityImmersive() {
9101        enforceNotIsolatedCaller("startActivity");
9102        synchronized (this) {
9103            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9104            return (r != null) ? r.immersive : false;
9105        }
9106    }
9107
9108    public final void enterSafeMode() {
9109        synchronized(this) {
9110            // It only makes sense to do this before the system is ready
9111            // and started launching other packages.
9112            if (!mSystemReady) {
9113                try {
9114                    AppGlobals.getPackageManager().enterSafeMode();
9115                } catch (RemoteException e) {
9116                }
9117            }
9118
9119            mSafeMode = true;
9120        }
9121    }
9122
9123    public final void showSafeModeOverlay() {
9124        View v = LayoutInflater.from(mContext).inflate(
9125                com.android.internal.R.layout.safe_mode, null);
9126        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9127        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9128        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9129        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9130        lp.gravity = Gravity.BOTTOM | Gravity.START;
9131        lp.format = v.getBackground().getOpacity();
9132        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9133                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9134        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9135        ((WindowManager)mContext.getSystemService(
9136                Context.WINDOW_SERVICE)).addView(v, lp);
9137    }
9138
9139    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9140        if (!(sender instanceof PendingIntentRecord)) {
9141            return;
9142        }
9143        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9144        synchronized (stats) {
9145            if (mBatteryStatsService.isOnBattery()) {
9146                mBatteryStatsService.enforceCallingPermission();
9147                PendingIntentRecord rec = (PendingIntentRecord)sender;
9148                int MY_UID = Binder.getCallingUid();
9149                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9150                BatteryStatsImpl.Uid.Pkg pkg =
9151                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9152                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9153                pkg.incWakeupsLocked();
9154            }
9155        }
9156    }
9157
9158    public boolean killPids(int[] pids, String pReason, boolean secure) {
9159        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9160            throw new SecurityException("killPids only available to the system");
9161        }
9162        String reason = (pReason == null) ? "Unknown" : pReason;
9163        // XXX Note: don't acquire main activity lock here, because the window
9164        // manager calls in with its locks held.
9165
9166        boolean killed = false;
9167        synchronized (mPidsSelfLocked) {
9168            int[] types = new int[pids.length];
9169            int worstType = 0;
9170            for (int i=0; i<pids.length; i++) {
9171                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9172                if (proc != null) {
9173                    int type = proc.setAdj;
9174                    types[i] = type;
9175                    if (type > worstType) {
9176                        worstType = type;
9177                    }
9178                }
9179            }
9180
9181            // If the worst oom_adj is somewhere in the cached proc LRU range,
9182            // then constrain it so we will kill all cached procs.
9183            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9184                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9185                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9186            }
9187
9188            // If this is not a secure call, don't let it kill processes that
9189            // are important.
9190            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9191                worstType = ProcessList.SERVICE_ADJ;
9192            }
9193
9194            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9195            for (int i=0; i<pids.length; i++) {
9196                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9197                if (proc == null) {
9198                    continue;
9199                }
9200                int adj = proc.setAdj;
9201                if (adj >= worstType && !proc.killedByAm) {
9202                    killUnneededProcessLocked(proc, reason);
9203                    killed = true;
9204                }
9205            }
9206        }
9207        return killed;
9208    }
9209
9210    @Override
9211    public void killUid(int uid, String reason) {
9212        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9213            throw new SecurityException("killUid only available to the system");
9214        }
9215        synchronized (this) {
9216            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9217                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9218                    reason != null ? reason : "kill uid");
9219        }
9220    }
9221
9222    @Override
9223    public boolean killProcessesBelowForeground(String reason) {
9224        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9225            throw new SecurityException("killProcessesBelowForeground() only available to system");
9226        }
9227
9228        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9229    }
9230
9231    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9232        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9233            throw new SecurityException("killProcessesBelowAdj() only available to system");
9234        }
9235
9236        boolean killed = false;
9237        synchronized (mPidsSelfLocked) {
9238            final int size = mPidsSelfLocked.size();
9239            for (int i = 0; i < size; i++) {
9240                final int pid = mPidsSelfLocked.keyAt(i);
9241                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9242                if (proc == null) continue;
9243
9244                final int adj = proc.setAdj;
9245                if (adj > belowAdj && !proc.killedByAm) {
9246                    killUnneededProcessLocked(proc, reason);
9247                    killed = true;
9248                }
9249            }
9250        }
9251        return killed;
9252    }
9253
9254    @Override
9255    public void hang(final IBinder who, boolean allowRestart) {
9256        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9257                != PackageManager.PERMISSION_GRANTED) {
9258            throw new SecurityException("Requires permission "
9259                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9260        }
9261
9262        final IBinder.DeathRecipient death = new DeathRecipient() {
9263            @Override
9264            public void binderDied() {
9265                synchronized (this) {
9266                    notifyAll();
9267                }
9268            }
9269        };
9270
9271        try {
9272            who.linkToDeath(death, 0);
9273        } catch (RemoteException e) {
9274            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9275            return;
9276        }
9277
9278        synchronized (this) {
9279            Watchdog.getInstance().setAllowRestart(allowRestart);
9280            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9281            synchronized (death) {
9282                while (who.isBinderAlive()) {
9283                    try {
9284                        death.wait();
9285                    } catch (InterruptedException e) {
9286                    }
9287                }
9288            }
9289            Watchdog.getInstance().setAllowRestart(true);
9290        }
9291    }
9292
9293    @Override
9294    public void restart() {
9295        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9296                != PackageManager.PERMISSION_GRANTED) {
9297            throw new SecurityException("Requires permission "
9298                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9299        }
9300
9301        Log.i(TAG, "Sending shutdown broadcast...");
9302
9303        BroadcastReceiver br = new BroadcastReceiver() {
9304            @Override public void onReceive(Context context, Intent intent) {
9305                // Now the broadcast is done, finish up the low-level shutdown.
9306                Log.i(TAG, "Shutting down activity manager...");
9307                shutdown(10000);
9308                Log.i(TAG, "Shutdown complete, restarting!");
9309                Process.killProcess(Process.myPid());
9310                System.exit(10);
9311            }
9312        };
9313
9314        // First send the high-level shut down broadcast.
9315        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9316        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9317        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9318        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9319        mContext.sendOrderedBroadcastAsUser(intent,
9320                UserHandle.ALL, null, br, mHandler, 0, null, null);
9321        */
9322        br.onReceive(mContext, intent);
9323    }
9324
9325    private long getLowRamTimeSinceIdle(long now) {
9326        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9327    }
9328
9329    @Override
9330    public void performIdleMaintenance() {
9331        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9332                != PackageManager.PERMISSION_GRANTED) {
9333            throw new SecurityException("Requires permission "
9334                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9335        }
9336
9337        synchronized (this) {
9338            final long now = SystemClock.uptimeMillis();
9339            final long timeSinceLastIdle = now - mLastIdleTime;
9340            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9341            mLastIdleTime = now;
9342            mLowRamTimeSinceLastIdle = 0;
9343            if (mLowRamStartTime != 0) {
9344                mLowRamStartTime = now;
9345            }
9346
9347            StringBuilder sb = new StringBuilder(128);
9348            sb.append("Idle maintenance over ");
9349            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9350            sb.append(" low RAM for ");
9351            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9352            Slog.i(TAG, sb.toString());
9353
9354            // If at least 1/3 of our time since the last idle period has been spent
9355            // with RAM low, then we want to kill processes.
9356            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9357
9358            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9359                ProcessRecord proc = mLruProcesses.get(i);
9360                if (proc.notCachedSinceIdle) {
9361                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9362                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9363                        if (doKilling && proc.initialIdlePss != 0
9364                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9365                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9366                                    + " from " + proc.initialIdlePss + ")");
9367                        }
9368                    }
9369                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9370                    proc.notCachedSinceIdle = true;
9371                    proc.initialIdlePss = 0;
9372                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9373                            isSleeping(), now);
9374                }
9375            }
9376
9377            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9378            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9379        }
9380    }
9381
9382    private void retrieveSettings() {
9383        final ContentResolver resolver = mContext.getContentResolver();
9384        String debugApp = Settings.Global.getString(
9385            resolver, Settings.Global.DEBUG_APP);
9386        boolean waitForDebugger = Settings.Global.getInt(
9387            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9388        boolean alwaysFinishActivities = Settings.Global.getInt(
9389            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9390        boolean forceRtl = Settings.Global.getInt(
9391                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9392        // Transfer any global setting for forcing RTL layout, into a System Property
9393        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9394
9395        Configuration configuration = new Configuration();
9396        Settings.System.getConfiguration(resolver, configuration);
9397        if (forceRtl) {
9398            // This will take care of setting the correct layout direction flags
9399            configuration.setLayoutDirection(configuration.locale);
9400        }
9401
9402        synchronized (this) {
9403            mDebugApp = mOrigDebugApp = debugApp;
9404            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9405            mAlwaysFinishActivities = alwaysFinishActivities;
9406            // This happens before any activities are started, so we can
9407            // change mConfiguration in-place.
9408            updateConfigurationLocked(configuration, null, false, true);
9409            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9410        }
9411    }
9412
9413    public boolean testIsSystemReady() {
9414        // no need to synchronize(this) just to read & return the value
9415        return mSystemReady;
9416    }
9417
9418    private static File getCalledPreBootReceiversFile() {
9419        File dataDir = Environment.getDataDirectory();
9420        File systemDir = new File(dataDir, "system");
9421        File fname = new File(systemDir, "called_pre_boots.dat");
9422        return fname;
9423    }
9424
9425    static final int LAST_DONE_VERSION = 10000;
9426
9427    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9428        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9429        File file = getCalledPreBootReceiversFile();
9430        FileInputStream fis = null;
9431        try {
9432            fis = new FileInputStream(file);
9433            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9434            int fvers = dis.readInt();
9435            if (fvers == LAST_DONE_VERSION) {
9436                String vers = dis.readUTF();
9437                String codename = dis.readUTF();
9438                String build = dis.readUTF();
9439                if (android.os.Build.VERSION.RELEASE.equals(vers)
9440                        && android.os.Build.VERSION.CODENAME.equals(codename)
9441                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9442                    int num = dis.readInt();
9443                    while (num > 0) {
9444                        num--;
9445                        String pkg = dis.readUTF();
9446                        String cls = dis.readUTF();
9447                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9448                    }
9449                }
9450            }
9451        } catch (FileNotFoundException e) {
9452        } catch (IOException e) {
9453            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9454        } finally {
9455            if (fis != null) {
9456                try {
9457                    fis.close();
9458                } catch (IOException e) {
9459                }
9460            }
9461        }
9462        return lastDoneReceivers;
9463    }
9464
9465    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9466        File file = getCalledPreBootReceiversFile();
9467        FileOutputStream fos = null;
9468        DataOutputStream dos = null;
9469        try {
9470            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9471            fos = new FileOutputStream(file);
9472            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9473            dos.writeInt(LAST_DONE_VERSION);
9474            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9475            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9476            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9477            dos.writeInt(list.size());
9478            for (int i=0; i<list.size(); i++) {
9479                dos.writeUTF(list.get(i).getPackageName());
9480                dos.writeUTF(list.get(i).getClassName());
9481            }
9482        } catch (IOException e) {
9483            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9484            file.delete();
9485        } finally {
9486            FileUtils.sync(fos);
9487            if (dos != null) {
9488                try {
9489                    dos.close();
9490                } catch (IOException e) {
9491                    // TODO Auto-generated catch block
9492                    e.printStackTrace();
9493                }
9494            }
9495        }
9496    }
9497
9498    public void systemReady(final Runnable goingCallback) {
9499        synchronized(this) {
9500            if (mSystemReady) {
9501                if (goingCallback != null) goingCallback.run();
9502                return;
9503            }
9504
9505            // Check to see if there are any update receivers to run.
9506            if (!mDidUpdate) {
9507                if (mWaitingUpdate) {
9508                    return;
9509                }
9510                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9511                List<ResolveInfo> ris = null;
9512                try {
9513                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9514                            intent, null, 0, 0);
9515                } catch (RemoteException e) {
9516                }
9517                if (ris != null) {
9518                    for (int i=ris.size()-1; i>=0; i--) {
9519                        if ((ris.get(i).activityInfo.applicationInfo.flags
9520                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9521                            ris.remove(i);
9522                        }
9523                    }
9524                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9525
9526                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9527
9528                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9529                    for (int i=0; i<ris.size(); i++) {
9530                        ActivityInfo ai = ris.get(i).activityInfo;
9531                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9532                        if (lastDoneReceivers.contains(comp)) {
9533                            // We already did the pre boot receiver for this app with the current
9534                            // platform version, so don't do it again...
9535                            ris.remove(i);
9536                            i--;
9537                            // ...however, do keep it as one that has been done, so we don't
9538                            // forget about it when rewriting the file of last done receivers.
9539                            doneReceivers.add(comp);
9540                        }
9541                    }
9542
9543                    final int[] users = getUsersLocked();
9544                    for (int i=0; i<ris.size(); i++) {
9545                        ActivityInfo ai = ris.get(i).activityInfo;
9546                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9547                        doneReceivers.add(comp);
9548                        intent.setComponent(comp);
9549                        for (int j=0; j<users.length; j++) {
9550                            IIntentReceiver finisher = null;
9551                            if (i == ris.size()-1 && j == users.length-1) {
9552                                finisher = new IIntentReceiver.Stub() {
9553                                    public void performReceive(Intent intent, int resultCode,
9554                                            String data, Bundle extras, boolean ordered,
9555                                            boolean sticky, int sendingUser) {
9556                                        // The raw IIntentReceiver interface is called
9557                                        // with the AM lock held, so redispatch to
9558                                        // execute our code without the lock.
9559                                        mHandler.post(new Runnable() {
9560                                            public void run() {
9561                                                synchronized (ActivityManagerService.this) {
9562                                                    mDidUpdate = true;
9563                                                }
9564                                                writeLastDonePreBootReceivers(doneReceivers);
9565                                                showBootMessage(mContext.getText(
9566                                                        R.string.android_upgrading_complete),
9567                                                        false);
9568                                                systemReady(goingCallback);
9569                                            }
9570                                        });
9571                                    }
9572                                };
9573                            }
9574                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9575                                    + " for user " + users[j]);
9576                            broadcastIntentLocked(null, null, intent, null, finisher,
9577                                    0, null, null, null, AppOpsManager.OP_NONE,
9578                                    true, false, MY_PID, Process.SYSTEM_UID,
9579                                    users[j]);
9580                            if (finisher != null) {
9581                                mWaitingUpdate = true;
9582                            }
9583                        }
9584                    }
9585                }
9586                if (mWaitingUpdate) {
9587                    return;
9588                }
9589                mDidUpdate = true;
9590            }
9591
9592            mAppOpsService.systemReady();
9593            mUsageStatsService.systemReady();
9594            mSystemReady = true;
9595        }
9596
9597        ArrayList<ProcessRecord> procsToKill = null;
9598        synchronized(mPidsSelfLocked) {
9599            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9600                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9601                if (!isAllowedWhileBooting(proc.info)){
9602                    if (procsToKill == null) {
9603                        procsToKill = new ArrayList<ProcessRecord>();
9604                    }
9605                    procsToKill.add(proc);
9606                }
9607            }
9608        }
9609
9610        synchronized(this) {
9611            if (procsToKill != null) {
9612                for (int i=procsToKill.size()-1; i>=0; i--) {
9613                    ProcessRecord proc = procsToKill.get(i);
9614                    Slog.i(TAG, "Removing system update proc: " + proc);
9615                    removeProcessLocked(proc, true, false, "system update done");
9616                }
9617            }
9618
9619            // Now that we have cleaned up any update processes, we
9620            // are ready to start launching real processes and know that
9621            // we won't trample on them any more.
9622            mProcessesReady = true;
9623        }
9624
9625        Slog.i(TAG, "System now ready");
9626        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9627            SystemClock.uptimeMillis());
9628
9629        synchronized(this) {
9630            // Make sure we have no pre-ready processes sitting around.
9631
9632            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9633                ResolveInfo ri = mContext.getPackageManager()
9634                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9635                                STOCK_PM_FLAGS);
9636                CharSequence errorMsg = null;
9637                if (ri != null) {
9638                    ActivityInfo ai = ri.activityInfo;
9639                    ApplicationInfo app = ai.applicationInfo;
9640                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9641                        mTopAction = Intent.ACTION_FACTORY_TEST;
9642                        mTopData = null;
9643                        mTopComponent = new ComponentName(app.packageName,
9644                                ai.name);
9645                    } else {
9646                        errorMsg = mContext.getResources().getText(
9647                                com.android.internal.R.string.factorytest_not_system);
9648                    }
9649                } else {
9650                    errorMsg = mContext.getResources().getText(
9651                            com.android.internal.R.string.factorytest_no_action);
9652                }
9653                if (errorMsg != null) {
9654                    mTopAction = null;
9655                    mTopData = null;
9656                    mTopComponent = null;
9657                    Message msg = Message.obtain();
9658                    msg.what = SHOW_FACTORY_ERROR_MSG;
9659                    msg.getData().putCharSequence("msg", errorMsg);
9660                    mHandler.sendMessage(msg);
9661                }
9662            }
9663        }
9664
9665        retrieveSettings();
9666
9667        synchronized (this) {
9668            readGrantedUriPermissionsLocked();
9669        }
9670
9671        if (goingCallback != null) goingCallback.run();
9672
9673        mSystemServiceManager.startUser(mCurrentUserId);
9674
9675        synchronized (this) {
9676            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9677                try {
9678                    List apps = AppGlobals.getPackageManager().
9679                        getPersistentApplications(STOCK_PM_FLAGS);
9680                    if (apps != null) {
9681                        int N = apps.size();
9682                        int i;
9683                        for (i=0; i<N; i++) {
9684                            ApplicationInfo info
9685                                = (ApplicationInfo)apps.get(i);
9686                            if (info != null &&
9687                                    !info.packageName.equals("android")) {
9688                                addAppLocked(info, false);
9689                            }
9690                        }
9691                    }
9692                } catch (RemoteException ex) {
9693                    // pm is in same process, this will never happen.
9694                }
9695            }
9696
9697            // Start up initial activity.
9698            mBooting = true;
9699
9700            try {
9701                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9702                    Message msg = Message.obtain();
9703                    msg.what = SHOW_UID_ERROR_MSG;
9704                    mHandler.sendMessage(msg);
9705                }
9706            } catch (RemoteException e) {
9707            }
9708
9709            long ident = Binder.clearCallingIdentity();
9710            try {
9711                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9712                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9713                        | Intent.FLAG_RECEIVER_FOREGROUND);
9714                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9715                broadcastIntentLocked(null, null, intent,
9716                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9717                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9718                intent = new Intent(Intent.ACTION_USER_STARTING);
9719                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9720                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9721                broadcastIntentLocked(null, null, intent,
9722                        null, new IIntentReceiver.Stub() {
9723                            @Override
9724                            public void performReceive(Intent intent, int resultCode, String data,
9725                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9726                                    throws RemoteException {
9727                            }
9728                        }, 0, null, null,
9729                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9730                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9731            } catch (Throwable t) {
9732                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
9733            } finally {
9734                Binder.restoreCallingIdentity(ident);
9735            }
9736            mStackSupervisor.resumeTopActivitiesLocked();
9737            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9738        }
9739    }
9740
9741    private boolean makeAppCrashingLocked(ProcessRecord app,
9742            String shortMsg, String longMsg, String stackTrace) {
9743        app.crashing = true;
9744        app.crashingReport = generateProcessError(app,
9745                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9746        startAppProblemLocked(app);
9747        app.stopFreezingAllLocked();
9748        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9749    }
9750
9751    private void makeAppNotRespondingLocked(ProcessRecord app,
9752            String activity, String shortMsg, String longMsg) {
9753        app.notResponding = true;
9754        app.notRespondingReport = generateProcessError(app,
9755                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9756                activity, shortMsg, longMsg, null);
9757        startAppProblemLocked(app);
9758        app.stopFreezingAllLocked();
9759    }
9760
9761    /**
9762     * Generate a process error record, suitable for attachment to a ProcessRecord.
9763     *
9764     * @param app The ProcessRecord in which the error occurred.
9765     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9766     *                      ActivityManager.AppErrorStateInfo
9767     * @param activity The activity associated with the crash, if known.
9768     * @param shortMsg Short message describing the crash.
9769     * @param longMsg Long message describing the crash.
9770     * @param stackTrace Full crash stack trace, may be null.
9771     *
9772     * @return Returns a fully-formed AppErrorStateInfo record.
9773     */
9774    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9775            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9776        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9777
9778        report.condition = condition;
9779        report.processName = app.processName;
9780        report.pid = app.pid;
9781        report.uid = app.info.uid;
9782        report.tag = activity;
9783        report.shortMsg = shortMsg;
9784        report.longMsg = longMsg;
9785        report.stackTrace = stackTrace;
9786
9787        return report;
9788    }
9789
9790    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9791        synchronized (this) {
9792            app.crashing = false;
9793            app.crashingReport = null;
9794            app.notResponding = false;
9795            app.notRespondingReport = null;
9796            if (app.anrDialog == fromDialog) {
9797                app.anrDialog = null;
9798            }
9799            if (app.waitDialog == fromDialog) {
9800                app.waitDialog = null;
9801            }
9802            if (app.pid > 0 && app.pid != MY_PID) {
9803                handleAppCrashLocked(app, null, null, null);
9804                killUnneededProcessLocked(app, "user request after error");
9805            }
9806        }
9807    }
9808
9809    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9810            String stackTrace) {
9811        long now = SystemClock.uptimeMillis();
9812
9813        Long crashTime;
9814        if (!app.isolated) {
9815            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9816        } else {
9817            crashTime = null;
9818        }
9819        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9820            // This process loses!
9821            Slog.w(TAG, "Process " + app.info.processName
9822                    + " has crashed too many times: killing!");
9823            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9824                    app.userId, app.info.processName, app.uid);
9825            mStackSupervisor.handleAppCrashLocked(app);
9826            if (!app.persistent) {
9827                // We don't want to start this process again until the user
9828                // explicitly does so...  but for persistent process, we really
9829                // need to keep it running.  If a persistent process is actually
9830                // repeatedly crashing, then badness for everyone.
9831                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9832                        app.info.processName);
9833                if (!app.isolated) {
9834                    // XXX We don't have a way to mark isolated processes
9835                    // as bad, since they don't have a peristent identity.
9836                    mBadProcesses.put(app.info.processName, app.uid,
9837                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9838                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9839                }
9840                app.bad = true;
9841                app.removed = true;
9842                // Don't let services in this process be restarted and potentially
9843                // annoy the user repeatedly.  Unless it is persistent, since those
9844                // processes run critical code.
9845                removeProcessLocked(app, false, false, "crash");
9846                mStackSupervisor.resumeTopActivitiesLocked();
9847                return false;
9848            }
9849            mStackSupervisor.resumeTopActivitiesLocked();
9850        } else {
9851            mStackSupervisor.finishTopRunningActivityLocked(app);
9852        }
9853
9854        // Bump up the crash count of any services currently running in the proc.
9855        for (int i=app.services.size()-1; i>=0; i--) {
9856            // Any services running in the application need to be placed
9857            // back in the pending list.
9858            ServiceRecord sr = app.services.valueAt(i);
9859            sr.crashCount++;
9860        }
9861
9862        // If the crashing process is what we consider to be the "home process" and it has been
9863        // replaced by a third-party app, clear the package preferred activities from packages
9864        // with a home activity running in the process to prevent a repeatedly crashing app
9865        // from blocking the user to manually clear the list.
9866        final ArrayList<ActivityRecord> activities = app.activities;
9867        if (app == mHomeProcess && activities.size() > 0
9868                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9869            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9870                final ActivityRecord r = activities.get(activityNdx);
9871                if (r.isHomeActivity()) {
9872                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9873                    try {
9874                        ActivityThread.getPackageManager()
9875                                .clearPackagePreferredActivities(r.packageName);
9876                    } catch (RemoteException c) {
9877                        // pm is in same process, this will never happen.
9878                    }
9879                }
9880            }
9881        }
9882
9883        if (!app.isolated) {
9884            // XXX Can't keep track of crash times for isolated processes,
9885            // because they don't have a perisistent identity.
9886            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9887        }
9888
9889        return true;
9890    }
9891
9892    void startAppProblemLocked(ProcessRecord app) {
9893        if (app.userId == mCurrentUserId) {
9894            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9895                    mContext, app.info.packageName, app.info.flags);
9896        } else {
9897            // If this app is not running under the current user, then we
9898            // can't give it a report button because that would require
9899            // launching the report UI under a different user.
9900            app.errorReportReceiver = null;
9901        }
9902        skipCurrentReceiverLocked(app);
9903    }
9904
9905    void skipCurrentReceiverLocked(ProcessRecord app) {
9906        for (BroadcastQueue queue : mBroadcastQueues) {
9907            queue.skipCurrentReceiverLocked(app);
9908        }
9909    }
9910
9911    /**
9912     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9913     * The application process will exit immediately after this call returns.
9914     * @param app object of the crashing app, null for the system server
9915     * @param crashInfo describing the exception
9916     */
9917    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9918        ProcessRecord r = findAppProcess(app, "Crash");
9919        final String processName = app == null ? "system_server"
9920                : (r == null ? "unknown" : r.processName);
9921
9922        handleApplicationCrashInner("crash", r, processName, crashInfo);
9923    }
9924
9925    /* Native crash reporting uses this inner version because it needs to be somewhat
9926     * decoupled from the AM-managed cleanup lifecycle
9927     */
9928    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
9929            ApplicationErrorReport.CrashInfo crashInfo) {
9930        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
9931                UserHandle.getUserId(Binder.getCallingUid()), processName,
9932                r == null ? -1 : r.info.flags,
9933                crashInfo.exceptionClassName,
9934                crashInfo.exceptionMessage,
9935                crashInfo.throwFileName,
9936                crashInfo.throwLineNumber);
9937
9938        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
9939
9940        crashApplication(r, crashInfo);
9941    }
9942
9943    public void handleApplicationStrictModeViolation(
9944            IBinder app,
9945            int violationMask,
9946            StrictMode.ViolationInfo info) {
9947        ProcessRecord r = findAppProcess(app, "StrictMode");
9948        if (r == null) {
9949            return;
9950        }
9951
9952        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
9953            Integer stackFingerprint = info.hashCode();
9954            boolean logIt = true;
9955            synchronized (mAlreadyLoggedViolatedStacks) {
9956                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
9957                    logIt = false;
9958                    // TODO: sub-sample into EventLog for these, with
9959                    // the info.durationMillis?  Then we'd get
9960                    // the relative pain numbers, without logging all
9961                    // the stack traces repeatedly.  We'd want to do
9962                    // likewise in the client code, which also does
9963                    // dup suppression, before the Binder call.
9964                } else {
9965                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
9966                        mAlreadyLoggedViolatedStacks.clear();
9967                    }
9968                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
9969                }
9970            }
9971            if (logIt) {
9972                logStrictModeViolationToDropBox(r, info);
9973            }
9974        }
9975
9976        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
9977            AppErrorResult result = new AppErrorResult();
9978            synchronized (this) {
9979                final long origId = Binder.clearCallingIdentity();
9980
9981                Message msg = Message.obtain();
9982                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
9983                HashMap<String, Object> data = new HashMap<String, Object>();
9984                data.put("result", result);
9985                data.put("app", r);
9986                data.put("violationMask", violationMask);
9987                data.put("info", info);
9988                msg.obj = data;
9989                mHandler.sendMessage(msg);
9990
9991                Binder.restoreCallingIdentity(origId);
9992            }
9993            int res = result.get();
9994            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
9995        }
9996    }
9997
9998    // Depending on the policy in effect, there could be a bunch of
9999    // these in quick succession so we try to batch these together to
10000    // minimize disk writes, number of dropbox entries, and maximize
10001    // compression, by having more fewer, larger records.
10002    private void logStrictModeViolationToDropBox(
10003            ProcessRecord process,
10004            StrictMode.ViolationInfo info) {
10005        if (info == null) {
10006            return;
10007        }
10008        final boolean isSystemApp = process == null ||
10009                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10010                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10011        final String processName = process == null ? "unknown" : process.processName;
10012        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10013        final DropBoxManager dbox = (DropBoxManager)
10014                mContext.getSystemService(Context.DROPBOX_SERVICE);
10015
10016        // Exit early if the dropbox isn't configured to accept this report type.
10017        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10018
10019        boolean bufferWasEmpty;
10020        boolean needsFlush;
10021        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10022        synchronized (sb) {
10023            bufferWasEmpty = sb.length() == 0;
10024            appendDropBoxProcessHeaders(process, processName, sb);
10025            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10026            sb.append("System-App: ").append(isSystemApp).append("\n");
10027            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10028            if (info.violationNumThisLoop != 0) {
10029                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10030            }
10031            if (info.numAnimationsRunning != 0) {
10032                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10033            }
10034            if (info.broadcastIntentAction != null) {
10035                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10036            }
10037            if (info.durationMillis != -1) {
10038                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10039            }
10040            if (info.numInstances != -1) {
10041                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10042            }
10043            if (info.tags != null) {
10044                for (String tag : info.tags) {
10045                    sb.append("Span-Tag: ").append(tag).append("\n");
10046                }
10047            }
10048            sb.append("\n");
10049            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10050                sb.append(info.crashInfo.stackTrace);
10051            }
10052            sb.append("\n");
10053
10054            // Only buffer up to ~64k.  Various logging bits truncate
10055            // things at 128k.
10056            needsFlush = (sb.length() > 64 * 1024);
10057        }
10058
10059        // Flush immediately if the buffer's grown too large, or this
10060        // is a non-system app.  Non-system apps are isolated with a
10061        // different tag & policy and not batched.
10062        //
10063        // Batching is useful during internal testing with
10064        // StrictMode settings turned up high.  Without batching,
10065        // thousands of separate files could be created on boot.
10066        if (!isSystemApp || needsFlush) {
10067            new Thread("Error dump: " + dropboxTag) {
10068                @Override
10069                public void run() {
10070                    String report;
10071                    synchronized (sb) {
10072                        report = sb.toString();
10073                        sb.delete(0, sb.length());
10074                        sb.trimToSize();
10075                    }
10076                    if (report.length() != 0) {
10077                        dbox.addText(dropboxTag, report);
10078                    }
10079                }
10080            }.start();
10081            return;
10082        }
10083
10084        // System app batching:
10085        if (!bufferWasEmpty) {
10086            // An existing dropbox-writing thread is outstanding, so
10087            // we don't need to start it up.  The existing thread will
10088            // catch the buffer appends we just did.
10089            return;
10090        }
10091
10092        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10093        // (After this point, we shouldn't access AMS internal data structures.)
10094        new Thread("Error dump: " + dropboxTag) {
10095            @Override
10096            public void run() {
10097                // 5 second sleep to let stacks arrive and be batched together
10098                try {
10099                    Thread.sleep(5000);  // 5 seconds
10100                } catch (InterruptedException e) {}
10101
10102                String errorReport;
10103                synchronized (mStrictModeBuffer) {
10104                    errorReport = mStrictModeBuffer.toString();
10105                    if (errorReport.length() == 0) {
10106                        return;
10107                    }
10108                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10109                    mStrictModeBuffer.trimToSize();
10110                }
10111                dbox.addText(dropboxTag, errorReport);
10112            }
10113        }.start();
10114    }
10115
10116    /**
10117     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10118     * @param app object of the crashing app, null for the system server
10119     * @param tag reported by the caller
10120     * @param crashInfo describing the context of the error
10121     * @return true if the process should exit immediately (WTF is fatal)
10122     */
10123    public boolean handleApplicationWtf(IBinder app, String tag,
10124            ApplicationErrorReport.CrashInfo crashInfo) {
10125        ProcessRecord r = findAppProcess(app, "WTF");
10126        final String processName = app == null ? "system_server"
10127                : (r == null ? "unknown" : r.processName);
10128
10129        EventLog.writeEvent(EventLogTags.AM_WTF,
10130                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10131                processName,
10132                r == null ? -1 : r.info.flags,
10133                tag, crashInfo.exceptionMessage);
10134
10135        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10136
10137        if (r != null && r.pid != Process.myPid() &&
10138                Settings.Global.getInt(mContext.getContentResolver(),
10139                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10140            crashApplication(r, crashInfo);
10141            return true;
10142        } else {
10143            return false;
10144        }
10145    }
10146
10147    /**
10148     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10149     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10150     */
10151    private ProcessRecord findAppProcess(IBinder app, String reason) {
10152        if (app == null) {
10153            return null;
10154        }
10155
10156        synchronized (this) {
10157            final int NP = mProcessNames.getMap().size();
10158            for (int ip=0; ip<NP; ip++) {
10159                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10160                final int NA = apps.size();
10161                for (int ia=0; ia<NA; ia++) {
10162                    ProcessRecord p = apps.valueAt(ia);
10163                    if (p.thread != null && p.thread.asBinder() == app) {
10164                        return p;
10165                    }
10166                }
10167            }
10168
10169            Slog.w(TAG, "Can't find mystery application for " + reason
10170                    + " from pid=" + Binder.getCallingPid()
10171                    + " uid=" + Binder.getCallingUid() + ": " + app);
10172            return null;
10173        }
10174    }
10175
10176    /**
10177     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10178     * to append various headers to the dropbox log text.
10179     */
10180    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10181            StringBuilder sb) {
10182        // Watchdog thread ends up invoking this function (with
10183        // a null ProcessRecord) to add the stack file to dropbox.
10184        // Do not acquire a lock on this (am) in such cases, as it
10185        // could cause a potential deadlock, if and when watchdog
10186        // is invoked due to unavailability of lock on am and it
10187        // would prevent watchdog from killing system_server.
10188        if (process == null) {
10189            sb.append("Process: ").append(processName).append("\n");
10190            return;
10191        }
10192        // Note: ProcessRecord 'process' is guarded by the service
10193        // instance.  (notably process.pkgList, which could otherwise change
10194        // concurrently during execution of this method)
10195        synchronized (this) {
10196            sb.append("Process: ").append(processName).append("\n");
10197            int flags = process.info.flags;
10198            IPackageManager pm = AppGlobals.getPackageManager();
10199            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10200            for (int ip=0; ip<process.pkgList.size(); ip++) {
10201                String pkg = process.pkgList.keyAt(ip);
10202                sb.append("Package: ").append(pkg);
10203                try {
10204                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10205                    if (pi != null) {
10206                        sb.append(" v").append(pi.versionCode);
10207                        if (pi.versionName != null) {
10208                            sb.append(" (").append(pi.versionName).append(")");
10209                        }
10210                    }
10211                } catch (RemoteException e) {
10212                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10213                }
10214                sb.append("\n");
10215            }
10216        }
10217    }
10218
10219    private static String processClass(ProcessRecord process) {
10220        if (process == null || process.pid == MY_PID) {
10221            return "system_server";
10222        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10223            return "system_app";
10224        } else {
10225            return "data_app";
10226        }
10227    }
10228
10229    /**
10230     * Write a description of an error (crash, WTF, ANR) to the drop box.
10231     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10232     * @param process which caused the error, null means the system server
10233     * @param activity which triggered the error, null if unknown
10234     * @param parent activity related to the error, null if unknown
10235     * @param subject line related to the error, null if absent
10236     * @param report in long form describing the error, null if absent
10237     * @param logFile to include in the report, null if none
10238     * @param crashInfo giving an application stack trace, null if absent
10239     */
10240    public void addErrorToDropBox(String eventType,
10241            ProcessRecord process, String processName, ActivityRecord activity,
10242            ActivityRecord parent, String subject,
10243            final String report, final File logFile,
10244            final ApplicationErrorReport.CrashInfo crashInfo) {
10245        // NOTE -- this must never acquire the ActivityManagerService lock,
10246        // otherwise the watchdog may be prevented from resetting the system.
10247
10248        final String dropboxTag = processClass(process) + "_" + eventType;
10249        final DropBoxManager dbox = (DropBoxManager)
10250                mContext.getSystemService(Context.DROPBOX_SERVICE);
10251
10252        // Exit early if the dropbox isn't configured to accept this report type.
10253        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10254
10255        final StringBuilder sb = new StringBuilder(1024);
10256        appendDropBoxProcessHeaders(process, processName, sb);
10257        if (activity != null) {
10258            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10259        }
10260        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10261            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10262        }
10263        if (parent != null && parent != activity) {
10264            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10265        }
10266        if (subject != null) {
10267            sb.append("Subject: ").append(subject).append("\n");
10268        }
10269        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10270        if (Debug.isDebuggerConnected()) {
10271            sb.append("Debugger: Connected\n");
10272        }
10273        sb.append("\n");
10274
10275        // Do the rest in a worker thread to avoid blocking the caller on I/O
10276        // (After this point, we shouldn't access AMS internal data structures.)
10277        Thread worker = new Thread("Error dump: " + dropboxTag) {
10278            @Override
10279            public void run() {
10280                if (report != null) {
10281                    sb.append(report);
10282                }
10283                if (logFile != null) {
10284                    try {
10285                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10286                                    "\n\n[[TRUNCATED]]"));
10287                    } catch (IOException e) {
10288                        Slog.e(TAG, "Error reading " + logFile, e);
10289                    }
10290                }
10291                if (crashInfo != null && crashInfo.stackTrace != null) {
10292                    sb.append(crashInfo.stackTrace);
10293                }
10294
10295                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10296                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10297                if (lines > 0) {
10298                    sb.append("\n");
10299
10300                    // Merge several logcat streams, and take the last N lines
10301                    InputStreamReader input = null;
10302                    try {
10303                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10304                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10305                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10306
10307                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10308                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10309                        input = new InputStreamReader(logcat.getInputStream());
10310
10311                        int num;
10312                        char[] buf = new char[8192];
10313                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10314                    } catch (IOException e) {
10315                        Slog.e(TAG, "Error running logcat", e);
10316                    } finally {
10317                        if (input != null) try { input.close(); } catch (IOException e) {}
10318                    }
10319                }
10320
10321                dbox.addText(dropboxTag, sb.toString());
10322            }
10323        };
10324
10325        if (process == null) {
10326            // If process is null, we are being called from some internal code
10327            // and may be about to die -- run this synchronously.
10328            worker.run();
10329        } else {
10330            worker.start();
10331        }
10332    }
10333
10334    /**
10335     * Bring up the "unexpected error" dialog box for a crashing app.
10336     * Deal with edge cases (intercepts from instrumented applications,
10337     * ActivityController, error intent receivers, that sort of thing).
10338     * @param r the application crashing
10339     * @param crashInfo describing the failure
10340     */
10341    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10342        long timeMillis = System.currentTimeMillis();
10343        String shortMsg = crashInfo.exceptionClassName;
10344        String longMsg = crashInfo.exceptionMessage;
10345        String stackTrace = crashInfo.stackTrace;
10346        if (shortMsg != null && longMsg != null) {
10347            longMsg = shortMsg + ": " + longMsg;
10348        } else if (shortMsg != null) {
10349            longMsg = shortMsg;
10350        }
10351
10352        AppErrorResult result = new AppErrorResult();
10353        synchronized (this) {
10354            if (mController != null) {
10355                try {
10356                    String name = r != null ? r.processName : null;
10357                    int pid = r != null ? r.pid : Binder.getCallingPid();
10358                    if (!mController.appCrashed(name, pid,
10359                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10360                        Slog.w(TAG, "Force-killing crashed app " + name
10361                                + " at watcher's request");
10362                        Process.killProcess(pid);
10363                        return;
10364                    }
10365                } catch (RemoteException e) {
10366                    mController = null;
10367                    Watchdog.getInstance().setActivityController(null);
10368                }
10369            }
10370
10371            final long origId = Binder.clearCallingIdentity();
10372
10373            // If this process is running instrumentation, finish it.
10374            if (r != null && r.instrumentationClass != null) {
10375                Slog.w(TAG, "Error in app " + r.processName
10376                      + " running instrumentation " + r.instrumentationClass + ":");
10377                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10378                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10379                Bundle info = new Bundle();
10380                info.putString("shortMsg", shortMsg);
10381                info.putString("longMsg", longMsg);
10382                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10383                Binder.restoreCallingIdentity(origId);
10384                return;
10385            }
10386
10387            // If we can't identify the process or it's already exceeded its crash quota,
10388            // quit right away without showing a crash dialog.
10389            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10390                Binder.restoreCallingIdentity(origId);
10391                return;
10392            }
10393
10394            Message msg = Message.obtain();
10395            msg.what = SHOW_ERROR_MSG;
10396            HashMap data = new HashMap();
10397            data.put("result", result);
10398            data.put("app", r);
10399            msg.obj = data;
10400            mHandler.sendMessage(msg);
10401
10402            Binder.restoreCallingIdentity(origId);
10403        }
10404
10405        int res = result.get();
10406
10407        Intent appErrorIntent = null;
10408        synchronized (this) {
10409            if (r != null && !r.isolated) {
10410                // XXX Can't keep track of crash time for isolated processes,
10411                // since they don't have a persistent identity.
10412                mProcessCrashTimes.put(r.info.processName, r.uid,
10413                        SystemClock.uptimeMillis());
10414            }
10415            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10416                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10417            }
10418        }
10419
10420        if (appErrorIntent != null) {
10421            try {
10422                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10423            } catch (ActivityNotFoundException e) {
10424                Slog.w(TAG, "bug report receiver dissappeared", e);
10425            }
10426        }
10427    }
10428
10429    Intent createAppErrorIntentLocked(ProcessRecord r,
10430            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10431        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10432        if (report == null) {
10433            return null;
10434        }
10435        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10436        result.setComponent(r.errorReportReceiver);
10437        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10438        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10439        return result;
10440    }
10441
10442    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10443            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10444        if (r.errorReportReceiver == null) {
10445            return null;
10446        }
10447
10448        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10449            return null;
10450        }
10451
10452        ApplicationErrorReport report = new ApplicationErrorReport();
10453        report.packageName = r.info.packageName;
10454        report.installerPackageName = r.errorReportReceiver.getPackageName();
10455        report.processName = r.processName;
10456        report.time = timeMillis;
10457        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10458
10459        if (r.crashing || r.forceCrashReport) {
10460            report.type = ApplicationErrorReport.TYPE_CRASH;
10461            report.crashInfo = crashInfo;
10462        } else if (r.notResponding) {
10463            report.type = ApplicationErrorReport.TYPE_ANR;
10464            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10465
10466            report.anrInfo.activity = r.notRespondingReport.tag;
10467            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10468            report.anrInfo.info = r.notRespondingReport.longMsg;
10469        }
10470
10471        return report;
10472    }
10473
10474    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10475        enforceNotIsolatedCaller("getProcessesInErrorState");
10476        // assume our apps are happy - lazy create the list
10477        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10478
10479        final boolean allUsers = ActivityManager.checkUidPermission(
10480                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10481                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10482        int userId = UserHandle.getUserId(Binder.getCallingUid());
10483
10484        synchronized (this) {
10485
10486            // iterate across all processes
10487            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10488                ProcessRecord app = mLruProcesses.get(i);
10489                if (!allUsers && app.userId != userId) {
10490                    continue;
10491                }
10492                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10493                    // This one's in trouble, so we'll generate a report for it
10494                    // crashes are higher priority (in case there's a crash *and* an anr)
10495                    ActivityManager.ProcessErrorStateInfo report = null;
10496                    if (app.crashing) {
10497                        report = app.crashingReport;
10498                    } else if (app.notResponding) {
10499                        report = app.notRespondingReport;
10500                    }
10501
10502                    if (report != null) {
10503                        if (errList == null) {
10504                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10505                        }
10506                        errList.add(report);
10507                    } else {
10508                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10509                                " crashing = " + app.crashing +
10510                                " notResponding = " + app.notResponding);
10511                    }
10512                }
10513            }
10514        }
10515
10516        return errList;
10517    }
10518
10519    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10520        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10521            if (currApp != null) {
10522                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10523            }
10524            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10525        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10526            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10527        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10528            if (currApp != null) {
10529                currApp.lru = 0;
10530            }
10531            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10532        } else if (adj >= ProcessList.SERVICE_ADJ) {
10533            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10534        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10535            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10536        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10537            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10538        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10539            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10540        } else {
10541            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10542        }
10543    }
10544
10545    private void fillInProcMemInfo(ProcessRecord app,
10546            ActivityManager.RunningAppProcessInfo outInfo) {
10547        outInfo.pid = app.pid;
10548        outInfo.uid = app.info.uid;
10549        if (mHeavyWeightProcess == app) {
10550            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10551        }
10552        if (app.persistent) {
10553            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10554        }
10555        if (app.activities.size() > 0) {
10556            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10557        }
10558        outInfo.lastTrimLevel = app.trimMemoryLevel;
10559        int adj = app.curAdj;
10560        outInfo.importance = oomAdjToImportance(adj, outInfo);
10561        outInfo.importanceReasonCode = app.adjTypeCode;
10562        outInfo.processState = app.curProcState;
10563    }
10564
10565    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10566        enforceNotIsolatedCaller("getRunningAppProcesses");
10567        // Lazy instantiation of list
10568        List<ActivityManager.RunningAppProcessInfo> runList = null;
10569        final boolean allUsers = ActivityManager.checkUidPermission(
10570                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10571                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10572        int userId = UserHandle.getUserId(Binder.getCallingUid());
10573        synchronized (this) {
10574            // Iterate across all processes
10575            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10576                ProcessRecord app = mLruProcesses.get(i);
10577                if (!allUsers && app.userId != userId) {
10578                    continue;
10579                }
10580                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10581                    // Generate process state info for running application
10582                    ActivityManager.RunningAppProcessInfo currApp =
10583                        new ActivityManager.RunningAppProcessInfo(app.processName,
10584                                app.pid, app.getPackageList());
10585                    fillInProcMemInfo(app, currApp);
10586                    if (app.adjSource instanceof ProcessRecord) {
10587                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10588                        currApp.importanceReasonImportance = oomAdjToImportance(
10589                                app.adjSourceOom, null);
10590                    } else if (app.adjSource instanceof ActivityRecord) {
10591                        ActivityRecord r = (ActivityRecord)app.adjSource;
10592                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10593                    }
10594                    if (app.adjTarget instanceof ComponentName) {
10595                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10596                    }
10597                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10598                    //        + " lru=" + currApp.lru);
10599                    if (runList == null) {
10600                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10601                    }
10602                    runList.add(currApp);
10603                }
10604            }
10605        }
10606        return runList;
10607    }
10608
10609    public List<ApplicationInfo> getRunningExternalApplications() {
10610        enforceNotIsolatedCaller("getRunningExternalApplications");
10611        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10612        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10613        if (runningApps != null && runningApps.size() > 0) {
10614            Set<String> extList = new HashSet<String>();
10615            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10616                if (app.pkgList != null) {
10617                    for (String pkg : app.pkgList) {
10618                        extList.add(pkg);
10619                    }
10620                }
10621            }
10622            IPackageManager pm = AppGlobals.getPackageManager();
10623            for (String pkg : extList) {
10624                try {
10625                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10626                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10627                        retList.add(info);
10628                    }
10629                } catch (RemoteException e) {
10630                }
10631            }
10632        }
10633        return retList;
10634    }
10635
10636    @Override
10637    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10638        enforceNotIsolatedCaller("getMyMemoryState");
10639        synchronized (this) {
10640            ProcessRecord proc;
10641            synchronized (mPidsSelfLocked) {
10642                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10643            }
10644            fillInProcMemInfo(proc, outInfo);
10645        }
10646    }
10647
10648    @Override
10649    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10650        if (checkCallingPermission(android.Manifest.permission.DUMP)
10651                != PackageManager.PERMISSION_GRANTED) {
10652            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10653                    + Binder.getCallingPid()
10654                    + ", uid=" + Binder.getCallingUid()
10655                    + " without permission "
10656                    + android.Manifest.permission.DUMP);
10657            return;
10658        }
10659
10660        boolean dumpAll = false;
10661        boolean dumpClient = false;
10662        String dumpPackage = null;
10663
10664        int opti = 0;
10665        while (opti < args.length) {
10666            String opt = args[opti];
10667            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10668                break;
10669            }
10670            opti++;
10671            if ("-a".equals(opt)) {
10672                dumpAll = true;
10673            } else if ("-c".equals(opt)) {
10674                dumpClient = true;
10675            } else if ("-h".equals(opt)) {
10676                pw.println("Activity manager dump options:");
10677                pw.println("  [-a] [-c] [-h] [cmd] ...");
10678                pw.println("  cmd may be one of:");
10679                pw.println("    a[ctivities]: activity stack state");
10680                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10681                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10682                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10683                pw.println("    o[om]: out of memory management");
10684                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10685                pw.println("    provider [COMP_SPEC]: provider client-side state");
10686                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10687                pw.println("    service [COMP_SPEC]: service client-side state");
10688                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10689                pw.println("    all: dump all activities");
10690                pw.println("    top: dump the top activity");
10691                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10692                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10693                pw.println("    a partial substring in a component name, a");
10694                pw.println("    hex object identifier.");
10695                pw.println("  -a: include all available server state.");
10696                pw.println("  -c: include client state.");
10697                return;
10698            } else {
10699                pw.println("Unknown argument: " + opt + "; use -h for help");
10700            }
10701        }
10702
10703        long origId = Binder.clearCallingIdentity();
10704        boolean more = false;
10705        // Is the caller requesting to dump a particular piece of data?
10706        if (opti < args.length) {
10707            String cmd = args[opti];
10708            opti++;
10709            if ("activities".equals(cmd) || "a".equals(cmd)) {
10710                synchronized (this) {
10711                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10712                }
10713            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10714                String[] newArgs;
10715                String name;
10716                if (opti >= args.length) {
10717                    name = null;
10718                    newArgs = EMPTY_STRING_ARRAY;
10719                } else {
10720                    name = args[opti];
10721                    opti++;
10722                    newArgs = new String[args.length - opti];
10723                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10724                            args.length - opti);
10725                }
10726                synchronized (this) {
10727                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10728                }
10729            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10730                String[] newArgs;
10731                String name;
10732                if (opti >= args.length) {
10733                    name = null;
10734                    newArgs = EMPTY_STRING_ARRAY;
10735                } else {
10736                    name = args[opti];
10737                    opti++;
10738                    newArgs = new String[args.length - opti];
10739                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10740                            args.length - opti);
10741                }
10742                synchronized (this) {
10743                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10744                }
10745            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10746                String[] newArgs;
10747                String name;
10748                if (opti >= args.length) {
10749                    name = null;
10750                    newArgs = EMPTY_STRING_ARRAY;
10751                } else {
10752                    name = args[opti];
10753                    opti++;
10754                    newArgs = new String[args.length - opti];
10755                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10756                            args.length - opti);
10757                }
10758                synchronized (this) {
10759                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10760                }
10761            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10762                synchronized (this) {
10763                    dumpOomLocked(fd, pw, args, opti, true);
10764                }
10765            } else if ("provider".equals(cmd)) {
10766                String[] newArgs;
10767                String name;
10768                if (opti >= args.length) {
10769                    name = null;
10770                    newArgs = EMPTY_STRING_ARRAY;
10771                } else {
10772                    name = args[opti];
10773                    opti++;
10774                    newArgs = new String[args.length - opti];
10775                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10776                }
10777                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10778                    pw.println("No providers match: " + name);
10779                    pw.println("Use -h for help.");
10780                }
10781            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10782                synchronized (this) {
10783                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10784                }
10785            } else if ("service".equals(cmd)) {
10786                String[] newArgs;
10787                String name;
10788                if (opti >= args.length) {
10789                    name = null;
10790                    newArgs = EMPTY_STRING_ARRAY;
10791                } else {
10792                    name = args[opti];
10793                    opti++;
10794                    newArgs = new String[args.length - opti];
10795                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10796                            args.length - opti);
10797                }
10798                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10799                    pw.println("No services match: " + name);
10800                    pw.println("Use -h for help.");
10801                }
10802            } else if ("package".equals(cmd)) {
10803                String[] newArgs;
10804                if (opti >= args.length) {
10805                    pw.println("package: no package name specified");
10806                    pw.println("Use -h for help.");
10807                } else {
10808                    dumpPackage = args[opti];
10809                    opti++;
10810                    newArgs = new String[args.length - opti];
10811                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10812                            args.length - opti);
10813                    args = newArgs;
10814                    opti = 0;
10815                    more = true;
10816                }
10817            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10818                synchronized (this) {
10819                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10820                }
10821            } else {
10822                // Dumping a single activity?
10823                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10824                    pw.println("Bad activity command, or no activities match: " + cmd);
10825                    pw.println("Use -h for help.");
10826                }
10827            }
10828            if (!more) {
10829                Binder.restoreCallingIdentity(origId);
10830                return;
10831            }
10832        }
10833
10834        // No piece of data specified, dump everything.
10835        synchronized (this) {
10836            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10837            pw.println();
10838            if (dumpAll) {
10839                pw.println("-------------------------------------------------------------------------------");
10840            }
10841            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10842            pw.println();
10843            if (dumpAll) {
10844                pw.println("-------------------------------------------------------------------------------");
10845            }
10846            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10847            pw.println();
10848            if (dumpAll) {
10849                pw.println("-------------------------------------------------------------------------------");
10850            }
10851            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10852            pw.println();
10853            if (dumpAll) {
10854                pw.println("-------------------------------------------------------------------------------");
10855            }
10856            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10857            pw.println();
10858            if (dumpAll) {
10859                pw.println("-------------------------------------------------------------------------------");
10860            }
10861            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10862        }
10863        Binder.restoreCallingIdentity(origId);
10864    }
10865
10866    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10867            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10868        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10869
10870        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10871                dumpPackage);
10872        boolean needSep = printedAnything;
10873
10874        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10875                dumpPackage, needSep, "  mFocusedActivity: ");
10876        if (printed) {
10877            printedAnything = true;
10878            needSep = false;
10879        }
10880
10881        if (dumpPackage == null) {
10882            if (needSep) {
10883                pw.println();
10884            }
10885            needSep = true;
10886            printedAnything = true;
10887            mStackSupervisor.dump(pw, "  ");
10888        }
10889
10890        if (mRecentTasks.size() > 0) {
10891            boolean printedHeader = false;
10892
10893            final int N = mRecentTasks.size();
10894            for (int i=0; i<N; i++) {
10895                TaskRecord tr = mRecentTasks.get(i);
10896                if (dumpPackage != null) {
10897                    if (tr.realActivity == null ||
10898                            !dumpPackage.equals(tr.realActivity)) {
10899                        continue;
10900                    }
10901                }
10902                if (!printedHeader) {
10903                    if (needSep) {
10904                        pw.println();
10905                    }
10906                    pw.println("  Recent tasks:");
10907                    printedHeader = true;
10908                    printedAnything = true;
10909                }
10910                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10911                        pw.println(tr);
10912                if (dumpAll) {
10913                    mRecentTasks.get(i).dump(pw, "    ");
10914                }
10915            }
10916        }
10917
10918        if (!printedAnything) {
10919            pw.println("  (nothing)");
10920        }
10921    }
10922
10923    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10924            int opti, boolean dumpAll, String dumpPackage) {
10925        boolean needSep = false;
10926        boolean printedAnything = false;
10927        int numPers = 0;
10928
10929        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
10930
10931        if (dumpAll) {
10932            final int NP = mProcessNames.getMap().size();
10933            for (int ip=0; ip<NP; ip++) {
10934                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
10935                final int NA = procs.size();
10936                for (int ia=0; ia<NA; ia++) {
10937                    ProcessRecord r = procs.valueAt(ia);
10938                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10939                        continue;
10940                    }
10941                    if (!needSep) {
10942                        pw.println("  All known processes:");
10943                        needSep = true;
10944                        printedAnything = true;
10945                    }
10946                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
10947                        pw.print(" UID "); pw.print(procs.keyAt(ia));
10948                        pw.print(" "); pw.println(r);
10949                    r.dump(pw, "    ");
10950                    if (r.persistent) {
10951                        numPers++;
10952                    }
10953                }
10954            }
10955        }
10956
10957        if (mIsolatedProcesses.size() > 0) {
10958            boolean printed = false;
10959            for (int i=0; i<mIsolatedProcesses.size(); i++) {
10960                ProcessRecord r = mIsolatedProcesses.valueAt(i);
10961                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10962                    continue;
10963                }
10964                if (!printed) {
10965                    if (needSep) {
10966                        pw.println();
10967                    }
10968                    pw.println("  Isolated process list (sorted by uid):");
10969                    printedAnything = true;
10970                    printed = true;
10971                    needSep = true;
10972                }
10973                pw.println(String.format("%sIsolated #%2d: %s",
10974                        "    ", i, r.toString()));
10975            }
10976        }
10977
10978        if (mLruProcesses.size() > 0) {
10979            if (needSep) {
10980                pw.println();
10981            }
10982            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
10983                    pw.print(" total, non-act at ");
10984                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10985                    pw.print(", non-svc at ");
10986                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10987                    pw.println("):");
10988            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
10989            needSep = true;
10990            printedAnything = true;
10991        }
10992
10993        if (dumpAll || dumpPackage != null) {
10994            synchronized (mPidsSelfLocked) {
10995                boolean printed = false;
10996                for (int i=0; i<mPidsSelfLocked.size(); i++) {
10997                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
10998                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10999                        continue;
11000                    }
11001                    if (!printed) {
11002                        if (needSep) pw.println();
11003                        needSep = true;
11004                        pw.println("  PID mappings:");
11005                        printed = true;
11006                        printedAnything = true;
11007                    }
11008                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11009                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11010                }
11011            }
11012        }
11013
11014        if (mForegroundProcesses.size() > 0) {
11015            synchronized (mPidsSelfLocked) {
11016                boolean printed = false;
11017                for (int i=0; i<mForegroundProcesses.size(); i++) {
11018                    ProcessRecord r = mPidsSelfLocked.get(
11019                            mForegroundProcesses.valueAt(i).pid);
11020                    if (dumpPackage != null && (r == null
11021                            || !r.pkgList.containsKey(dumpPackage))) {
11022                        continue;
11023                    }
11024                    if (!printed) {
11025                        if (needSep) pw.println();
11026                        needSep = true;
11027                        pw.println("  Foreground Processes:");
11028                        printed = true;
11029                        printedAnything = true;
11030                    }
11031                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11032                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11033                }
11034            }
11035        }
11036
11037        if (mPersistentStartingProcesses.size() > 0) {
11038            if (needSep) pw.println();
11039            needSep = true;
11040            printedAnything = true;
11041            pw.println("  Persisent processes that are starting:");
11042            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11043                    "Starting Norm", "Restarting PERS", dumpPackage);
11044        }
11045
11046        if (mRemovedProcesses.size() > 0) {
11047            if (needSep) pw.println();
11048            needSep = true;
11049            printedAnything = true;
11050            pw.println("  Processes that are being removed:");
11051            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11052                    "Removed Norm", "Removed PERS", dumpPackage);
11053        }
11054
11055        if (mProcessesOnHold.size() > 0) {
11056            if (needSep) pw.println();
11057            needSep = true;
11058            printedAnything = true;
11059            pw.println("  Processes that are on old until the system is ready:");
11060            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11061                    "OnHold Norm", "OnHold PERS", dumpPackage);
11062        }
11063
11064        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11065
11066        if (mProcessCrashTimes.getMap().size() > 0) {
11067            boolean printed = false;
11068            long now = SystemClock.uptimeMillis();
11069            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11070            final int NP = pmap.size();
11071            for (int ip=0; ip<NP; ip++) {
11072                String pname = pmap.keyAt(ip);
11073                SparseArray<Long> uids = pmap.valueAt(ip);
11074                final int N = uids.size();
11075                for (int i=0; i<N; i++) {
11076                    int puid = uids.keyAt(i);
11077                    ProcessRecord r = mProcessNames.get(pname, puid);
11078                    if (dumpPackage != null && (r == null
11079                            || !r.pkgList.containsKey(dumpPackage))) {
11080                        continue;
11081                    }
11082                    if (!printed) {
11083                        if (needSep) pw.println();
11084                        needSep = true;
11085                        pw.println("  Time since processes crashed:");
11086                        printed = true;
11087                        printedAnything = true;
11088                    }
11089                    pw.print("    Process "); pw.print(pname);
11090                            pw.print(" uid "); pw.print(puid);
11091                            pw.print(": last crashed ");
11092                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11093                            pw.println(" ago");
11094                }
11095            }
11096        }
11097
11098        if (mBadProcesses.getMap().size() > 0) {
11099            boolean printed = false;
11100            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11101            final int NP = pmap.size();
11102            for (int ip=0; ip<NP; ip++) {
11103                String pname = pmap.keyAt(ip);
11104                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11105                final int N = uids.size();
11106                for (int i=0; i<N; i++) {
11107                    int puid = uids.keyAt(i);
11108                    ProcessRecord r = mProcessNames.get(pname, puid);
11109                    if (dumpPackage != null && (r == null
11110                            || !r.pkgList.containsKey(dumpPackage))) {
11111                        continue;
11112                    }
11113                    if (!printed) {
11114                        if (needSep) pw.println();
11115                        needSep = true;
11116                        pw.println("  Bad processes:");
11117                        printedAnything = true;
11118                    }
11119                    BadProcessInfo info = uids.valueAt(i);
11120                    pw.print("    Bad process "); pw.print(pname);
11121                            pw.print(" uid "); pw.print(puid);
11122                            pw.print(": crashed at time "); pw.println(info.time);
11123                    if (info.shortMsg != null) {
11124                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11125                    }
11126                    if (info.longMsg != null) {
11127                        pw.print("      Long msg: "); pw.println(info.longMsg);
11128                    }
11129                    if (info.stack != null) {
11130                        pw.println("      Stack:");
11131                        int lastPos = 0;
11132                        for (int pos=0; pos<info.stack.length(); pos++) {
11133                            if (info.stack.charAt(pos) == '\n') {
11134                                pw.print("        ");
11135                                pw.write(info.stack, lastPos, pos-lastPos);
11136                                pw.println();
11137                                lastPos = pos+1;
11138                            }
11139                        }
11140                        if (lastPos < info.stack.length()) {
11141                            pw.print("        ");
11142                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11143                            pw.println();
11144                        }
11145                    }
11146                }
11147            }
11148        }
11149
11150        if (dumpPackage == null) {
11151            pw.println();
11152            needSep = false;
11153            pw.println("  mStartedUsers:");
11154            for (int i=0; i<mStartedUsers.size(); i++) {
11155                UserStartedState uss = mStartedUsers.valueAt(i);
11156                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11157                        pw.print(": "); uss.dump("", pw);
11158            }
11159            pw.print("  mStartedUserArray: [");
11160            for (int i=0; i<mStartedUserArray.length; i++) {
11161                if (i > 0) pw.print(", ");
11162                pw.print(mStartedUserArray[i]);
11163            }
11164            pw.println("]");
11165            pw.print("  mUserLru: [");
11166            for (int i=0; i<mUserLru.size(); i++) {
11167                if (i > 0) pw.print(", ");
11168                pw.print(mUserLru.get(i));
11169            }
11170            pw.println("]");
11171            if (dumpAll) {
11172                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11173            }
11174        }
11175        if (mHomeProcess != null && (dumpPackage == null
11176                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11177            if (needSep) {
11178                pw.println();
11179                needSep = false;
11180            }
11181            pw.println("  mHomeProcess: " + mHomeProcess);
11182        }
11183        if (mPreviousProcess != null && (dumpPackage == null
11184                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11185            if (needSep) {
11186                pw.println();
11187                needSep = false;
11188            }
11189            pw.println("  mPreviousProcess: " + mPreviousProcess);
11190        }
11191        if (dumpAll) {
11192            StringBuilder sb = new StringBuilder(128);
11193            sb.append("  mPreviousProcessVisibleTime: ");
11194            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11195            pw.println(sb);
11196        }
11197        if (mHeavyWeightProcess != null && (dumpPackage == null
11198                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11199            if (needSep) {
11200                pw.println();
11201                needSep = false;
11202            }
11203            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11204        }
11205        if (dumpPackage == null) {
11206            pw.println("  mConfiguration: " + mConfiguration);
11207        }
11208        if (dumpAll) {
11209            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11210            if (mCompatModePackages.getPackages().size() > 0) {
11211                boolean printed = false;
11212                for (Map.Entry<String, Integer> entry
11213                        : mCompatModePackages.getPackages().entrySet()) {
11214                    String pkg = entry.getKey();
11215                    int mode = entry.getValue();
11216                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11217                        continue;
11218                    }
11219                    if (!printed) {
11220                        pw.println("  mScreenCompatPackages:");
11221                        printed = true;
11222                    }
11223                    pw.print("    "); pw.print(pkg); pw.print(": ");
11224                            pw.print(mode); pw.println();
11225                }
11226            }
11227        }
11228        if (dumpPackage == null) {
11229            if (mSleeping || mWentToSleep || mLockScreenShown) {
11230                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11231                        + " mLockScreenShown " + mLockScreenShown);
11232            }
11233            if (mShuttingDown || mRunningVoice) {
11234                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11235            }
11236        }
11237        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11238                || mOrigWaitForDebugger) {
11239            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11240                    || dumpPackage.equals(mOrigDebugApp)) {
11241                if (needSep) {
11242                    pw.println();
11243                    needSep = false;
11244                }
11245                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11246                        + " mDebugTransient=" + mDebugTransient
11247                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11248            }
11249        }
11250        if (mOpenGlTraceApp != null) {
11251            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11252                if (needSep) {
11253                    pw.println();
11254                    needSep = false;
11255                }
11256                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11257            }
11258        }
11259        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11260                || mProfileFd != null) {
11261            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11262                if (needSep) {
11263                    pw.println();
11264                    needSep = false;
11265                }
11266                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11267                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11268                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11269                        + mAutoStopProfiler);
11270            }
11271        }
11272        if (dumpPackage == null) {
11273            if (mAlwaysFinishActivities || mController != null) {
11274                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11275                        + " mController=" + mController);
11276            }
11277            if (dumpAll) {
11278                pw.println("  Total persistent processes: " + numPers);
11279                pw.println("  mProcessesReady=" + mProcessesReady
11280                        + " mSystemReady=" + mSystemReady);
11281                pw.println("  mBooting=" + mBooting
11282                        + " mBooted=" + mBooted
11283                        + " mFactoryTest=" + mFactoryTest);
11284                pw.print("  mLastPowerCheckRealtime=");
11285                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11286                        pw.println("");
11287                pw.print("  mLastPowerCheckUptime=");
11288                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11289                        pw.println("");
11290                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11291                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11292                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11293                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11294                        + " (" + mLruProcesses.size() + " total)"
11295                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11296                        + " mNumServiceProcs=" + mNumServiceProcs
11297                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11298                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11299                        + " mLastMemoryLevel" + mLastMemoryLevel
11300                        + " mLastNumProcesses" + mLastNumProcesses);
11301                long now = SystemClock.uptimeMillis();
11302                pw.print("  mLastIdleTime=");
11303                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11304                        pw.print(" mLowRamSinceLastIdle=");
11305                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11306                        pw.println();
11307            }
11308        }
11309
11310        if (!printedAnything) {
11311            pw.println("  (nothing)");
11312        }
11313    }
11314
11315    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11316            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11317        if (mProcessesToGc.size() > 0) {
11318            boolean printed = false;
11319            long now = SystemClock.uptimeMillis();
11320            for (int i=0; i<mProcessesToGc.size(); i++) {
11321                ProcessRecord proc = mProcessesToGc.get(i);
11322                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11323                    continue;
11324                }
11325                if (!printed) {
11326                    if (needSep) pw.println();
11327                    needSep = true;
11328                    pw.println("  Processes that are waiting to GC:");
11329                    printed = true;
11330                }
11331                pw.print("    Process "); pw.println(proc);
11332                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11333                        pw.print(", last gced=");
11334                        pw.print(now-proc.lastRequestedGc);
11335                        pw.print(" ms ago, last lowMem=");
11336                        pw.print(now-proc.lastLowMemory);
11337                        pw.println(" ms ago");
11338
11339            }
11340        }
11341        return needSep;
11342    }
11343
11344    void printOomLevel(PrintWriter pw, String name, int adj) {
11345        pw.print("    ");
11346        if (adj >= 0) {
11347            pw.print(' ');
11348            if (adj < 10) pw.print(' ');
11349        } else {
11350            if (adj > -10) pw.print(' ');
11351        }
11352        pw.print(adj);
11353        pw.print(": ");
11354        pw.print(name);
11355        pw.print(" (");
11356        pw.print(mProcessList.getMemLevel(adj)/1024);
11357        pw.println(" kB)");
11358    }
11359
11360    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11361            int opti, boolean dumpAll) {
11362        boolean needSep = false;
11363
11364        if (mLruProcesses.size() > 0) {
11365            if (needSep) pw.println();
11366            needSep = true;
11367            pw.println("  OOM levels:");
11368            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11369            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11370            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11371            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11372            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11373            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11374            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11375            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11376            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11377            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11378            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11379            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11380            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11381
11382            if (needSep) pw.println();
11383            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11384                    pw.print(" total, non-act at ");
11385                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11386                    pw.print(", non-svc at ");
11387                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11388                    pw.println("):");
11389            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11390            needSep = true;
11391        }
11392
11393        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11394
11395        pw.println();
11396        pw.println("  mHomeProcess: " + mHomeProcess);
11397        pw.println("  mPreviousProcess: " + mPreviousProcess);
11398        if (mHeavyWeightProcess != null) {
11399            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11400        }
11401
11402        return true;
11403    }
11404
11405    /**
11406     * There are three ways to call this:
11407     *  - no provider specified: dump all the providers
11408     *  - a flattened component name that matched an existing provider was specified as the
11409     *    first arg: dump that one provider
11410     *  - the first arg isn't the flattened component name of an existing provider:
11411     *    dump all providers whose component contains the first arg as a substring
11412     */
11413    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11414            int opti, boolean dumpAll) {
11415        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11416    }
11417
11418    static class ItemMatcher {
11419        ArrayList<ComponentName> components;
11420        ArrayList<String> strings;
11421        ArrayList<Integer> objects;
11422        boolean all;
11423
11424        ItemMatcher() {
11425            all = true;
11426        }
11427
11428        void build(String name) {
11429            ComponentName componentName = ComponentName.unflattenFromString(name);
11430            if (componentName != null) {
11431                if (components == null) {
11432                    components = new ArrayList<ComponentName>();
11433                }
11434                components.add(componentName);
11435                all = false;
11436            } else {
11437                int objectId = 0;
11438                // Not a '/' separated full component name; maybe an object ID?
11439                try {
11440                    objectId = Integer.parseInt(name, 16);
11441                    if (objects == null) {
11442                        objects = new ArrayList<Integer>();
11443                    }
11444                    objects.add(objectId);
11445                    all = false;
11446                } catch (RuntimeException e) {
11447                    // Not an integer; just do string match.
11448                    if (strings == null) {
11449                        strings = new ArrayList<String>();
11450                    }
11451                    strings.add(name);
11452                    all = false;
11453                }
11454            }
11455        }
11456
11457        int build(String[] args, int opti) {
11458            for (; opti<args.length; opti++) {
11459                String name = args[opti];
11460                if ("--".equals(name)) {
11461                    return opti+1;
11462                }
11463                build(name);
11464            }
11465            return opti;
11466        }
11467
11468        boolean match(Object object, ComponentName comp) {
11469            if (all) {
11470                return true;
11471            }
11472            if (components != null) {
11473                for (int i=0; i<components.size(); i++) {
11474                    if (components.get(i).equals(comp)) {
11475                        return true;
11476                    }
11477                }
11478            }
11479            if (objects != null) {
11480                for (int i=0; i<objects.size(); i++) {
11481                    if (System.identityHashCode(object) == objects.get(i)) {
11482                        return true;
11483                    }
11484                }
11485            }
11486            if (strings != null) {
11487                String flat = comp.flattenToString();
11488                for (int i=0; i<strings.size(); i++) {
11489                    if (flat.contains(strings.get(i))) {
11490                        return true;
11491                    }
11492                }
11493            }
11494            return false;
11495        }
11496    }
11497
11498    /**
11499     * There are three things that cmd can be:
11500     *  - a flattened component name that matches an existing activity
11501     *  - the cmd arg isn't the flattened component name of an existing activity:
11502     *    dump all activity whose component contains the cmd as a substring
11503     *  - A hex number of the ActivityRecord object instance.
11504     */
11505    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11506            int opti, boolean dumpAll) {
11507        ArrayList<ActivityRecord> activities;
11508
11509        synchronized (this) {
11510            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11511        }
11512
11513        if (activities.size() <= 0) {
11514            return false;
11515        }
11516
11517        String[] newArgs = new String[args.length - opti];
11518        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11519
11520        TaskRecord lastTask = null;
11521        boolean needSep = false;
11522        for (int i=activities.size()-1; i>=0; i--) {
11523            ActivityRecord r = activities.get(i);
11524            if (needSep) {
11525                pw.println();
11526            }
11527            needSep = true;
11528            synchronized (this) {
11529                if (lastTask != r.task) {
11530                    lastTask = r.task;
11531                    pw.print("TASK "); pw.print(lastTask.affinity);
11532                            pw.print(" id="); pw.println(lastTask.taskId);
11533                    if (dumpAll) {
11534                        lastTask.dump(pw, "  ");
11535                    }
11536                }
11537            }
11538            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11539        }
11540        return true;
11541    }
11542
11543    /**
11544     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11545     * there is a thread associated with the activity.
11546     */
11547    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11548            final ActivityRecord r, String[] args, boolean dumpAll) {
11549        String innerPrefix = prefix + "  ";
11550        synchronized (this) {
11551            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11552                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11553                    pw.print(" pid=");
11554                    if (r.app != null) pw.println(r.app.pid);
11555                    else pw.println("(not running)");
11556            if (dumpAll) {
11557                r.dump(pw, innerPrefix);
11558            }
11559        }
11560        if (r.app != null && r.app.thread != null) {
11561            // flush anything that is already in the PrintWriter since the thread is going
11562            // to write to the file descriptor directly
11563            pw.flush();
11564            try {
11565                TransferPipe tp = new TransferPipe();
11566                try {
11567                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11568                            r.appToken, innerPrefix, args);
11569                    tp.go(fd);
11570                } finally {
11571                    tp.kill();
11572                }
11573            } catch (IOException e) {
11574                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11575            } catch (RemoteException e) {
11576                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11577            }
11578        }
11579    }
11580
11581    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11582            int opti, boolean dumpAll, String dumpPackage) {
11583        boolean needSep = false;
11584        boolean onlyHistory = false;
11585        boolean printedAnything = false;
11586
11587        if ("history".equals(dumpPackage)) {
11588            if (opti < args.length && "-s".equals(args[opti])) {
11589                dumpAll = false;
11590            }
11591            onlyHistory = true;
11592            dumpPackage = null;
11593        }
11594
11595        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11596        if (!onlyHistory && dumpAll) {
11597            if (mRegisteredReceivers.size() > 0) {
11598                boolean printed = false;
11599                Iterator it = mRegisteredReceivers.values().iterator();
11600                while (it.hasNext()) {
11601                    ReceiverList r = (ReceiverList)it.next();
11602                    if (dumpPackage != null && (r.app == null ||
11603                            !dumpPackage.equals(r.app.info.packageName))) {
11604                        continue;
11605                    }
11606                    if (!printed) {
11607                        pw.println("  Registered Receivers:");
11608                        needSep = true;
11609                        printed = true;
11610                        printedAnything = true;
11611                    }
11612                    pw.print("  * "); pw.println(r);
11613                    r.dump(pw, "    ");
11614                }
11615            }
11616
11617            if (mReceiverResolver.dump(pw, needSep ?
11618                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11619                    "    ", dumpPackage, false)) {
11620                needSep = true;
11621                printedAnything = true;
11622            }
11623        }
11624
11625        for (BroadcastQueue q : mBroadcastQueues) {
11626            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11627            printedAnything |= needSep;
11628        }
11629
11630        needSep = true;
11631
11632        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11633            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11634                if (needSep) {
11635                    pw.println();
11636                }
11637                needSep = true;
11638                printedAnything = true;
11639                pw.print("  Sticky broadcasts for user ");
11640                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11641                StringBuilder sb = new StringBuilder(128);
11642                for (Map.Entry<String, ArrayList<Intent>> ent
11643                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11644                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11645                    if (dumpAll) {
11646                        pw.println(":");
11647                        ArrayList<Intent> intents = ent.getValue();
11648                        final int N = intents.size();
11649                        for (int i=0; i<N; i++) {
11650                            sb.setLength(0);
11651                            sb.append("    Intent: ");
11652                            intents.get(i).toShortString(sb, false, true, false, false);
11653                            pw.println(sb.toString());
11654                            Bundle bundle = intents.get(i).getExtras();
11655                            if (bundle != null) {
11656                                pw.print("      ");
11657                                pw.println(bundle.toString());
11658                            }
11659                        }
11660                    } else {
11661                        pw.println("");
11662                    }
11663                }
11664            }
11665        }
11666
11667        if (!onlyHistory && dumpAll) {
11668            pw.println();
11669            for (BroadcastQueue queue : mBroadcastQueues) {
11670                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11671                        + queue.mBroadcastsScheduled);
11672            }
11673            pw.println("  mHandler:");
11674            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11675            needSep = true;
11676            printedAnything = true;
11677        }
11678
11679        if (!printedAnything) {
11680            pw.println("  (nothing)");
11681        }
11682    }
11683
11684    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11685            int opti, boolean dumpAll, String dumpPackage) {
11686        boolean needSep;
11687        boolean printedAnything = false;
11688
11689        ItemMatcher matcher = new ItemMatcher();
11690        matcher.build(args, opti);
11691
11692        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11693
11694        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11695        printedAnything |= needSep;
11696
11697        if (mLaunchingProviders.size() > 0) {
11698            boolean printed = false;
11699            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11700                ContentProviderRecord r = mLaunchingProviders.get(i);
11701                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11702                    continue;
11703                }
11704                if (!printed) {
11705                    if (needSep) pw.println();
11706                    needSep = true;
11707                    pw.println("  Launching content providers:");
11708                    printed = true;
11709                    printedAnything = true;
11710                }
11711                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11712                        pw.println(r);
11713            }
11714        }
11715
11716        if (mGrantedUriPermissions.size() > 0) {
11717            boolean printed = false;
11718            int dumpUid = -2;
11719            if (dumpPackage != null) {
11720                try {
11721                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11722                } catch (NameNotFoundException e) {
11723                    dumpUid = -1;
11724                }
11725            }
11726            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11727                int uid = mGrantedUriPermissions.keyAt(i);
11728                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11729                    continue;
11730                }
11731                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
11732                if (!printed) {
11733                    if (needSep) pw.println();
11734                    needSep = true;
11735                    pw.println("  Granted Uri Permissions:");
11736                    printed = true;
11737                    printedAnything = true;
11738                }
11739                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
11740                for (UriPermission perm : perms.values()) {
11741                    pw.print("    "); pw.println(perm);
11742                    if (dumpAll) {
11743                        perm.dump(pw, "      ");
11744                    }
11745                }
11746            }
11747        }
11748
11749        if (!printedAnything) {
11750            pw.println("  (nothing)");
11751        }
11752    }
11753
11754    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11755            int opti, boolean dumpAll, String dumpPackage) {
11756        boolean printed = false;
11757
11758        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11759
11760        if (mIntentSenderRecords.size() > 0) {
11761            Iterator<WeakReference<PendingIntentRecord>> it
11762                    = mIntentSenderRecords.values().iterator();
11763            while (it.hasNext()) {
11764                WeakReference<PendingIntentRecord> ref = it.next();
11765                PendingIntentRecord rec = ref != null ? ref.get(): null;
11766                if (dumpPackage != null && (rec == null
11767                        || !dumpPackage.equals(rec.key.packageName))) {
11768                    continue;
11769                }
11770                printed = true;
11771                if (rec != null) {
11772                    pw.print("  * "); pw.println(rec);
11773                    if (dumpAll) {
11774                        rec.dump(pw, "    ");
11775                    }
11776                } else {
11777                    pw.print("  * "); pw.println(ref);
11778                }
11779            }
11780        }
11781
11782        if (!printed) {
11783            pw.println("  (nothing)");
11784        }
11785    }
11786
11787    private static final int dumpProcessList(PrintWriter pw,
11788            ActivityManagerService service, List list,
11789            String prefix, String normalLabel, String persistentLabel,
11790            String dumpPackage) {
11791        int numPers = 0;
11792        final int N = list.size()-1;
11793        for (int i=N; i>=0; i--) {
11794            ProcessRecord r = (ProcessRecord)list.get(i);
11795            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11796                continue;
11797            }
11798            pw.println(String.format("%s%s #%2d: %s",
11799                    prefix, (r.persistent ? persistentLabel : normalLabel),
11800                    i, r.toString()));
11801            if (r.persistent) {
11802                numPers++;
11803            }
11804        }
11805        return numPers;
11806    }
11807
11808    private static final boolean dumpProcessOomList(PrintWriter pw,
11809            ActivityManagerService service, List<ProcessRecord> origList,
11810            String prefix, String normalLabel, String persistentLabel,
11811            boolean inclDetails, String dumpPackage) {
11812
11813        ArrayList<Pair<ProcessRecord, Integer>> list
11814                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11815        for (int i=0; i<origList.size(); i++) {
11816            ProcessRecord r = origList.get(i);
11817            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11818                continue;
11819            }
11820            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11821        }
11822
11823        if (list.size() <= 0) {
11824            return false;
11825        }
11826
11827        Comparator<Pair<ProcessRecord, Integer>> comparator
11828                = new Comparator<Pair<ProcessRecord, Integer>>() {
11829            @Override
11830            public int compare(Pair<ProcessRecord, Integer> object1,
11831                    Pair<ProcessRecord, Integer> object2) {
11832                if (object1.first.setAdj != object2.first.setAdj) {
11833                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11834                }
11835                if (object1.second.intValue() != object2.second.intValue()) {
11836                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11837                }
11838                return 0;
11839            }
11840        };
11841
11842        Collections.sort(list, comparator);
11843
11844        final long curRealtime = SystemClock.elapsedRealtime();
11845        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11846        final long curUptime = SystemClock.uptimeMillis();
11847        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11848
11849        for (int i=list.size()-1; i>=0; i--) {
11850            ProcessRecord r = list.get(i).first;
11851            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11852            char schedGroup;
11853            switch (r.setSchedGroup) {
11854                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11855                    schedGroup = 'B';
11856                    break;
11857                case Process.THREAD_GROUP_DEFAULT:
11858                    schedGroup = 'F';
11859                    break;
11860                default:
11861                    schedGroup = '?';
11862                    break;
11863            }
11864            char foreground;
11865            if (r.foregroundActivities) {
11866                foreground = 'A';
11867            } else if (r.foregroundServices) {
11868                foreground = 'S';
11869            } else {
11870                foreground = ' ';
11871            }
11872            String procState = ProcessList.makeProcStateString(r.curProcState);
11873            pw.print(prefix);
11874            pw.print(r.persistent ? persistentLabel : normalLabel);
11875            pw.print(" #");
11876            int num = (origList.size()-1)-list.get(i).second;
11877            if (num < 10) pw.print(' ');
11878            pw.print(num);
11879            pw.print(": ");
11880            pw.print(oomAdj);
11881            pw.print(' ');
11882            pw.print(schedGroup);
11883            pw.print('/');
11884            pw.print(foreground);
11885            pw.print('/');
11886            pw.print(procState);
11887            pw.print(" trm:");
11888            if (r.trimMemoryLevel < 10) pw.print(' ');
11889            pw.print(r.trimMemoryLevel);
11890            pw.print(' ');
11891            pw.print(r.toShortString());
11892            pw.print(" (");
11893            pw.print(r.adjType);
11894            pw.println(')');
11895            if (r.adjSource != null || r.adjTarget != null) {
11896                pw.print(prefix);
11897                pw.print("    ");
11898                if (r.adjTarget instanceof ComponentName) {
11899                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11900                } else if (r.adjTarget != null) {
11901                    pw.print(r.adjTarget.toString());
11902                } else {
11903                    pw.print("{null}");
11904                }
11905                pw.print("<=");
11906                if (r.adjSource instanceof ProcessRecord) {
11907                    pw.print("Proc{");
11908                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11909                    pw.println("}");
11910                } else if (r.adjSource != null) {
11911                    pw.println(r.adjSource.toString());
11912                } else {
11913                    pw.println("{null}");
11914                }
11915            }
11916            if (inclDetails) {
11917                pw.print(prefix);
11918                pw.print("    ");
11919                pw.print("oom: max="); pw.print(r.maxAdj);
11920                pw.print(" curRaw="); pw.print(r.curRawAdj);
11921                pw.print(" setRaw="); pw.print(r.setRawAdj);
11922                pw.print(" cur="); pw.print(r.curAdj);
11923                pw.print(" set="); pw.println(r.setAdj);
11924                pw.print(prefix);
11925                pw.print("    ");
11926                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
11927                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
11928                pw.print(" lastPss="); pw.print(r.lastPss);
11929                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
11930                pw.print(prefix);
11931                pw.print("    ");
11932                pw.print("keeping="); pw.print(r.keeping);
11933                pw.print(" cached="); pw.print(r.cached);
11934                pw.print(" empty="); pw.print(r.empty);
11935                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
11936
11937                if (!r.keeping) {
11938                    if (r.lastWakeTime != 0) {
11939                        long wtime;
11940                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
11941                        synchronized (stats) {
11942                            wtime = stats.getProcessWakeTime(r.info.uid,
11943                                    r.pid, curRealtime);
11944                        }
11945                        long timeUsed = wtime - r.lastWakeTime;
11946                        pw.print(prefix);
11947                        pw.print("    ");
11948                        pw.print("keep awake over ");
11949                        TimeUtils.formatDuration(realtimeSince, pw);
11950                        pw.print(" used ");
11951                        TimeUtils.formatDuration(timeUsed, pw);
11952                        pw.print(" (");
11953                        pw.print((timeUsed*100)/realtimeSince);
11954                        pw.println("%)");
11955                    }
11956                    if (r.lastCpuTime != 0) {
11957                        long timeUsed = r.curCpuTime - r.lastCpuTime;
11958                        pw.print(prefix);
11959                        pw.print("    ");
11960                        pw.print("run cpu over ");
11961                        TimeUtils.formatDuration(uptimeSince, pw);
11962                        pw.print(" used ");
11963                        TimeUtils.formatDuration(timeUsed, pw);
11964                        pw.print(" (");
11965                        pw.print((timeUsed*100)/uptimeSince);
11966                        pw.println("%)");
11967                    }
11968                }
11969            }
11970        }
11971        return true;
11972    }
11973
11974    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
11975        ArrayList<ProcessRecord> procs;
11976        synchronized (this) {
11977            if (args != null && args.length > start
11978                    && args[start].charAt(0) != '-') {
11979                procs = new ArrayList<ProcessRecord>();
11980                int pid = -1;
11981                try {
11982                    pid = Integer.parseInt(args[start]);
11983                } catch (NumberFormatException e) {
11984                }
11985                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11986                    ProcessRecord proc = mLruProcesses.get(i);
11987                    if (proc.pid == pid) {
11988                        procs.add(proc);
11989                    } else if (proc.processName.equals(args[start])) {
11990                        procs.add(proc);
11991                    }
11992                }
11993                if (procs.size() <= 0) {
11994                    return null;
11995                }
11996            } else {
11997                procs = new ArrayList<ProcessRecord>(mLruProcesses);
11998            }
11999        }
12000        return procs;
12001    }
12002
12003    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12004            PrintWriter pw, String[] args) {
12005        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12006        if (procs == null) {
12007            pw.println("No process found for: " + args[0]);
12008            return;
12009        }
12010
12011        long uptime = SystemClock.uptimeMillis();
12012        long realtime = SystemClock.elapsedRealtime();
12013        pw.println("Applications Graphics Acceleration Info:");
12014        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12015
12016        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12017            ProcessRecord r = procs.get(i);
12018            if (r.thread != null) {
12019                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12020                pw.flush();
12021                try {
12022                    TransferPipe tp = new TransferPipe();
12023                    try {
12024                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12025                        tp.go(fd);
12026                    } finally {
12027                        tp.kill();
12028                    }
12029                } catch (IOException e) {
12030                    pw.println("Failure while dumping the app: " + r);
12031                    pw.flush();
12032                } catch (RemoteException e) {
12033                    pw.println("Got a RemoteException while dumping the app " + r);
12034                    pw.flush();
12035                }
12036            }
12037        }
12038    }
12039
12040    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12041        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12042        if (procs == null) {
12043            pw.println("No process found for: " + args[0]);
12044            return;
12045        }
12046
12047        pw.println("Applications Database Info:");
12048
12049        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12050            ProcessRecord r = procs.get(i);
12051            if (r.thread != null) {
12052                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12053                pw.flush();
12054                try {
12055                    TransferPipe tp = new TransferPipe();
12056                    try {
12057                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12058                        tp.go(fd);
12059                    } finally {
12060                        tp.kill();
12061                    }
12062                } catch (IOException e) {
12063                    pw.println("Failure while dumping the app: " + r);
12064                    pw.flush();
12065                } catch (RemoteException e) {
12066                    pw.println("Got a RemoteException while dumping the app " + r);
12067                    pw.flush();
12068                }
12069            }
12070        }
12071    }
12072
12073    final static class MemItem {
12074        final boolean isProc;
12075        final String label;
12076        final String shortLabel;
12077        final long pss;
12078        final int id;
12079        final boolean hasActivities;
12080        ArrayList<MemItem> subitems;
12081
12082        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12083                boolean _hasActivities) {
12084            isProc = true;
12085            label = _label;
12086            shortLabel = _shortLabel;
12087            pss = _pss;
12088            id = _id;
12089            hasActivities = _hasActivities;
12090        }
12091
12092        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12093            isProc = false;
12094            label = _label;
12095            shortLabel = _shortLabel;
12096            pss = _pss;
12097            id = _id;
12098            hasActivities = false;
12099        }
12100    }
12101
12102    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12103            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12104        if (sort && !isCompact) {
12105            Collections.sort(items, new Comparator<MemItem>() {
12106                @Override
12107                public int compare(MemItem lhs, MemItem rhs) {
12108                    if (lhs.pss < rhs.pss) {
12109                        return 1;
12110                    } else if (lhs.pss > rhs.pss) {
12111                        return -1;
12112                    }
12113                    return 0;
12114                }
12115            });
12116        }
12117
12118        for (int i=0; i<items.size(); i++) {
12119            MemItem mi = items.get(i);
12120            if (!isCompact) {
12121                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12122            } else if (mi.isProc) {
12123                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12124                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12125                pw.println(mi.hasActivities ? ",a" : ",e");
12126            } else {
12127                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12128                pw.println(mi.pss);
12129            }
12130            if (mi.subitems != null) {
12131                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12132                        true, isCompact);
12133            }
12134        }
12135    }
12136
12137    // These are in KB.
12138    static final long[] DUMP_MEM_BUCKETS = new long[] {
12139        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12140        120*1024, 160*1024, 200*1024,
12141        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12142        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12143    };
12144
12145    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12146            boolean stackLike) {
12147        int start = label.lastIndexOf('.');
12148        if (start >= 0) start++;
12149        else start = 0;
12150        int end = label.length();
12151        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12152            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12153                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12154                out.append(bucket);
12155                out.append(stackLike ? "MB." : "MB ");
12156                out.append(label, start, end);
12157                return;
12158            }
12159        }
12160        out.append(memKB/1024);
12161        out.append(stackLike ? "MB." : "MB ");
12162        out.append(label, start, end);
12163    }
12164
12165    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12166            ProcessList.NATIVE_ADJ,
12167            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12168            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12169            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12170            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12171            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12172    };
12173    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12174            "Native",
12175            "System", "Persistent", "Foreground",
12176            "Visible", "Perceptible",
12177            "Heavy Weight", "Backup",
12178            "A Services", "Home",
12179            "Previous", "B Services", "Cached"
12180    };
12181    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12182            "native",
12183            "sys", "pers", "fore",
12184            "vis", "percept",
12185            "heavy", "backup",
12186            "servicea", "home",
12187            "prev", "serviceb", "cached"
12188    };
12189
12190    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12191            long realtime, boolean isCheckinRequest, boolean isCompact) {
12192        if (isCheckinRequest || isCompact) {
12193            // short checkin version
12194            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12195        } else {
12196            pw.println("Applications Memory Usage (kB):");
12197            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12198        }
12199    }
12200
12201    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12202            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12203        boolean dumpDetails = false;
12204        boolean dumpFullDetails = false;
12205        boolean dumpDalvik = false;
12206        boolean oomOnly = false;
12207        boolean isCompact = false;
12208        boolean localOnly = false;
12209
12210        int opti = 0;
12211        while (opti < args.length) {
12212            String opt = args[opti];
12213            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12214                break;
12215            }
12216            opti++;
12217            if ("-a".equals(opt)) {
12218                dumpDetails = true;
12219                dumpFullDetails = true;
12220                dumpDalvik = true;
12221            } else if ("-d".equals(opt)) {
12222                dumpDalvik = true;
12223            } else if ("-c".equals(opt)) {
12224                isCompact = true;
12225            } else if ("--oom".equals(opt)) {
12226                oomOnly = true;
12227            } else if ("--local".equals(opt)) {
12228                localOnly = true;
12229            } else if ("-h".equals(opt)) {
12230                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12231                pw.println("  -a: include all available information for each process.");
12232                pw.println("  -d: include dalvik details when dumping process details.");
12233                pw.println("  -c: dump in a compact machine-parseable representation.");
12234                pw.println("  --oom: only show processes organized by oom adj.");
12235                pw.println("  --local: only collect details locally, don't call process.");
12236                pw.println("If [process] is specified it can be the name or ");
12237                pw.println("pid of a specific process to dump.");
12238                return;
12239            } else {
12240                pw.println("Unknown argument: " + opt + "; use -h for help");
12241            }
12242        }
12243
12244        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12245        long uptime = SystemClock.uptimeMillis();
12246        long realtime = SystemClock.elapsedRealtime();
12247        final long[] tmpLong = new long[1];
12248
12249        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12250        if (procs == null) {
12251            // No Java processes.  Maybe they want to print a native process.
12252            if (args != null && args.length > opti
12253                    && args[opti].charAt(0) != '-') {
12254                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12255                        = new ArrayList<ProcessCpuTracker.Stats>();
12256                updateCpuStatsNow();
12257                int findPid = -1;
12258                try {
12259                    findPid = Integer.parseInt(args[opti]);
12260                } catch (NumberFormatException e) {
12261                }
12262                synchronized (mProcessCpuThread) {
12263                    final int N = mProcessCpuTracker.countStats();
12264                    for (int i=0; i<N; i++) {
12265                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12266                        if (st.pid == findPid || (st.baseName != null
12267                                && st.baseName.equals(args[opti]))) {
12268                            nativeProcs.add(st);
12269                        }
12270                    }
12271                }
12272                if (nativeProcs.size() > 0) {
12273                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12274                            isCompact);
12275                    Debug.MemoryInfo mi = null;
12276                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12277                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12278                        final int pid = r.pid;
12279                        if (!isCheckinRequest && dumpDetails) {
12280                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12281                        }
12282                        if (mi == null) {
12283                            mi = new Debug.MemoryInfo();
12284                        }
12285                        if (dumpDetails || (!brief && !oomOnly)) {
12286                            Debug.getMemoryInfo(pid, mi);
12287                        } else {
12288                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12289                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12290                        }
12291                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12292                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12293                        if (isCheckinRequest) {
12294                            pw.println();
12295                        }
12296                    }
12297                    return;
12298                }
12299            }
12300            pw.println("No process found for: " + args[opti]);
12301            return;
12302        }
12303
12304        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12305            dumpDetails = true;
12306        }
12307
12308        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12309
12310        String[] innerArgs = new String[args.length-opti];
12311        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12312
12313        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12314        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12315        long nativePss=0, dalvikPss=0, otherPss=0;
12316        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12317
12318        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12319        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12320                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12321
12322        long totalPss = 0;
12323        long cachedPss = 0;
12324
12325        Debug.MemoryInfo mi = null;
12326        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12327            final ProcessRecord r = procs.get(i);
12328            final IApplicationThread thread;
12329            final int pid;
12330            final int oomAdj;
12331            final boolean hasActivities;
12332            synchronized (this) {
12333                thread = r.thread;
12334                pid = r.pid;
12335                oomAdj = r.getSetAdjWithServices();
12336                hasActivities = r.activities.size() > 0;
12337            }
12338            if (thread != null) {
12339                if (!isCheckinRequest && dumpDetails) {
12340                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12341                }
12342                if (mi == null) {
12343                    mi = new Debug.MemoryInfo();
12344                }
12345                if (dumpDetails || (!brief && !oomOnly)) {
12346                    Debug.getMemoryInfo(pid, mi);
12347                } else {
12348                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12349                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12350                }
12351                if (dumpDetails) {
12352                    if (localOnly) {
12353                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12354                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12355                        if (isCheckinRequest) {
12356                            pw.println();
12357                        }
12358                    } else {
12359                        try {
12360                            pw.flush();
12361                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12362                                    dumpDalvik, innerArgs);
12363                        } catch (RemoteException e) {
12364                            if (!isCheckinRequest) {
12365                                pw.println("Got RemoteException!");
12366                                pw.flush();
12367                            }
12368                        }
12369                    }
12370                }
12371
12372                final long myTotalPss = mi.getTotalPss();
12373                final long myTotalUss = mi.getTotalUss();
12374
12375                synchronized (this) {
12376                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12377                        // Record this for posterity if the process has been stable.
12378                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12379                    }
12380                }
12381
12382                if (!isCheckinRequest && mi != null) {
12383                    totalPss += myTotalPss;
12384                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12385                            (hasActivities ? " / activities)" : ")"),
12386                            r.processName, myTotalPss, pid, hasActivities);
12387                    procMems.add(pssItem);
12388                    procMemsMap.put(pid, pssItem);
12389
12390                    nativePss += mi.nativePss;
12391                    dalvikPss += mi.dalvikPss;
12392                    otherPss += mi.otherPss;
12393                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12394                        long mem = mi.getOtherPss(j);
12395                        miscPss[j] += mem;
12396                        otherPss -= mem;
12397                    }
12398
12399                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12400                        cachedPss += myTotalPss;
12401                    }
12402
12403                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12404                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12405                                || oomIndex == (oomPss.length-1)) {
12406                            oomPss[oomIndex] += myTotalPss;
12407                            if (oomProcs[oomIndex] == null) {
12408                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12409                            }
12410                            oomProcs[oomIndex].add(pssItem);
12411                            break;
12412                        }
12413                    }
12414                }
12415            }
12416        }
12417
12418        if (!isCheckinRequest && procs.size() > 1) {
12419            // If we are showing aggregations, also look for native processes to
12420            // include so that our aggregations are more accurate.
12421            updateCpuStatsNow();
12422            synchronized (mProcessCpuThread) {
12423                final int N = mProcessCpuTracker.countStats();
12424                for (int i=0; i<N; i++) {
12425                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12426                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12427                        if (mi == null) {
12428                            mi = new Debug.MemoryInfo();
12429                        }
12430                        if (!brief && !oomOnly) {
12431                            Debug.getMemoryInfo(st.pid, mi);
12432                        } else {
12433                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12434                            mi.nativePrivateDirty = (int)tmpLong[0];
12435                        }
12436
12437                        final long myTotalPss = mi.getTotalPss();
12438                        totalPss += myTotalPss;
12439
12440                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12441                                st.name, myTotalPss, st.pid, false);
12442                        procMems.add(pssItem);
12443
12444                        nativePss += mi.nativePss;
12445                        dalvikPss += mi.dalvikPss;
12446                        otherPss += mi.otherPss;
12447                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12448                            long mem = mi.getOtherPss(j);
12449                            miscPss[j] += mem;
12450                            otherPss -= mem;
12451                        }
12452                        oomPss[0] += myTotalPss;
12453                        if (oomProcs[0] == null) {
12454                            oomProcs[0] = new ArrayList<MemItem>();
12455                        }
12456                        oomProcs[0].add(pssItem);
12457                    }
12458                }
12459            }
12460
12461            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12462
12463            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12464            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12465            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12466            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12467                String label = Debug.MemoryInfo.getOtherLabel(j);
12468                catMems.add(new MemItem(label, label, miscPss[j], j));
12469            }
12470
12471            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12472            for (int j=0; j<oomPss.length; j++) {
12473                if (oomPss[j] != 0) {
12474                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12475                            : DUMP_MEM_OOM_LABEL[j];
12476                    MemItem item = new MemItem(label, label, oomPss[j],
12477                            DUMP_MEM_OOM_ADJ[j]);
12478                    item.subitems = oomProcs[j];
12479                    oomMems.add(item);
12480                }
12481            }
12482
12483            if (!brief && !oomOnly && !isCompact) {
12484                pw.println();
12485                pw.println("Total PSS by process:");
12486                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12487                pw.println();
12488            }
12489            if (!isCompact) {
12490                pw.println("Total PSS by OOM adjustment:");
12491            }
12492            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12493            if (!brief && !oomOnly) {
12494                PrintWriter out = categoryPw != null ? categoryPw : pw;
12495                if (!isCompact) {
12496                    out.println();
12497                    out.println("Total PSS by category:");
12498                }
12499                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12500            }
12501            if (!isCompact) {
12502                pw.println();
12503            }
12504            MemInfoReader memInfo = new MemInfoReader();
12505            memInfo.readMemInfo();
12506            if (!brief) {
12507                if (!isCompact) {
12508                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12509                    pw.print(" kB (status ");
12510                    switch (mLastMemoryLevel) {
12511                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12512                            pw.println("normal)");
12513                            break;
12514                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12515                            pw.println("moderate)");
12516                            break;
12517                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12518                            pw.println("low)");
12519                            break;
12520                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12521                            pw.println("critical)");
12522                            break;
12523                        default:
12524                            pw.print(mLastMemoryLevel);
12525                            pw.println(")");
12526                            break;
12527                    }
12528                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12529                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12530                            pw.print(cachedPss); pw.print(" cached pss + ");
12531                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12532                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12533                } else {
12534                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12535                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12536                            + memInfo.getFreeSizeKb()); pw.print(",");
12537                    pw.println(totalPss - cachedPss);
12538                }
12539            }
12540            if (!isCompact) {
12541                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12542                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12543                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12544                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12545                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12546                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12547                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12548                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12549                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12550                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12551                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12552            }
12553            if (!brief) {
12554                if (memInfo.getZramTotalSizeKb() != 0) {
12555                    if (!isCompact) {
12556                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12557                                pw.print(" kB physical used for ");
12558                                pw.print(memInfo.getSwapTotalSizeKb()
12559                                        - memInfo.getSwapFreeSizeKb());
12560                                pw.print(" kB in swap (");
12561                                pw.print(memInfo.getSwapTotalSizeKb());
12562                                pw.println(" kB total swap)");
12563                    } else {
12564                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12565                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12566                                pw.println(memInfo.getSwapFreeSizeKb());
12567                    }
12568                }
12569                final int[] SINGLE_LONG_FORMAT = new int[] {
12570                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12571                };
12572                long[] longOut = new long[1];
12573                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12574                        SINGLE_LONG_FORMAT, null, longOut, null);
12575                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12576                longOut[0] = 0;
12577                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12578                        SINGLE_LONG_FORMAT, null, longOut, null);
12579                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12580                longOut[0] = 0;
12581                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12582                        SINGLE_LONG_FORMAT, null, longOut, null);
12583                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12584                longOut[0] = 0;
12585                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12586                        SINGLE_LONG_FORMAT, null, longOut, null);
12587                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12588                if (!isCompact) {
12589                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12590                        pw.print("      KSM: "); pw.print(sharing);
12591                                pw.print(" kB saved from shared ");
12592                                pw.print(shared); pw.println(" kB");
12593                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12594                                pw.print(voltile); pw.println(" kB volatile");
12595                    }
12596                    pw.print("   Tuning: ");
12597                    pw.print(ActivityManager.staticGetMemoryClass());
12598                    pw.print(" (large ");
12599                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12600                    pw.print("), oom ");
12601                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12602                    pw.print(" kB");
12603                    pw.print(", restore limit ");
12604                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12605                    pw.print(" kB");
12606                    if (ActivityManager.isLowRamDeviceStatic()) {
12607                        pw.print(" (low-ram)");
12608                    }
12609                    if (ActivityManager.isHighEndGfx()) {
12610                        pw.print(" (high-end-gfx)");
12611                    }
12612                    pw.println();
12613                } else {
12614                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12615                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12616                    pw.println(voltile);
12617                    pw.print("tuning,");
12618                    pw.print(ActivityManager.staticGetMemoryClass());
12619                    pw.print(',');
12620                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12621                    pw.print(',');
12622                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12623                    if (ActivityManager.isLowRamDeviceStatic()) {
12624                        pw.print(",low-ram");
12625                    }
12626                    if (ActivityManager.isHighEndGfx()) {
12627                        pw.print(",high-end-gfx");
12628                    }
12629                    pw.println();
12630                }
12631            }
12632        }
12633    }
12634
12635    /**
12636     * Searches array of arguments for the specified string
12637     * @param args array of argument strings
12638     * @param value value to search for
12639     * @return true if the value is contained in the array
12640     */
12641    private static boolean scanArgs(String[] args, String value) {
12642        if (args != null) {
12643            for (String arg : args) {
12644                if (value.equals(arg)) {
12645                    return true;
12646                }
12647            }
12648        }
12649        return false;
12650    }
12651
12652    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12653            ContentProviderRecord cpr, boolean always) {
12654        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12655
12656        if (!inLaunching || always) {
12657            synchronized (cpr) {
12658                cpr.launchingApp = null;
12659                cpr.notifyAll();
12660            }
12661            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12662            String names[] = cpr.info.authority.split(";");
12663            for (int j = 0; j < names.length; j++) {
12664                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12665            }
12666        }
12667
12668        for (int i=0; i<cpr.connections.size(); i++) {
12669            ContentProviderConnection conn = cpr.connections.get(i);
12670            if (conn.waiting) {
12671                // If this connection is waiting for the provider, then we don't
12672                // need to mess with its process unless we are always removing
12673                // or for some reason the provider is not currently launching.
12674                if (inLaunching && !always) {
12675                    continue;
12676                }
12677            }
12678            ProcessRecord capp = conn.client;
12679            conn.dead = true;
12680            if (conn.stableCount > 0) {
12681                if (!capp.persistent && capp.thread != null
12682                        && capp.pid != 0
12683                        && capp.pid != MY_PID) {
12684                    killUnneededProcessLocked(capp, "depends on provider "
12685                            + cpr.name.flattenToShortString()
12686                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12687                }
12688            } else if (capp.thread != null && conn.provider.provider != null) {
12689                try {
12690                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12691                } catch (RemoteException e) {
12692                }
12693                // In the protocol here, we don't expect the client to correctly
12694                // clean up this connection, we'll just remove it.
12695                cpr.connections.remove(i);
12696                conn.client.conProviders.remove(conn);
12697            }
12698        }
12699
12700        if (inLaunching && always) {
12701            mLaunchingProviders.remove(cpr);
12702        }
12703        return inLaunching;
12704    }
12705
12706    /**
12707     * Main code for cleaning up a process when it has gone away.  This is
12708     * called both as a result of the process dying, or directly when stopping
12709     * a process when running in single process mode.
12710     */
12711    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12712            boolean restarting, boolean allowRestart, int index) {
12713        if (index >= 0) {
12714            removeLruProcessLocked(app);
12715            ProcessList.remove(app.pid);
12716        }
12717
12718        mProcessesToGc.remove(app);
12719        mPendingPssProcesses.remove(app);
12720
12721        // Dismiss any open dialogs.
12722        if (app.crashDialog != null && !app.forceCrashReport) {
12723            app.crashDialog.dismiss();
12724            app.crashDialog = null;
12725        }
12726        if (app.anrDialog != null) {
12727            app.anrDialog.dismiss();
12728            app.anrDialog = null;
12729        }
12730        if (app.waitDialog != null) {
12731            app.waitDialog.dismiss();
12732            app.waitDialog = null;
12733        }
12734
12735        app.crashing = false;
12736        app.notResponding = false;
12737
12738        app.resetPackageList(mProcessStats);
12739        app.unlinkDeathRecipient();
12740        app.makeInactive(mProcessStats);
12741        app.forcingToForeground = null;
12742        updateProcessForegroundLocked(app, false, false);
12743        app.foregroundActivities = false;
12744        app.hasShownUi = false;
12745        app.treatLikeActivity = false;
12746        app.hasAboveClient = false;
12747        app.hasClientActivities = false;
12748
12749        mServices.killServicesLocked(app, allowRestart);
12750
12751        boolean restart = false;
12752
12753        // Remove published content providers.
12754        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12755            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12756            final boolean always = app.bad || !allowRestart;
12757            if (removeDyingProviderLocked(app, cpr, always) || always) {
12758                // We left the provider in the launching list, need to
12759                // restart it.
12760                restart = true;
12761            }
12762
12763            cpr.provider = null;
12764            cpr.proc = null;
12765        }
12766        app.pubProviders.clear();
12767
12768        // Take care of any launching providers waiting for this process.
12769        if (checkAppInLaunchingProvidersLocked(app, false)) {
12770            restart = true;
12771        }
12772
12773        // Unregister from connected content providers.
12774        if (!app.conProviders.isEmpty()) {
12775            for (int i=0; i<app.conProviders.size(); i++) {
12776                ContentProviderConnection conn = app.conProviders.get(i);
12777                conn.provider.connections.remove(conn);
12778            }
12779            app.conProviders.clear();
12780        }
12781
12782        // At this point there may be remaining entries in mLaunchingProviders
12783        // where we were the only one waiting, so they are no longer of use.
12784        // Look for these and clean up if found.
12785        // XXX Commented out for now.  Trying to figure out a way to reproduce
12786        // the actual situation to identify what is actually going on.
12787        if (false) {
12788            for (int i=0; i<mLaunchingProviders.size(); i++) {
12789                ContentProviderRecord cpr = (ContentProviderRecord)
12790                        mLaunchingProviders.get(i);
12791                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12792                    synchronized (cpr) {
12793                        cpr.launchingApp = null;
12794                        cpr.notifyAll();
12795                    }
12796                }
12797            }
12798        }
12799
12800        skipCurrentReceiverLocked(app);
12801
12802        // Unregister any receivers.
12803        for (int i=app.receivers.size()-1; i>=0; i--) {
12804            removeReceiverLocked(app.receivers.valueAt(i));
12805        }
12806        app.receivers.clear();
12807
12808        // If the app is undergoing backup, tell the backup manager about it
12809        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12810            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12811                    + mBackupTarget.appInfo + " died during backup");
12812            try {
12813                IBackupManager bm = IBackupManager.Stub.asInterface(
12814                        ServiceManager.getService(Context.BACKUP_SERVICE));
12815                bm.agentDisconnected(app.info.packageName);
12816            } catch (RemoteException e) {
12817                // can't happen; backup manager is local
12818            }
12819        }
12820
12821        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12822            ProcessChangeItem item = mPendingProcessChanges.get(i);
12823            if (item.pid == app.pid) {
12824                mPendingProcessChanges.remove(i);
12825                mAvailProcessChanges.add(item);
12826            }
12827        }
12828        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12829
12830        // If the caller is restarting this app, then leave it in its
12831        // current lists and let the caller take care of it.
12832        if (restarting) {
12833            return;
12834        }
12835
12836        if (!app.persistent || app.isolated) {
12837            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12838                    "Removing non-persistent process during cleanup: " + app);
12839            mProcessNames.remove(app.processName, app.uid);
12840            mIsolatedProcesses.remove(app.uid);
12841            if (mHeavyWeightProcess == app) {
12842                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12843                        mHeavyWeightProcess.userId, 0));
12844                mHeavyWeightProcess = null;
12845            }
12846        } else if (!app.removed) {
12847            // This app is persistent, so we need to keep its record around.
12848            // If it is not already on the pending app list, add it there
12849            // and start a new process for it.
12850            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12851                mPersistentStartingProcesses.add(app);
12852                restart = true;
12853            }
12854        }
12855        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12856                "Clean-up removing on hold: " + app);
12857        mProcessesOnHold.remove(app);
12858
12859        if (app == mHomeProcess) {
12860            mHomeProcess = null;
12861        }
12862        if (app == mPreviousProcess) {
12863            mPreviousProcess = null;
12864        }
12865
12866        if (restart && !app.isolated) {
12867            // We have components that still need to be running in the
12868            // process, so re-launch it.
12869            mProcessNames.put(app.processName, app.uid, app);
12870            startProcessLocked(app, "restart", app.processName);
12871        } else if (app.pid > 0 && app.pid != MY_PID) {
12872            // Goodbye!
12873            boolean removed;
12874            synchronized (mPidsSelfLocked) {
12875                mPidsSelfLocked.remove(app.pid);
12876                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12877            }
12878            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
12879                    app.processName, app.info.uid);
12880            if (app.isolated) {
12881                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
12882            }
12883            app.setPid(0);
12884        }
12885    }
12886
12887    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12888        // Look through the content providers we are waiting to have launched,
12889        // and if any run in this process then either schedule a restart of
12890        // the process or kill the client waiting for it if this process has
12891        // gone bad.
12892        int NL = mLaunchingProviders.size();
12893        boolean restart = false;
12894        for (int i=0; i<NL; i++) {
12895            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12896            if (cpr.launchingApp == app) {
12897                if (!alwaysBad && !app.bad) {
12898                    restart = true;
12899                } else {
12900                    removeDyingProviderLocked(app, cpr, true);
12901                    // cpr should have been removed from mLaunchingProviders
12902                    NL = mLaunchingProviders.size();
12903                    i--;
12904                }
12905            }
12906        }
12907        return restart;
12908    }
12909
12910    // =========================================================
12911    // SERVICES
12912    // =========================================================
12913
12914    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12915            int flags) {
12916        enforceNotIsolatedCaller("getServices");
12917        synchronized (this) {
12918            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12919        }
12920    }
12921
12922    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12923        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12924        synchronized (this) {
12925            return mServices.getRunningServiceControlPanelLocked(name);
12926        }
12927    }
12928
12929    public ComponentName startService(IApplicationThread caller, Intent service,
12930            String resolvedType, int userId) {
12931        enforceNotIsolatedCaller("startService");
12932        // Refuse possible leaked file descriptors
12933        if (service != null && service.hasFileDescriptors() == true) {
12934            throw new IllegalArgumentException("File descriptors passed in Intent");
12935        }
12936
12937        if (DEBUG_SERVICE)
12938            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
12939        synchronized(this) {
12940            final int callingPid = Binder.getCallingPid();
12941            final int callingUid = Binder.getCallingUid();
12942            final long origId = Binder.clearCallingIdentity();
12943            ComponentName res = mServices.startServiceLocked(caller, service,
12944                    resolvedType, callingPid, callingUid, userId);
12945            Binder.restoreCallingIdentity(origId);
12946            return res;
12947        }
12948    }
12949
12950    ComponentName startServiceInPackage(int uid,
12951            Intent service, String resolvedType, int userId) {
12952        synchronized(this) {
12953            if (DEBUG_SERVICE)
12954                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
12955            final long origId = Binder.clearCallingIdentity();
12956            ComponentName res = mServices.startServiceLocked(null, service,
12957                    resolvedType, -1, uid, userId);
12958            Binder.restoreCallingIdentity(origId);
12959            return res;
12960        }
12961    }
12962
12963    public int stopService(IApplicationThread caller, Intent service,
12964            String resolvedType, int userId) {
12965        enforceNotIsolatedCaller("stopService");
12966        // Refuse possible leaked file descriptors
12967        if (service != null && service.hasFileDescriptors() == true) {
12968            throw new IllegalArgumentException("File descriptors passed in Intent");
12969        }
12970
12971        synchronized(this) {
12972            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
12973        }
12974    }
12975
12976    public IBinder peekService(Intent service, String resolvedType) {
12977        enforceNotIsolatedCaller("peekService");
12978        // Refuse possible leaked file descriptors
12979        if (service != null && service.hasFileDescriptors() == true) {
12980            throw new IllegalArgumentException("File descriptors passed in Intent");
12981        }
12982        synchronized(this) {
12983            return mServices.peekServiceLocked(service, resolvedType);
12984        }
12985    }
12986
12987    public boolean stopServiceToken(ComponentName className, IBinder token,
12988            int startId) {
12989        synchronized(this) {
12990            return mServices.stopServiceTokenLocked(className, token, startId);
12991        }
12992    }
12993
12994    public void setServiceForeground(ComponentName className, IBinder token,
12995            int id, Notification notification, boolean removeNotification) {
12996        synchronized(this) {
12997            mServices.setServiceForegroundLocked(className, token, id, notification,
12998                    removeNotification);
12999        }
13000    }
13001
13002    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13003            boolean requireFull, String name, String callerPackage) {
13004        final int callingUserId = UserHandle.getUserId(callingUid);
13005        if (callingUserId != userId) {
13006            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13007                if ((requireFull || checkComponentPermission(
13008                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13009                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
13010                        && checkComponentPermission(
13011                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
13012                                callingPid, callingUid, -1, true)
13013                                != PackageManager.PERMISSION_GRANTED) {
13014                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13015                        // In this case, they would like to just execute as their
13016                        // owner user instead of failing.
13017                        userId = callingUserId;
13018                    } else {
13019                        StringBuilder builder = new StringBuilder(128);
13020                        builder.append("Permission Denial: ");
13021                        builder.append(name);
13022                        if (callerPackage != null) {
13023                            builder.append(" from ");
13024                            builder.append(callerPackage);
13025                        }
13026                        builder.append(" asks to run as user ");
13027                        builder.append(userId);
13028                        builder.append(" but is calling from user ");
13029                        builder.append(UserHandle.getUserId(callingUid));
13030                        builder.append("; this requires ");
13031                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
13032                        if (!requireFull) {
13033                            builder.append(" or ");
13034                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
13035                        }
13036                        String msg = builder.toString();
13037                        Slog.w(TAG, msg);
13038                        throw new SecurityException(msg);
13039                    }
13040                }
13041            }
13042            if (userId == UserHandle.USER_CURRENT
13043                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
13044                // Note that we may be accessing this outside of a lock...
13045                // shouldn't be a big deal, if this is being called outside
13046                // of a locked context there is intrinsically a race with
13047                // the value the caller will receive and someone else changing it.
13048                userId = mCurrentUserId;
13049            }
13050            if (!allowAll && userId < 0) {
13051                throw new IllegalArgumentException(
13052                        "Call does not support special user #" + userId);
13053            }
13054        }
13055        return userId;
13056    }
13057
13058    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13059            String className, int flags) {
13060        boolean result = false;
13061        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13062            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
13063                if (ActivityManager.checkUidPermission(
13064                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13065                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13066                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13067                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13068                            + " requests FLAG_SINGLE_USER, but app does not hold "
13069                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
13070                    Slog.w(TAG, msg);
13071                    throw new SecurityException(msg);
13072                }
13073                result = true;
13074            }
13075        } else if (componentProcessName == aInfo.packageName) {
13076            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13077        } else if ("system".equals(componentProcessName)) {
13078            result = true;
13079        }
13080        if (DEBUG_MU) {
13081            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13082                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13083        }
13084        return result;
13085    }
13086
13087    public int bindService(IApplicationThread caller, IBinder token,
13088            Intent service, String resolvedType,
13089            IServiceConnection connection, int flags, int userId) {
13090        enforceNotIsolatedCaller("bindService");
13091        // Refuse possible leaked file descriptors
13092        if (service != null && service.hasFileDescriptors() == true) {
13093            throw new IllegalArgumentException("File descriptors passed in Intent");
13094        }
13095
13096        synchronized(this) {
13097            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13098                    connection, flags, userId);
13099        }
13100    }
13101
13102    public boolean unbindService(IServiceConnection connection) {
13103        synchronized (this) {
13104            return mServices.unbindServiceLocked(connection);
13105        }
13106    }
13107
13108    public void publishService(IBinder token, Intent intent, IBinder service) {
13109        // Refuse possible leaked file descriptors
13110        if (intent != null && intent.hasFileDescriptors() == true) {
13111            throw new IllegalArgumentException("File descriptors passed in Intent");
13112        }
13113
13114        synchronized(this) {
13115            if (!(token instanceof ServiceRecord)) {
13116                throw new IllegalArgumentException("Invalid service token");
13117            }
13118            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13119        }
13120    }
13121
13122    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13123        // Refuse possible leaked file descriptors
13124        if (intent != null && intent.hasFileDescriptors() == true) {
13125            throw new IllegalArgumentException("File descriptors passed in Intent");
13126        }
13127
13128        synchronized(this) {
13129            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13130        }
13131    }
13132
13133    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13134        synchronized(this) {
13135            if (!(token instanceof ServiceRecord)) {
13136                throw new IllegalArgumentException("Invalid service token");
13137            }
13138            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13139        }
13140    }
13141
13142    // =========================================================
13143    // BACKUP AND RESTORE
13144    // =========================================================
13145
13146    // Cause the target app to be launched if necessary and its backup agent
13147    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13148    // activity manager to announce its creation.
13149    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13150        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13151        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
13152
13153        synchronized(this) {
13154            // !!! TODO: currently no check here that we're already bound
13155            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13156            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13157            synchronized (stats) {
13158                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13159            }
13160
13161            // Backup agent is now in use, its package can't be stopped.
13162            try {
13163                AppGlobals.getPackageManager().setPackageStoppedState(
13164                        app.packageName, false, UserHandle.getUserId(app.uid));
13165            } catch (RemoteException e) {
13166            } catch (IllegalArgumentException e) {
13167                Slog.w(TAG, "Failed trying to unstop package "
13168                        + app.packageName + ": " + e);
13169            }
13170
13171            BackupRecord r = new BackupRecord(ss, app, backupMode);
13172            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13173                    ? new ComponentName(app.packageName, app.backupAgentName)
13174                    : new ComponentName("android", "FullBackupAgent");
13175            // startProcessLocked() returns existing proc's record if it's already running
13176            ProcessRecord proc = startProcessLocked(app.processName, app,
13177                    false, 0, "backup", hostingName, false, false, false);
13178            if (proc == null) {
13179                Slog.e(TAG, "Unable to start backup agent process " + r);
13180                return false;
13181            }
13182
13183            r.app = proc;
13184            mBackupTarget = r;
13185            mBackupAppName = app.packageName;
13186
13187            // Try not to kill the process during backup
13188            updateOomAdjLocked(proc);
13189
13190            // If the process is already attached, schedule the creation of the backup agent now.
13191            // If it is not yet live, this will be done when it attaches to the framework.
13192            if (proc.thread != null) {
13193                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13194                try {
13195                    proc.thread.scheduleCreateBackupAgent(app,
13196                            compatibilityInfoForPackageLocked(app), backupMode);
13197                } catch (RemoteException e) {
13198                    // Will time out on the backup manager side
13199                }
13200            } else {
13201                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13202            }
13203            // Invariants: at this point, the target app process exists and the application
13204            // is either already running or in the process of coming up.  mBackupTarget and
13205            // mBackupAppName describe the app, so that when it binds back to the AM we
13206            // know that it's scheduled for a backup-agent operation.
13207        }
13208
13209        return true;
13210    }
13211
13212    @Override
13213    public void clearPendingBackup() {
13214        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13215        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13216
13217        synchronized (this) {
13218            mBackupTarget = null;
13219            mBackupAppName = null;
13220        }
13221    }
13222
13223    // A backup agent has just come up
13224    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13225        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13226                + " = " + agent);
13227
13228        synchronized(this) {
13229            if (!agentPackageName.equals(mBackupAppName)) {
13230                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13231                return;
13232            }
13233        }
13234
13235        long oldIdent = Binder.clearCallingIdentity();
13236        try {
13237            IBackupManager bm = IBackupManager.Stub.asInterface(
13238                    ServiceManager.getService(Context.BACKUP_SERVICE));
13239            bm.agentConnected(agentPackageName, agent);
13240        } catch (RemoteException e) {
13241            // can't happen; the backup manager service is local
13242        } catch (Exception e) {
13243            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13244            e.printStackTrace();
13245        } finally {
13246            Binder.restoreCallingIdentity(oldIdent);
13247        }
13248    }
13249
13250    // done with this agent
13251    public void unbindBackupAgent(ApplicationInfo appInfo) {
13252        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13253        if (appInfo == null) {
13254            Slog.w(TAG, "unbind backup agent for null app");
13255            return;
13256        }
13257
13258        synchronized(this) {
13259            try {
13260                if (mBackupAppName == null) {
13261                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13262                    return;
13263                }
13264
13265                if (!mBackupAppName.equals(appInfo.packageName)) {
13266                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13267                    return;
13268                }
13269
13270                // Not backing this app up any more; reset its OOM adjustment
13271                final ProcessRecord proc = mBackupTarget.app;
13272                updateOomAdjLocked(proc);
13273
13274                // If the app crashed during backup, 'thread' will be null here
13275                if (proc.thread != null) {
13276                    try {
13277                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13278                                compatibilityInfoForPackageLocked(appInfo));
13279                    } catch (Exception e) {
13280                        Slog.e(TAG, "Exception when unbinding backup agent:");
13281                        e.printStackTrace();
13282                    }
13283                }
13284            } finally {
13285                mBackupTarget = null;
13286                mBackupAppName = null;
13287            }
13288        }
13289    }
13290    // =========================================================
13291    // BROADCASTS
13292    // =========================================================
13293
13294    private final List getStickiesLocked(String action, IntentFilter filter,
13295            List cur, int userId) {
13296        final ContentResolver resolver = mContext.getContentResolver();
13297        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13298        if (stickies == null) {
13299            return cur;
13300        }
13301        final ArrayList<Intent> list = stickies.get(action);
13302        if (list == null) {
13303            return cur;
13304        }
13305        int N = list.size();
13306        for (int i=0; i<N; i++) {
13307            Intent intent = list.get(i);
13308            if (filter.match(resolver, intent, true, TAG) >= 0) {
13309                if (cur == null) {
13310                    cur = new ArrayList<Intent>();
13311                }
13312                cur.add(intent);
13313            }
13314        }
13315        return cur;
13316    }
13317
13318    boolean isPendingBroadcastProcessLocked(int pid) {
13319        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13320                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13321    }
13322
13323    void skipPendingBroadcastLocked(int pid) {
13324            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13325            for (BroadcastQueue queue : mBroadcastQueues) {
13326                queue.skipPendingBroadcastLocked(pid);
13327            }
13328    }
13329
13330    // The app just attached; send any pending broadcasts that it should receive
13331    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13332        boolean didSomething = false;
13333        for (BroadcastQueue queue : mBroadcastQueues) {
13334            didSomething |= queue.sendPendingBroadcastsLocked(app);
13335        }
13336        return didSomething;
13337    }
13338
13339    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13340            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13341        enforceNotIsolatedCaller("registerReceiver");
13342        int callingUid;
13343        int callingPid;
13344        synchronized(this) {
13345            ProcessRecord callerApp = null;
13346            if (caller != null) {
13347                callerApp = getRecordForAppLocked(caller);
13348                if (callerApp == null) {
13349                    throw new SecurityException(
13350                            "Unable to find app for caller " + caller
13351                            + " (pid=" + Binder.getCallingPid()
13352                            + ") when registering receiver " + receiver);
13353                }
13354                if (callerApp.info.uid != Process.SYSTEM_UID &&
13355                        !callerApp.pkgList.containsKey(callerPackage) &&
13356                        !"android".equals(callerPackage)) {
13357                    throw new SecurityException("Given caller package " + callerPackage
13358                            + " is not running in process " + callerApp);
13359                }
13360                callingUid = callerApp.info.uid;
13361                callingPid = callerApp.pid;
13362            } else {
13363                callerPackage = null;
13364                callingUid = Binder.getCallingUid();
13365                callingPid = Binder.getCallingPid();
13366            }
13367
13368            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13369                    true, true, "registerReceiver", callerPackage);
13370
13371            List allSticky = null;
13372
13373            // Look for any matching sticky broadcasts...
13374            Iterator actions = filter.actionsIterator();
13375            if (actions != null) {
13376                while (actions.hasNext()) {
13377                    String action = (String)actions.next();
13378                    allSticky = getStickiesLocked(action, filter, allSticky,
13379                            UserHandle.USER_ALL);
13380                    allSticky = getStickiesLocked(action, filter, allSticky,
13381                            UserHandle.getUserId(callingUid));
13382                }
13383            } else {
13384                allSticky = getStickiesLocked(null, filter, allSticky,
13385                        UserHandle.USER_ALL);
13386                allSticky = getStickiesLocked(null, filter, allSticky,
13387                        UserHandle.getUserId(callingUid));
13388            }
13389
13390            // The first sticky in the list is returned directly back to
13391            // the client.
13392            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13393
13394            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13395                    + ": " + sticky);
13396
13397            if (receiver == null) {
13398                return sticky;
13399            }
13400
13401            ReceiverList rl
13402                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13403            if (rl == null) {
13404                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13405                        userId, receiver);
13406                if (rl.app != null) {
13407                    rl.app.receivers.add(rl);
13408                } else {
13409                    try {
13410                        receiver.asBinder().linkToDeath(rl, 0);
13411                    } catch (RemoteException e) {
13412                        return sticky;
13413                    }
13414                    rl.linkedToDeath = true;
13415                }
13416                mRegisteredReceivers.put(receiver.asBinder(), rl);
13417            } else if (rl.uid != callingUid) {
13418                throw new IllegalArgumentException(
13419                        "Receiver requested to register for uid " + callingUid
13420                        + " was previously registered for uid " + rl.uid);
13421            } else if (rl.pid != callingPid) {
13422                throw new IllegalArgumentException(
13423                        "Receiver requested to register for pid " + callingPid
13424                        + " was previously registered for pid " + rl.pid);
13425            } else if (rl.userId != userId) {
13426                throw new IllegalArgumentException(
13427                        "Receiver requested to register for user " + userId
13428                        + " was previously registered for user " + rl.userId);
13429            }
13430            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13431                    permission, callingUid, userId);
13432            rl.add(bf);
13433            if (!bf.debugCheck()) {
13434                Slog.w(TAG, "==> For Dynamic broadast");
13435            }
13436            mReceiverResolver.addFilter(bf);
13437
13438            // Enqueue broadcasts for all existing stickies that match
13439            // this filter.
13440            if (allSticky != null) {
13441                ArrayList receivers = new ArrayList();
13442                receivers.add(bf);
13443
13444                int N = allSticky.size();
13445                for (int i=0; i<N; i++) {
13446                    Intent intent = (Intent)allSticky.get(i);
13447                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13448                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13449                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13450                            null, null, false, true, true, -1);
13451                    queue.enqueueParallelBroadcastLocked(r);
13452                    queue.scheduleBroadcastsLocked();
13453                }
13454            }
13455
13456            return sticky;
13457        }
13458    }
13459
13460    public void unregisterReceiver(IIntentReceiver receiver) {
13461        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13462
13463        final long origId = Binder.clearCallingIdentity();
13464        try {
13465            boolean doTrim = false;
13466
13467            synchronized(this) {
13468                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13469                if (rl != null) {
13470                    if (rl.curBroadcast != null) {
13471                        BroadcastRecord r = rl.curBroadcast;
13472                        final boolean doNext = finishReceiverLocked(
13473                                receiver.asBinder(), r.resultCode, r.resultData,
13474                                r.resultExtras, r.resultAbort);
13475                        if (doNext) {
13476                            doTrim = true;
13477                            r.queue.processNextBroadcast(false);
13478                        }
13479                    }
13480
13481                    if (rl.app != null) {
13482                        rl.app.receivers.remove(rl);
13483                    }
13484                    removeReceiverLocked(rl);
13485                    if (rl.linkedToDeath) {
13486                        rl.linkedToDeath = false;
13487                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13488                    }
13489                }
13490            }
13491
13492            // If we actually concluded any broadcasts, we might now be able
13493            // to trim the recipients' apps from our working set
13494            if (doTrim) {
13495                trimApplications();
13496                return;
13497            }
13498
13499        } finally {
13500            Binder.restoreCallingIdentity(origId);
13501        }
13502    }
13503
13504    void removeReceiverLocked(ReceiverList rl) {
13505        mRegisteredReceivers.remove(rl.receiver.asBinder());
13506        int N = rl.size();
13507        for (int i=0; i<N; i++) {
13508            mReceiverResolver.removeFilter(rl.get(i));
13509        }
13510    }
13511
13512    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13513        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13514            ProcessRecord r = mLruProcesses.get(i);
13515            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13516                try {
13517                    r.thread.dispatchPackageBroadcast(cmd, packages);
13518                } catch (RemoteException ex) {
13519                }
13520            }
13521        }
13522    }
13523
13524    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13525            int[] users) {
13526        List<ResolveInfo> receivers = null;
13527        try {
13528            HashSet<ComponentName> singleUserReceivers = null;
13529            boolean scannedFirstReceivers = false;
13530            for (int user : users) {
13531                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13532                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13533                if (user != 0 && newReceivers != null) {
13534                    // If this is not the primary user, we need to check for
13535                    // any receivers that should be filtered out.
13536                    for (int i=0; i<newReceivers.size(); i++) {
13537                        ResolveInfo ri = newReceivers.get(i);
13538                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13539                            newReceivers.remove(i);
13540                            i--;
13541                        }
13542                    }
13543                }
13544                if (newReceivers != null && newReceivers.size() == 0) {
13545                    newReceivers = null;
13546                }
13547                if (receivers == null) {
13548                    receivers = newReceivers;
13549                } else if (newReceivers != null) {
13550                    // We need to concatenate the additional receivers
13551                    // found with what we have do far.  This would be easy,
13552                    // but we also need to de-dup any receivers that are
13553                    // singleUser.
13554                    if (!scannedFirstReceivers) {
13555                        // Collect any single user receivers we had already retrieved.
13556                        scannedFirstReceivers = true;
13557                        for (int i=0; i<receivers.size(); i++) {
13558                            ResolveInfo ri = receivers.get(i);
13559                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13560                                ComponentName cn = new ComponentName(
13561                                        ri.activityInfo.packageName, ri.activityInfo.name);
13562                                if (singleUserReceivers == null) {
13563                                    singleUserReceivers = new HashSet<ComponentName>();
13564                                }
13565                                singleUserReceivers.add(cn);
13566                            }
13567                        }
13568                    }
13569                    // Add the new results to the existing results, tracking
13570                    // and de-dupping single user receivers.
13571                    for (int i=0; i<newReceivers.size(); i++) {
13572                        ResolveInfo ri = newReceivers.get(i);
13573                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13574                            ComponentName cn = new ComponentName(
13575                                    ri.activityInfo.packageName, ri.activityInfo.name);
13576                            if (singleUserReceivers == null) {
13577                                singleUserReceivers = new HashSet<ComponentName>();
13578                            }
13579                            if (!singleUserReceivers.contains(cn)) {
13580                                singleUserReceivers.add(cn);
13581                                receivers.add(ri);
13582                            }
13583                        } else {
13584                            receivers.add(ri);
13585                        }
13586                    }
13587                }
13588            }
13589        } catch (RemoteException ex) {
13590            // pm is in same process, this will never happen.
13591        }
13592        return receivers;
13593    }
13594
13595    private final int broadcastIntentLocked(ProcessRecord callerApp,
13596            String callerPackage, Intent intent, String resolvedType,
13597            IIntentReceiver resultTo, int resultCode, String resultData,
13598            Bundle map, String requiredPermission, int appOp,
13599            boolean ordered, boolean sticky, int callingPid, int callingUid,
13600            int userId) {
13601        intent = new Intent(intent);
13602
13603        // By default broadcasts do not go to stopped apps.
13604        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13605
13606        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13607            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13608            + " ordered=" + ordered + " userid=" + userId);
13609        if ((resultTo != null) && !ordered) {
13610            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13611        }
13612
13613        userId = handleIncomingUser(callingPid, callingUid, userId,
13614                true, false, "broadcast", callerPackage);
13615
13616        // Make sure that the user who is receiving this broadcast is started.
13617        // If not, we will just skip it.
13618        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13619            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13620                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13621                Slog.w(TAG, "Skipping broadcast of " + intent
13622                        + ": user " + userId + " is stopped");
13623                return ActivityManager.BROADCAST_SUCCESS;
13624            }
13625        }
13626
13627        /*
13628         * Prevent non-system code (defined here to be non-persistent
13629         * processes) from sending protected broadcasts.
13630         */
13631        int callingAppId = UserHandle.getAppId(callingUid);
13632        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13633            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13634            callingUid == 0) {
13635            // Always okay.
13636        } else if (callerApp == null || !callerApp.persistent) {
13637            try {
13638                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13639                        intent.getAction())) {
13640                    String msg = "Permission Denial: not allowed to send broadcast "
13641                            + intent.getAction() + " from pid="
13642                            + callingPid + ", uid=" + callingUid;
13643                    Slog.w(TAG, msg);
13644                    throw new SecurityException(msg);
13645                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13646                    // Special case for compatibility: we don't want apps to send this,
13647                    // but historically it has not been protected and apps may be using it
13648                    // to poke their own app widget.  So, instead of making it protected,
13649                    // just limit it to the caller.
13650                    if (callerApp == null) {
13651                        String msg = "Permission Denial: not allowed to send broadcast "
13652                                + intent.getAction() + " from unknown caller.";
13653                        Slog.w(TAG, msg);
13654                        throw new SecurityException(msg);
13655                    } else if (intent.getComponent() != null) {
13656                        // They are good enough to send to an explicit component...  verify
13657                        // it is being sent to the calling app.
13658                        if (!intent.getComponent().getPackageName().equals(
13659                                callerApp.info.packageName)) {
13660                            String msg = "Permission Denial: not allowed to send broadcast "
13661                                    + intent.getAction() + " to "
13662                                    + intent.getComponent().getPackageName() + " from "
13663                                    + callerApp.info.packageName;
13664                            Slog.w(TAG, msg);
13665                            throw new SecurityException(msg);
13666                        }
13667                    } else {
13668                        // Limit broadcast to their own package.
13669                        intent.setPackage(callerApp.info.packageName);
13670                    }
13671                }
13672            } catch (RemoteException e) {
13673                Slog.w(TAG, "Remote exception", e);
13674                return ActivityManager.BROADCAST_SUCCESS;
13675            }
13676        }
13677
13678        // Handle special intents: if this broadcast is from the package
13679        // manager about a package being removed, we need to remove all of
13680        // its activities from the history stack.
13681        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13682                intent.getAction());
13683        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13684                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13685                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13686                || uidRemoved) {
13687            if (checkComponentPermission(
13688                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13689                    callingPid, callingUid, -1, true)
13690                    == PackageManager.PERMISSION_GRANTED) {
13691                if (uidRemoved) {
13692                    final Bundle intentExtras = intent.getExtras();
13693                    final int uid = intentExtras != null
13694                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13695                    if (uid >= 0) {
13696                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13697                        synchronized (bs) {
13698                            bs.removeUidStatsLocked(uid);
13699                        }
13700                        mAppOpsService.uidRemoved(uid);
13701                    }
13702                } else {
13703                    // If resources are unavailable just force stop all
13704                    // those packages and flush the attribute cache as well.
13705                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13706                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13707                        if (list != null && (list.length > 0)) {
13708                            for (String pkg : list) {
13709                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13710                                        "storage unmount");
13711                            }
13712                            sendPackageBroadcastLocked(
13713                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13714                        }
13715                    } else {
13716                        Uri data = intent.getData();
13717                        String ssp;
13718                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13719                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13720                                    intent.getAction());
13721                            boolean fullUninstall = removed &&
13722                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13723                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13724                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13725                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13726                                        false, fullUninstall, userId,
13727                                        removed ? "pkg removed" : "pkg changed");
13728                            }
13729                            if (removed) {
13730                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13731                                        new String[] {ssp}, userId);
13732                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13733                                    mAppOpsService.packageRemoved(
13734                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13735
13736                                    // Remove all permissions granted from/to this package
13737                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13738                                }
13739                            }
13740                        }
13741                    }
13742                }
13743            } else {
13744                String msg = "Permission Denial: " + intent.getAction()
13745                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13746                        + ", uid=" + callingUid + ")"
13747                        + " requires "
13748                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13749                Slog.w(TAG, msg);
13750                throw new SecurityException(msg);
13751            }
13752
13753        // Special case for adding a package: by default turn on compatibility
13754        // mode.
13755        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13756            Uri data = intent.getData();
13757            String ssp;
13758            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13759                mCompatModePackages.handlePackageAddedLocked(ssp,
13760                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13761            }
13762        }
13763
13764        /*
13765         * If this is the time zone changed action, queue up a message that will reset the timezone
13766         * of all currently running processes. This message will get queued up before the broadcast
13767         * happens.
13768         */
13769        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13770            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13771        }
13772
13773        /*
13774         * If the user set the time, let all running processes know.
13775         */
13776        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
13777            final int is24Hour = intent.getBooleanExtra(
13778                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
13779            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
13780        }
13781
13782        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13783            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13784        }
13785
13786        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13787            ProxyInfo proxy = intent.getParcelableExtra("proxy");
13788            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13789        }
13790
13791        // Add to the sticky list if requested.
13792        if (sticky) {
13793            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13794                    callingPid, callingUid)
13795                    != PackageManager.PERMISSION_GRANTED) {
13796                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13797                        + callingPid + ", uid=" + callingUid
13798                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13799                Slog.w(TAG, msg);
13800                throw new SecurityException(msg);
13801            }
13802            if (requiredPermission != null) {
13803                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13804                        + " and enforce permission " + requiredPermission);
13805                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13806            }
13807            if (intent.getComponent() != null) {
13808                throw new SecurityException(
13809                        "Sticky broadcasts can't target a specific component");
13810            }
13811            // We use userId directly here, since the "all" target is maintained
13812            // as a separate set of sticky broadcasts.
13813            if (userId != UserHandle.USER_ALL) {
13814                // But first, if this is not a broadcast to all users, then
13815                // make sure it doesn't conflict with an existing broadcast to
13816                // all users.
13817                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13818                        UserHandle.USER_ALL);
13819                if (stickies != null) {
13820                    ArrayList<Intent> list = stickies.get(intent.getAction());
13821                    if (list != null) {
13822                        int N = list.size();
13823                        int i;
13824                        for (i=0; i<N; i++) {
13825                            if (intent.filterEquals(list.get(i))) {
13826                                throw new IllegalArgumentException(
13827                                        "Sticky broadcast " + intent + " for user "
13828                                        + userId + " conflicts with existing global broadcast");
13829                            }
13830                        }
13831                    }
13832                }
13833            }
13834            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13835            if (stickies == null) {
13836                stickies = new ArrayMap<String, ArrayList<Intent>>();
13837                mStickyBroadcasts.put(userId, stickies);
13838            }
13839            ArrayList<Intent> list = stickies.get(intent.getAction());
13840            if (list == null) {
13841                list = new ArrayList<Intent>();
13842                stickies.put(intent.getAction(), list);
13843            }
13844            int N = list.size();
13845            int i;
13846            for (i=0; i<N; i++) {
13847                if (intent.filterEquals(list.get(i))) {
13848                    // This sticky already exists, replace it.
13849                    list.set(i, new Intent(intent));
13850                    break;
13851                }
13852            }
13853            if (i >= N) {
13854                list.add(new Intent(intent));
13855            }
13856        }
13857
13858        int[] users;
13859        if (userId == UserHandle.USER_ALL) {
13860            // Caller wants broadcast to go to all started users.
13861            users = mStartedUserArray;
13862        } else {
13863            // Caller wants broadcast to go to one specific user.
13864            users = new int[] {userId};
13865        }
13866
13867        // Figure out who all will receive this broadcast.
13868        List receivers = null;
13869        List<BroadcastFilter> registeredReceivers = null;
13870        // Need to resolve the intent to interested receivers...
13871        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13872                 == 0) {
13873            receivers = collectReceiverComponents(intent, resolvedType, users);
13874        }
13875        if (intent.getComponent() == null) {
13876            registeredReceivers = mReceiverResolver.queryIntent(intent,
13877                    resolvedType, false, userId);
13878        }
13879
13880        final boolean replacePending =
13881                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13882
13883        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13884                + " replacePending=" + replacePending);
13885
13886        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13887        if (!ordered && NR > 0) {
13888            // If we are not serializing this broadcast, then send the
13889            // registered receivers separately so they don't wait for the
13890            // components to be launched.
13891            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13892            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13893                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13894                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13895                    ordered, sticky, false, userId);
13896            if (DEBUG_BROADCAST) Slog.v(
13897                    TAG, "Enqueueing parallel broadcast " + r);
13898            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13899            if (!replaced) {
13900                queue.enqueueParallelBroadcastLocked(r);
13901                queue.scheduleBroadcastsLocked();
13902            }
13903            registeredReceivers = null;
13904            NR = 0;
13905        }
13906
13907        // Merge into one list.
13908        int ir = 0;
13909        if (receivers != null) {
13910            // A special case for PACKAGE_ADDED: do not allow the package
13911            // being added to see this broadcast.  This prevents them from
13912            // using this as a back door to get run as soon as they are
13913            // installed.  Maybe in the future we want to have a special install
13914            // broadcast or such for apps, but we'd like to deliberately make
13915            // this decision.
13916            String skipPackages[] = null;
13917            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13918                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13919                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13920                Uri data = intent.getData();
13921                if (data != null) {
13922                    String pkgName = data.getSchemeSpecificPart();
13923                    if (pkgName != null) {
13924                        skipPackages = new String[] { pkgName };
13925                    }
13926                }
13927            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13928                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13929            }
13930            if (skipPackages != null && (skipPackages.length > 0)) {
13931                for (String skipPackage : skipPackages) {
13932                    if (skipPackage != null) {
13933                        int NT = receivers.size();
13934                        for (int it=0; it<NT; it++) {
13935                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
13936                            if (curt.activityInfo.packageName.equals(skipPackage)) {
13937                                receivers.remove(it);
13938                                it--;
13939                                NT--;
13940                            }
13941                        }
13942                    }
13943                }
13944            }
13945
13946            int NT = receivers != null ? receivers.size() : 0;
13947            int it = 0;
13948            ResolveInfo curt = null;
13949            BroadcastFilter curr = null;
13950            while (it < NT && ir < NR) {
13951                if (curt == null) {
13952                    curt = (ResolveInfo)receivers.get(it);
13953                }
13954                if (curr == null) {
13955                    curr = registeredReceivers.get(ir);
13956                }
13957                if (curr.getPriority() >= curt.priority) {
13958                    // Insert this broadcast record into the final list.
13959                    receivers.add(it, curr);
13960                    ir++;
13961                    curr = null;
13962                    it++;
13963                    NT++;
13964                } else {
13965                    // Skip to the next ResolveInfo in the final list.
13966                    it++;
13967                    curt = null;
13968                }
13969            }
13970        }
13971        while (ir < NR) {
13972            if (receivers == null) {
13973                receivers = new ArrayList();
13974            }
13975            receivers.add(registeredReceivers.get(ir));
13976            ir++;
13977        }
13978
13979        if ((receivers != null && receivers.size() > 0)
13980                || resultTo != null) {
13981            BroadcastQueue queue = broadcastQueueForIntent(intent);
13982            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13983                    callerPackage, callingPid, callingUid, resolvedType,
13984                    requiredPermission, appOp, receivers, resultTo, resultCode,
13985                    resultData, map, ordered, sticky, false, userId);
13986            if (DEBUG_BROADCAST) Slog.v(
13987                    TAG, "Enqueueing ordered broadcast " + r
13988                    + ": prev had " + queue.mOrderedBroadcasts.size());
13989            if (DEBUG_BROADCAST) {
13990                int seq = r.intent.getIntExtra("seq", -1);
13991                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
13992            }
13993            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
13994            if (!replaced) {
13995                queue.enqueueOrderedBroadcastLocked(r);
13996                queue.scheduleBroadcastsLocked();
13997            }
13998        }
13999
14000        return ActivityManager.BROADCAST_SUCCESS;
14001    }
14002
14003    final Intent verifyBroadcastLocked(Intent intent) {
14004        // Refuse possible leaked file descriptors
14005        if (intent != null && intent.hasFileDescriptors() == true) {
14006            throw new IllegalArgumentException("File descriptors passed in Intent");
14007        }
14008
14009        int flags = intent.getFlags();
14010
14011        if (!mProcessesReady) {
14012            // if the caller really truly claims to know what they're doing, go
14013            // ahead and allow the broadcast without launching any receivers
14014            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14015                intent = new Intent(intent);
14016                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14017            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14018                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14019                        + " before boot completion");
14020                throw new IllegalStateException("Cannot broadcast before boot completed");
14021            }
14022        }
14023
14024        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14025            throw new IllegalArgumentException(
14026                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14027        }
14028
14029        return intent;
14030    }
14031
14032    public final int broadcastIntent(IApplicationThread caller,
14033            Intent intent, String resolvedType, IIntentReceiver resultTo,
14034            int resultCode, String resultData, Bundle map,
14035            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14036        enforceNotIsolatedCaller("broadcastIntent");
14037        synchronized(this) {
14038            intent = verifyBroadcastLocked(intent);
14039
14040            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14041            final int callingPid = Binder.getCallingPid();
14042            final int callingUid = Binder.getCallingUid();
14043            final long origId = Binder.clearCallingIdentity();
14044            int res = broadcastIntentLocked(callerApp,
14045                    callerApp != null ? callerApp.info.packageName : null,
14046                    intent, resolvedType, resultTo,
14047                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14048                    callingPid, callingUid, userId);
14049            Binder.restoreCallingIdentity(origId);
14050            return res;
14051        }
14052    }
14053
14054    int broadcastIntentInPackage(String packageName, int uid,
14055            Intent intent, String resolvedType, IIntentReceiver resultTo,
14056            int resultCode, String resultData, Bundle map,
14057            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14058        synchronized(this) {
14059            intent = verifyBroadcastLocked(intent);
14060
14061            final long origId = Binder.clearCallingIdentity();
14062            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14063                    resultTo, resultCode, resultData, map, requiredPermission,
14064                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14065            Binder.restoreCallingIdentity(origId);
14066            return res;
14067        }
14068    }
14069
14070    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14071        // Refuse possible leaked file descriptors
14072        if (intent != null && intent.hasFileDescriptors() == true) {
14073            throw new IllegalArgumentException("File descriptors passed in Intent");
14074        }
14075
14076        userId = handleIncomingUser(Binder.getCallingPid(),
14077                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
14078
14079        synchronized(this) {
14080            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14081                    != PackageManager.PERMISSION_GRANTED) {
14082                String msg = "Permission Denial: unbroadcastIntent() from pid="
14083                        + Binder.getCallingPid()
14084                        + ", uid=" + Binder.getCallingUid()
14085                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14086                Slog.w(TAG, msg);
14087                throw new SecurityException(msg);
14088            }
14089            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14090            if (stickies != null) {
14091                ArrayList<Intent> list = stickies.get(intent.getAction());
14092                if (list != null) {
14093                    int N = list.size();
14094                    int i;
14095                    for (i=0; i<N; i++) {
14096                        if (intent.filterEquals(list.get(i))) {
14097                            list.remove(i);
14098                            break;
14099                        }
14100                    }
14101                    if (list.size() <= 0) {
14102                        stickies.remove(intent.getAction());
14103                    }
14104                }
14105                if (stickies.size() <= 0) {
14106                    mStickyBroadcasts.remove(userId);
14107                }
14108            }
14109        }
14110    }
14111
14112    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14113            String resultData, Bundle resultExtras, boolean resultAbort) {
14114        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14115        if (r == null) {
14116            Slog.w(TAG, "finishReceiver called but not found on queue");
14117            return false;
14118        }
14119
14120        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14121    }
14122
14123    void backgroundServicesFinishedLocked(int userId) {
14124        for (BroadcastQueue queue : mBroadcastQueues) {
14125            queue.backgroundServicesFinishedLocked(userId);
14126        }
14127    }
14128
14129    public void finishReceiver(IBinder who, int resultCode, String resultData,
14130            Bundle resultExtras, boolean resultAbort) {
14131        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14132
14133        // Refuse possible leaked file descriptors
14134        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14135            throw new IllegalArgumentException("File descriptors passed in Bundle");
14136        }
14137
14138        final long origId = Binder.clearCallingIdentity();
14139        try {
14140            boolean doNext = false;
14141            BroadcastRecord r;
14142
14143            synchronized(this) {
14144                r = broadcastRecordForReceiverLocked(who);
14145                if (r != null) {
14146                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14147                        resultData, resultExtras, resultAbort, true);
14148                }
14149            }
14150
14151            if (doNext) {
14152                r.queue.processNextBroadcast(false);
14153            }
14154            trimApplications();
14155        } finally {
14156            Binder.restoreCallingIdentity(origId);
14157        }
14158    }
14159
14160    // =========================================================
14161    // INSTRUMENTATION
14162    // =========================================================
14163
14164    public boolean startInstrumentation(ComponentName className,
14165            String profileFile, int flags, Bundle arguments,
14166            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14167            int userId) {
14168        enforceNotIsolatedCaller("startInstrumentation");
14169        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14170                userId, false, true, "startInstrumentation", null);
14171        // Refuse possible leaked file descriptors
14172        if (arguments != null && arguments.hasFileDescriptors()) {
14173            throw new IllegalArgumentException("File descriptors passed in Bundle");
14174        }
14175
14176        synchronized(this) {
14177            InstrumentationInfo ii = null;
14178            ApplicationInfo ai = null;
14179            try {
14180                ii = mContext.getPackageManager().getInstrumentationInfo(
14181                    className, STOCK_PM_FLAGS);
14182                ai = AppGlobals.getPackageManager().getApplicationInfo(
14183                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14184            } catch (PackageManager.NameNotFoundException e) {
14185            } catch (RemoteException e) {
14186            }
14187            if (ii == null) {
14188                reportStartInstrumentationFailure(watcher, className,
14189                        "Unable to find instrumentation info for: " + className);
14190                return false;
14191            }
14192            if (ai == null) {
14193                reportStartInstrumentationFailure(watcher, className,
14194                        "Unable to find instrumentation target package: " + ii.targetPackage);
14195                return false;
14196            }
14197
14198            int match = mContext.getPackageManager().checkSignatures(
14199                    ii.targetPackage, ii.packageName);
14200            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14201                String msg = "Permission Denial: starting instrumentation "
14202                        + className + " from pid="
14203                        + Binder.getCallingPid()
14204                        + ", uid=" + Binder.getCallingPid()
14205                        + " not allowed because package " + ii.packageName
14206                        + " does not have a signature matching the target "
14207                        + ii.targetPackage;
14208                reportStartInstrumentationFailure(watcher, className, msg);
14209                throw new SecurityException(msg);
14210            }
14211
14212            final long origId = Binder.clearCallingIdentity();
14213            // Instrumentation can kill and relaunch even persistent processes
14214            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14215                    "start instr");
14216            ProcessRecord app = addAppLocked(ai, false);
14217            app.instrumentationClass = className;
14218            app.instrumentationInfo = ai;
14219            app.instrumentationProfileFile = profileFile;
14220            app.instrumentationArguments = arguments;
14221            app.instrumentationWatcher = watcher;
14222            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14223            app.instrumentationResultClass = className;
14224            Binder.restoreCallingIdentity(origId);
14225        }
14226
14227        return true;
14228    }
14229
14230    /**
14231     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14232     * error to the logs, but if somebody is watching, send the report there too.  This enables
14233     * the "am" command to report errors with more information.
14234     *
14235     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14236     * @param cn The component name of the instrumentation.
14237     * @param report The error report.
14238     */
14239    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14240            ComponentName cn, String report) {
14241        Slog.w(TAG, report);
14242        try {
14243            if (watcher != null) {
14244                Bundle results = new Bundle();
14245                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14246                results.putString("Error", report);
14247                watcher.instrumentationStatus(cn, -1, results);
14248            }
14249        } catch (RemoteException e) {
14250            Slog.w(TAG, e);
14251        }
14252    }
14253
14254    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14255        if (app.instrumentationWatcher != null) {
14256            try {
14257                // NOTE:  IInstrumentationWatcher *must* be oneway here
14258                app.instrumentationWatcher.instrumentationFinished(
14259                    app.instrumentationClass,
14260                    resultCode,
14261                    results);
14262            } catch (RemoteException e) {
14263            }
14264        }
14265        if (app.instrumentationUiAutomationConnection != null) {
14266            try {
14267                app.instrumentationUiAutomationConnection.shutdown();
14268            } catch (RemoteException re) {
14269                /* ignore */
14270            }
14271            // Only a UiAutomation can set this flag and now that
14272            // it is finished we make sure it is reset to its default.
14273            mUserIsMonkey = false;
14274        }
14275        app.instrumentationWatcher = null;
14276        app.instrumentationUiAutomationConnection = null;
14277        app.instrumentationClass = null;
14278        app.instrumentationInfo = null;
14279        app.instrumentationProfileFile = null;
14280        app.instrumentationArguments = null;
14281
14282        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14283                "finished inst");
14284    }
14285
14286    public void finishInstrumentation(IApplicationThread target,
14287            int resultCode, Bundle results) {
14288        int userId = UserHandle.getCallingUserId();
14289        // Refuse possible leaked file descriptors
14290        if (results != null && results.hasFileDescriptors()) {
14291            throw new IllegalArgumentException("File descriptors passed in Intent");
14292        }
14293
14294        synchronized(this) {
14295            ProcessRecord app = getRecordForAppLocked(target);
14296            if (app == null) {
14297                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14298                return;
14299            }
14300            final long origId = Binder.clearCallingIdentity();
14301            finishInstrumentationLocked(app, resultCode, results);
14302            Binder.restoreCallingIdentity(origId);
14303        }
14304    }
14305
14306    // =========================================================
14307    // CONFIGURATION
14308    // =========================================================
14309
14310    public ConfigurationInfo getDeviceConfigurationInfo() {
14311        ConfigurationInfo config = new ConfigurationInfo();
14312        synchronized (this) {
14313            config.reqTouchScreen = mConfiguration.touchscreen;
14314            config.reqKeyboardType = mConfiguration.keyboard;
14315            config.reqNavigation = mConfiguration.navigation;
14316            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14317                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14318                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14319            }
14320            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14321                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14322                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14323            }
14324            config.reqGlEsVersion = GL_ES_VERSION;
14325        }
14326        return config;
14327    }
14328
14329    ActivityStack getFocusedStack() {
14330        return mStackSupervisor.getFocusedStack();
14331    }
14332
14333    public Configuration getConfiguration() {
14334        Configuration ci;
14335        synchronized(this) {
14336            ci = new Configuration(mConfiguration);
14337        }
14338        return ci;
14339    }
14340
14341    public void updatePersistentConfiguration(Configuration values) {
14342        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14343                "updateConfiguration()");
14344        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14345                "updateConfiguration()");
14346        if (values == null) {
14347            throw new NullPointerException("Configuration must not be null");
14348        }
14349
14350        synchronized(this) {
14351            final long origId = Binder.clearCallingIdentity();
14352            updateConfigurationLocked(values, null, true, false);
14353            Binder.restoreCallingIdentity(origId);
14354        }
14355    }
14356
14357    public void updateConfiguration(Configuration values) {
14358        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14359                "updateConfiguration()");
14360
14361        synchronized(this) {
14362            if (values == null && mWindowManager != null) {
14363                // sentinel: fetch the current configuration from the window manager
14364                values = mWindowManager.computeNewConfiguration();
14365            }
14366
14367            if (mWindowManager != null) {
14368                mProcessList.applyDisplaySize(mWindowManager);
14369            }
14370
14371            final long origId = Binder.clearCallingIdentity();
14372            if (values != null) {
14373                Settings.System.clearConfiguration(values);
14374            }
14375            updateConfigurationLocked(values, null, false, false);
14376            Binder.restoreCallingIdentity(origId);
14377        }
14378    }
14379
14380    /**
14381     * Do either or both things: (1) change the current configuration, and (2)
14382     * make sure the given activity is running with the (now) current
14383     * configuration.  Returns true if the activity has been left running, or
14384     * false if <var>starting</var> is being destroyed to match the new
14385     * configuration.
14386     * @param persistent TODO
14387     */
14388    boolean updateConfigurationLocked(Configuration values,
14389            ActivityRecord starting, boolean persistent, boolean initLocale) {
14390        int changes = 0;
14391
14392        if (values != null) {
14393            Configuration newConfig = new Configuration(mConfiguration);
14394            changes = newConfig.updateFrom(values);
14395            if (changes != 0) {
14396                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14397                    Slog.i(TAG, "Updating configuration to: " + values);
14398                }
14399
14400                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14401
14402                if (values.locale != null && !initLocale) {
14403                    saveLocaleLocked(values.locale,
14404                                     !values.locale.equals(mConfiguration.locale),
14405                                     values.userSetLocale);
14406                }
14407
14408                mConfigurationSeq++;
14409                if (mConfigurationSeq <= 0) {
14410                    mConfigurationSeq = 1;
14411                }
14412                newConfig.seq = mConfigurationSeq;
14413                mConfiguration = newConfig;
14414                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14415                mUsageStatsService.noteStartConfig(newConfig);
14416
14417                final Configuration configCopy = new Configuration(mConfiguration);
14418
14419                // TODO: If our config changes, should we auto dismiss any currently
14420                // showing dialogs?
14421                mShowDialogs = shouldShowDialogs(newConfig);
14422
14423                AttributeCache ac = AttributeCache.instance();
14424                if (ac != null) {
14425                    ac.updateConfiguration(configCopy);
14426                }
14427
14428                // Make sure all resources in our process are updated
14429                // right now, so that anyone who is going to retrieve
14430                // resource values after we return will be sure to get
14431                // the new ones.  This is especially important during
14432                // boot, where the first config change needs to guarantee
14433                // all resources have that config before following boot
14434                // code is executed.
14435                mSystemThread.applyConfigurationToResources(configCopy);
14436
14437                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14438                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14439                    msg.obj = new Configuration(configCopy);
14440                    mHandler.sendMessage(msg);
14441                }
14442
14443                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14444                    ProcessRecord app = mLruProcesses.get(i);
14445                    try {
14446                        if (app.thread != null) {
14447                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14448                                    + app.processName + " new config " + mConfiguration);
14449                            app.thread.scheduleConfigurationChanged(configCopy);
14450                        }
14451                    } catch (Exception e) {
14452                    }
14453                }
14454                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14455                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14456                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14457                        | Intent.FLAG_RECEIVER_FOREGROUND);
14458                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14459                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14460                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14461                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14462                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14463                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14464                    broadcastIntentLocked(null, null, intent,
14465                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14466                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14467                }
14468            }
14469        }
14470
14471        boolean kept = true;
14472        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14473        // mainStack is null during startup.
14474        if (mainStack != null) {
14475            if (changes != 0 && starting == null) {
14476                // If the configuration changed, and the caller is not already
14477                // in the process of starting an activity, then find the top
14478                // activity to check if its configuration needs to change.
14479                starting = mainStack.topRunningActivityLocked(null);
14480            }
14481
14482            if (starting != null) {
14483                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14484                // And we need to make sure at this point that all other activities
14485                // are made visible with the correct configuration.
14486                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14487            }
14488        }
14489
14490        if (values != null && mWindowManager != null) {
14491            mWindowManager.setNewConfiguration(mConfiguration);
14492        }
14493
14494        return kept;
14495    }
14496
14497    /**
14498     * Decide based on the configuration whether we should shouw the ANR,
14499     * crash, etc dialogs.  The idea is that if there is no affordnace to
14500     * press the on-screen buttons, we shouldn't show the dialog.
14501     *
14502     * A thought: SystemUI might also want to get told about this, the Power
14503     * dialog / global actions also might want different behaviors.
14504     */
14505    private static final boolean shouldShowDialogs(Configuration config) {
14506        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14507                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14508    }
14509
14510    /**
14511     * Save the locale.  You must be inside a synchronized (this) block.
14512     */
14513    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14514        if(isDiff) {
14515            SystemProperties.set("user.language", l.getLanguage());
14516            SystemProperties.set("user.region", l.getCountry());
14517        }
14518
14519        if(isPersist) {
14520            SystemProperties.set("persist.sys.language", l.getLanguage());
14521            SystemProperties.set("persist.sys.country", l.getCountry());
14522            SystemProperties.set("persist.sys.localevar", l.getVariant());
14523        }
14524    }
14525
14526    @Override
14527    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14528        ActivityRecord srec = ActivityRecord.forToken(token);
14529        return srec != null && srec.task.affinity != null &&
14530                srec.task.affinity.equals(destAffinity);
14531    }
14532
14533    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14534            Intent resultData) {
14535
14536        synchronized (this) {
14537            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14538            if (stack != null) {
14539                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14540            }
14541            return false;
14542        }
14543    }
14544
14545    public int getLaunchedFromUid(IBinder activityToken) {
14546        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14547        if (srec == null) {
14548            return -1;
14549        }
14550        return srec.launchedFromUid;
14551    }
14552
14553    public String getLaunchedFromPackage(IBinder activityToken) {
14554        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14555        if (srec == null) {
14556            return null;
14557        }
14558        return srec.launchedFromPackage;
14559    }
14560
14561    // =========================================================
14562    // LIFETIME MANAGEMENT
14563    // =========================================================
14564
14565    // Returns which broadcast queue the app is the current [or imminent] receiver
14566    // on, or 'null' if the app is not an active broadcast recipient.
14567    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14568        BroadcastRecord r = app.curReceiver;
14569        if (r != null) {
14570            return r.queue;
14571        }
14572
14573        // It's not the current receiver, but it might be starting up to become one
14574        synchronized (this) {
14575            for (BroadcastQueue queue : mBroadcastQueues) {
14576                r = queue.mPendingBroadcast;
14577                if (r != null && r.curApp == app) {
14578                    // found it; report which queue it's in
14579                    return queue;
14580                }
14581            }
14582        }
14583
14584        return null;
14585    }
14586
14587    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14588            boolean doingAll, long now) {
14589        if (mAdjSeq == app.adjSeq) {
14590            // This adjustment has already been computed.
14591            return app.curRawAdj;
14592        }
14593
14594        if (app.thread == null) {
14595            app.adjSeq = mAdjSeq;
14596            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14597            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14598            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14599        }
14600
14601        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14602        app.adjSource = null;
14603        app.adjTarget = null;
14604        app.empty = false;
14605        app.cached = false;
14606
14607        final int activitiesSize = app.activities.size();
14608
14609        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14610            // The max adjustment doesn't allow this app to be anything
14611            // below foreground, so it is not worth doing work for it.
14612            app.adjType = "fixed";
14613            app.adjSeq = mAdjSeq;
14614            app.curRawAdj = app.maxAdj;
14615            app.foregroundActivities = false;
14616            app.keeping = true;
14617            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14618            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14619            // System processes can do UI, and when they do we want to have
14620            // them trim their memory after the user leaves the UI.  To
14621            // facilitate this, here we need to determine whether or not it
14622            // is currently showing UI.
14623            app.systemNoUi = true;
14624            if (app == TOP_APP) {
14625                app.systemNoUi = false;
14626            } else if (activitiesSize > 0) {
14627                for (int j = 0; j < activitiesSize; j++) {
14628                    final ActivityRecord r = app.activities.get(j);
14629                    if (r.visible) {
14630                        app.systemNoUi = false;
14631                    }
14632                }
14633            }
14634            if (!app.systemNoUi) {
14635                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14636            }
14637            return (app.curAdj=app.maxAdj);
14638        }
14639
14640        app.keeping = false;
14641        app.systemNoUi = false;
14642
14643        // Determine the importance of the process, starting with most
14644        // important to least, and assign an appropriate OOM adjustment.
14645        int adj;
14646        int schedGroup;
14647        int procState;
14648        boolean foregroundActivities = false;
14649        boolean interesting = false;
14650        BroadcastQueue queue;
14651        if (app == TOP_APP) {
14652            // The last app on the list is the foreground app.
14653            adj = ProcessList.FOREGROUND_APP_ADJ;
14654            schedGroup = Process.THREAD_GROUP_DEFAULT;
14655            app.adjType = "top-activity";
14656            foregroundActivities = true;
14657            interesting = true;
14658            procState = ActivityManager.PROCESS_STATE_TOP;
14659        } else if (app.instrumentationClass != null) {
14660            // Don't want to kill running instrumentation.
14661            adj = ProcessList.FOREGROUND_APP_ADJ;
14662            schedGroup = Process.THREAD_GROUP_DEFAULT;
14663            app.adjType = "instrumentation";
14664            interesting = true;
14665            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14666        } else if ((queue = isReceivingBroadcast(app)) != null) {
14667            // An app that is currently receiving a broadcast also
14668            // counts as being in the foreground for OOM killer purposes.
14669            // It's placed in a sched group based on the nature of the
14670            // broadcast as reflected by which queue it's active in.
14671            adj = ProcessList.FOREGROUND_APP_ADJ;
14672            schedGroup = (queue == mFgBroadcastQueue)
14673                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14674            app.adjType = "broadcast";
14675            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14676        } else if (app.executingServices.size() > 0) {
14677            // An app that is currently executing a service callback also
14678            // counts as being in the foreground.
14679            adj = ProcessList.FOREGROUND_APP_ADJ;
14680            schedGroup = app.execServicesFg ?
14681                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14682            app.adjType = "exec-service";
14683            procState = ActivityManager.PROCESS_STATE_SERVICE;
14684            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14685        } else {
14686            // As far as we know the process is empty.  We may change our mind later.
14687            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14688            // At this point we don't actually know the adjustment.  Use the cached adj
14689            // value that the caller wants us to.
14690            adj = cachedAdj;
14691            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14692            app.cached = true;
14693            app.empty = true;
14694            app.adjType = "cch-empty";
14695        }
14696
14697        // Examine all activities if not already foreground.
14698        if (!foregroundActivities && activitiesSize > 0) {
14699            for (int j = 0; j < activitiesSize; j++) {
14700                final ActivityRecord r = app.activities.get(j);
14701                if (r.app != app) {
14702                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14703                            + app + "?!?");
14704                    continue;
14705                }
14706                if (r.visible) {
14707                    // App has a visible activity; only upgrade adjustment.
14708                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14709                        adj = ProcessList.VISIBLE_APP_ADJ;
14710                        app.adjType = "visible";
14711                    }
14712                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14713                        procState = ActivityManager.PROCESS_STATE_TOP;
14714                    }
14715                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14716                    app.cached = false;
14717                    app.empty = false;
14718                    foregroundActivities = true;
14719                    break;
14720                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14721                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14722                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14723                        app.adjType = "pausing";
14724                    }
14725                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14726                        procState = ActivityManager.PROCESS_STATE_TOP;
14727                    }
14728                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14729                    app.cached = false;
14730                    app.empty = false;
14731                    foregroundActivities = true;
14732                } else if (r.state == ActivityState.STOPPING) {
14733                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14734                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14735                        app.adjType = "stopping";
14736                    }
14737                    // For the process state, we will at this point consider the
14738                    // process to be cached.  It will be cached either as an activity
14739                    // or empty depending on whether the activity is finishing.  We do
14740                    // this so that we can treat the process as cached for purposes of
14741                    // memory trimming (determing current memory level, trim command to
14742                    // send to process) since there can be an arbitrary number of stopping
14743                    // processes and they should soon all go into the cached state.
14744                    if (!r.finishing) {
14745                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14746                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14747                        }
14748                    }
14749                    app.cached = false;
14750                    app.empty = false;
14751                    foregroundActivities = true;
14752                } else {
14753                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14754                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14755                        app.adjType = "cch-act";
14756                    }
14757                }
14758            }
14759        }
14760
14761        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14762            if (app.foregroundServices) {
14763                // The user is aware of this app, so make it visible.
14764                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14765                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14766                app.cached = false;
14767                app.adjType = "fg-service";
14768                schedGroup = Process.THREAD_GROUP_DEFAULT;
14769            } else if (app.forcingToForeground != null) {
14770                // The user is aware of this app, so make it visible.
14771                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14772                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14773                app.cached = false;
14774                app.adjType = "force-fg";
14775                app.adjSource = app.forcingToForeground;
14776                schedGroup = Process.THREAD_GROUP_DEFAULT;
14777            }
14778        }
14779
14780        if (app.foregroundServices) {
14781            interesting = true;
14782        }
14783
14784        if (app == mHeavyWeightProcess) {
14785            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14786                // We don't want to kill the current heavy-weight process.
14787                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14788                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14789                app.cached = false;
14790                app.adjType = "heavy";
14791            }
14792            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14793                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14794            }
14795        }
14796
14797        if (app == mHomeProcess) {
14798            if (adj > ProcessList.HOME_APP_ADJ) {
14799                // This process is hosting what we currently consider to be the
14800                // home app, so we don't want to let it go into the background.
14801                adj = ProcessList.HOME_APP_ADJ;
14802                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14803                app.cached = false;
14804                app.adjType = "home";
14805            }
14806            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14807                procState = ActivityManager.PROCESS_STATE_HOME;
14808            }
14809        }
14810
14811        if (app == mPreviousProcess && app.activities.size() > 0) {
14812            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14813                // This was the previous process that showed UI to the user.
14814                // We want to try to keep it around more aggressively, to give
14815                // a good experience around switching between two apps.
14816                adj = ProcessList.PREVIOUS_APP_ADJ;
14817                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14818                app.cached = false;
14819                app.adjType = "previous";
14820            }
14821            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14822                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14823            }
14824        }
14825
14826        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14827                + " reason=" + app.adjType);
14828
14829        // By default, we use the computed adjustment.  It may be changed if
14830        // there are applications dependent on our services or providers, but
14831        // this gives us a baseline and makes sure we don't get into an
14832        // infinite recursion.
14833        app.adjSeq = mAdjSeq;
14834        app.curRawAdj = adj;
14835        app.hasStartedServices = false;
14836
14837        if (mBackupTarget != null && app == mBackupTarget.app) {
14838            // If possible we want to avoid killing apps while they're being backed up
14839            if (adj > ProcessList.BACKUP_APP_ADJ) {
14840                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14841                adj = ProcessList.BACKUP_APP_ADJ;
14842                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14843                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14844                }
14845                app.adjType = "backup";
14846                app.cached = false;
14847            }
14848            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14849                procState = ActivityManager.PROCESS_STATE_BACKUP;
14850            }
14851        }
14852
14853        boolean mayBeTop = false;
14854
14855        for (int is = app.services.size()-1;
14856                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14857                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14858                        || procState > ActivityManager.PROCESS_STATE_TOP);
14859                is--) {
14860            ServiceRecord s = app.services.valueAt(is);
14861            if (s.startRequested) {
14862                app.hasStartedServices = true;
14863                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14864                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14865                }
14866                if (app.hasShownUi && app != mHomeProcess) {
14867                    // If this process has shown some UI, let it immediately
14868                    // go to the LRU list because it may be pretty heavy with
14869                    // UI stuff.  We'll tag it with a label just to help
14870                    // debug and understand what is going on.
14871                    if (adj > ProcessList.SERVICE_ADJ) {
14872                        app.adjType = "cch-started-ui-services";
14873                    }
14874                } else {
14875                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14876                        // This service has seen some activity within
14877                        // recent memory, so we will keep its process ahead
14878                        // of the background processes.
14879                        if (adj > ProcessList.SERVICE_ADJ) {
14880                            adj = ProcessList.SERVICE_ADJ;
14881                            app.adjType = "started-services";
14882                            app.cached = false;
14883                        }
14884                    }
14885                    // If we have let the service slide into the background
14886                    // state, still have some text describing what it is doing
14887                    // even though the service no longer has an impact.
14888                    if (adj > ProcessList.SERVICE_ADJ) {
14889                        app.adjType = "cch-started-services";
14890                    }
14891                }
14892                // Don't kill this process because it is doing work; it
14893                // has said it is doing work.
14894                app.keeping = true;
14895            }
14896            for (int conni = s.connections.size()-1;
14897                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14898                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14899                            || procState > ActivityManager.PROCESS_STATE_TOP);
14900                    conni--) {
14901                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14902                for (int i = 0;
14903                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14904                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14905                                || procState > ActivityManager.PROCESS_STATE_TOP);
14906                        i++) {
14907                    // XXX should compute this based on the max of
14908                    // all connected clients.
14909                    ConnectionRecord cr = clist.get(i);
14910                    if (cr.binding.client == app) {
14911                        // Binding to ourself is not interesting.
14912                        continue;
14913                    }
14914                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14915                        ProcessRecord client = cr.binding.client;
14916                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14917                                TOP_APP, doingAll, now);
14918                        int clientProcState = client.curProcState;
14919                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14920                            // If the other app is cached for any reason, for purposes here
14921                            // we are going to consider it empty.  The specific cached state
14922                            // doesn't propagate except under certain conditions.
14923                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14924                        }
14925                        String adjType = null;
14926                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14927                            // Not doing bind OOM management, so treat
14928                            // this guy more like a started service.
14929                            if (app.hasShownUi && app != mHomeProcess) {
14930                                // If this process has shown some UI, let it immediately
14931                                // go to the LRU list because it may be pretty heavy with
14932                                // UI stuff.  We'll tag it with a label just to help
14933                                // debug and understand what is going on.
14934                                if (adj > clientAdj) {
14935                                    adjType = "cch-bound-ui-services";
14936                                }
14937                                app.cached = false;
14938                                clientAdj = adj;
14939                                clientProcState = procState;
14940                            } else {
14941                                if (now >= (s.lastActivity
14942                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14943                                    // This service has not seen activity within
14944                                    // recent memory, so allow it to drop to the
14945                                    // LRU list if there is no other reason to keep
14946                                    // it around.  We'll also tag it with a label just
14947                                    // to help debug and undertand what is going on.
14948                                    if (adj > clientAdj) {
14949                                        adjType = "cch-bound-services";
14950                                    }
14951                                    clientAdj = adj;
14952                                }
14953                            }
14954                        }
14955                        if (adj > clientAdj) {
14956                            // If this process has recently shown UI, and
14957                            // the process that is binding to it is less
14958                            // important than being visible, then we don't
14959                            // care about the binding as much as we care
14960                            // about letting this process get into the LRU
14961                            // list to be killed and restarted if needed for
14962                            // memory.
14963                            if (app.hasShownUi && app != mHomeProcess
14964                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14965                                adjType = "cch-bound-ui-services";
14966                            } else {
14967                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14968                                        |Context.BIND_IMPORTANT)) != 0) {
14969                                    adj = clientAdj;
14970                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14971                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14972                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14973                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14974                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
14975                                    adj = clientAdj;
14976                                } else {
14977                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14978                                        adj = ProcessList.VISIBLE_APP_ADJ;
14979                                    }
14980                                }
14981                                if (!client.cached) {
14982                                    app.cached = false;
14983                                }
14984                                if (client.keeping) {
14985                                    app.keeping = true;
14986                                }
14987                                adjType = "service";
14988                            }
14989                        }
14990                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14991                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14992                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14993                            }
14994                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14995                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14996                                    // Special handling of clients who are in the top state.
14997                                    // We *may* want to consider this process to be in the
14998                                    // top state as well, but only if there is not another
14999                                    // reason for it to be running.  Being on the top is a
15000                                    // special state, meaning you are specifically running
15001                                    // for the current top app.  If the process is already
15002                                    // running in the background for some other reason, it
15003                                    // is more important to continue considering it to be
15004                                    // in the background state.
15005                                    mayBeTop = true;
15006                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15007                                } else {
15008                                    // Special handling for above-top states (persistent
15009                                    // processes).  These should not bring the current process
15010                                    // into the top state, since they are not on top.  Instead
15011                                    // give them the best state after that.
15012                                    clientProcState =
15013                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15014                                }
15015                            }
15016                        } else {
15017                            if (clientProcState <
15018                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15019                                clientProcState =
15020                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15021                            }
15022                        }
15023                        if (procState > clientProcState) {
15024                            procState = clientProcState;
15025                        }
15026                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15027                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15028                            app.pendingUiClean = true;
15029                        }
15030                        if (adjType != null) {
15031                            app.adjType = adjType;
15032                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15033                                    .REASON_SERVICE_IN_USE;
15034                            app.adjSource = cr.binding.client;
15035                            app.adjSourceOom = clientAdj;
15036                            app.adjTarget = s.name;
15037                        }
15038                    }
15039                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15040                        app.treatLikeActivity = true;
15041                    }
15042                    final ActivityRecord a = cr.activity;
15043                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15044                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15045                                (a.visible || a.state == ActivityState.RESUMED
15046                                 || a.state == ActivityState.PAUSING)) {
15047                            adj = ProcessList.FOREGROUND_APP_ADJ;
15048                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15049                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15050                            }
15051                            app.cached = false;
15052                            app.adjType = "service";
15053                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15054                                    .REASON_SERVICE_IN_USE;
15055                            app.adjSource = a;
15056                            app.adjSourceOom = adj;
15057                            app.adjTarget = s.name;
15058                        }
15059                    }
15060                }
15061            }
15062        }
15063
15064        for (int provi = app.pubProviders.size()-1;
15065                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15066                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15067                        || procState > ActivityManager.PROCESS_STATE_TOP);
15068                provi--) {
15069            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15070            for (int i = cpr.connections.size()-1;
15071                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15072                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15073                            || procState > ActivityManager.PROCESS_STATE_TOP);
15074                    i--) {
15075                ContentProviderConnection conn = cpr.connections.get(i);
15076                ProcessRecord client = conn.client;
15077                if (client == app) {
15078                    // Being our own client is not interesting.
15079                    continue;
15080                }
15081                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15082                int clientProcState = client.curProcState;
15083                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15084                    // If the other app is cached for any reason, for purposes here
15085                    // we are going to consider it empty.
15086                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15087                }
15088                if (adj > clientAdj) {
15089                    if (app.hasShownUi && app != mHomeProcess
15090                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15091                        app.adjType = "cch-ui-provider";
15092                    } else {
15093                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15094                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15095                        app.adjType = "provider";
15096                    }
15097                    app.cached &= client.cached;
15098                    app.keeping |= client.keeping;
15099                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15100                            .REASON_PROVIDER_IN_USE;
15101                    app.adjSource = client;
15102                    app.adjSourceOom = clientAdj;
15103                    app.adjTarget = cpr.name;
15104                }
15105                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15106                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15107                        // Special handling of clients who are in the top state.
15108                        // We *may* want to consider this process to be in the
15109                        // top state as well, but only if there is not another
15110                        // reason for it to be running.  Being on the top is a
15111                        // special state, meaning you are specifically running
15112                        // for the current top app.  If the process is already
15113                        // running in the background for some other reason, it
15114                        // is more important to continue considering it to be
15115                        // in the background state.
15116                        mayBeTop = true;
15117                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15118                    } else {
15119                        // Special handling for above-top states (persistent
15120                        // processes).  These should not bring the current process
15121                        // into the top state, since they are not on top.  Instead
15122                        // give them the best state after that.
15123                        clientProcState =
15124                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15125                    }
15126                }
15127                if (procState > clientProcState) {
15128                    procState = clientProcState;
15129                }
15130                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15131                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15132                }
15133            }
15134            // If the provider has external (non-framework) process
15135            // dependencies, ensure that its adjustment is at least
15136            // FOREGROUND_APP_ADJ.
15137            if (cpr.hasExternalProcessHandles()) {
15138                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15139                    adj = ProcessList.FOREGROUND_APP_ADJ;
15140                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15141                    app.cached = false;
15142                    app.keeping = true;
15143                    app.adjType = "provider";
15144                    app.adjTarget = cpr.name;
15145                }
15146                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15147                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15148                }
15149            }
15150        }
15151
15152        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15153            // A client of one of our services or providers is in the top state.  We
15154            // *may* want to be in the top state, but not if we are already running in
15155            // the background for some other reason.  For the decision here, we are going
15156            // to pick out a few specific states that we want to remain in when a client
15157            // is top (states that tend to be longer-term) and otherwise allow it to go
15158            // to the top state.
15159            switch (procState) {
15160                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15161                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15162                case ActivityManager.PROCESS_STATE_SERVICE:
15163                    // These all are longer-term states, so pull them up to the top
15164                    // of the background states, but not all the way to the top state.
15165                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15166                    break;
15167                default:
15168                    // Otherwise, top is a better choice, so take it.
15169                    procState = ActivityManager.PROCESS_STATE_TOP;
15170                    break;
15171            }
15172        }
15173
15174        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15175            if (app.hasClientActivities) {
15176                // This is a cached process, but with client activities.  Mark it so.
15177                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15178                app.adjType = "cch-client-act";
15179            } else if (app.treatLikeActivity) {
15180                // This is a cached process, but somebody wants us to treat it like it has
15181                // an activity, okay!
15182                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15183                app.adjType = "cch-as-act";
15184            }
15185        }
15186
15187        if (adj == ProcessList.SERVICE_ADJ) {
15188            if (doingAll) {
15189                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15190                mNewNumServiceProcs++;
15191                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15192                if (!app.serviceb) {
15193                    // This service isn't far enough down on the LRU list to
15194                    // normally be a B service, but if we are low on RAM and it
15195                    // is large we want to force it down since we would prefer to
15196                    // keep launcher over it.
15197                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15198                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15199                        app.serviceHighRam = true;
15200                        app.serviceb = true;
15201                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15202                    } else {
15203                        mNewNumAServiceProcs++;
15204                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15205                    }
15206                } else {
15207                    app.serviceHighRam = false;
15208                }
15209            }
15210            if (app.serviceb) {
15211                adj = ProcessList.SERVICE_B_ADJ;
15212            }
15213        }
15214
15215        app.curRawAdj = adj;
15216
15217        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15218        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15219        if (adj > app.maxAdj) {
15220            adj = app.maxAdj;
15221            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15222                schedGroup = Process.THREAD_GROUP_DEFAULT;
15223            }
15224        }
15225        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15226            app.keeping = true;
15227        }
15228
15229        // Do final modification to adj.  Everything we do between here and applying
15230        // the final setAdj must be done in this function, because we will also use
15231        // it when computing the final cached adj later.  Note that we don't need to
15232        // worry about this for max adj above, since max adj will always be used to
15233        // keep it out of the cached vaues.
15234        app.curAdj = app.modifyRawOomAdj(adj);
15235        app.curSchedGroup = schedGroup;
15236        app.curProcState = procState;
15237        app.foregroundActivities = foregroundActivities;
15238
15239        return app.curRawAdj;
15240    }
15241
15242    /**
15243     * Schedule PSS collection of a process.
15244     */
15245    void requestPssLocked(ProcessRecord proc, int procState) {
15246        if (mPendingPssProcesses.contains(proc)) {
15247            return;
15248        }
15249        if (mPendingPssProcesses.size() == 0) {
15250            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15251        }
15252        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15253        proc.pssProcState = procState;
15254        mPendingPssProcesses.add(proc);
15255    }
15256
15257    /**
15258     * Schedule PSS collection of all processes.
15259     */
15260    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15261        if (!always) {
15262            if (now < (mLastFullPssTime +
15263                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15264                return;
15265            }
15266        }
15267        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15268        mLastFullPssTime = now;
15269        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15270        mPendingPssProcesses.clear();
15271        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15272            ProcessRecord app = mLruProcesses.get(i);
15273            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15274                app.pssProcState = app.setProcState;
15275                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15276                        isSleeping(), now);
15277                mPendingPssProcesses.add(app);
15278            }
15279        }
15280        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15281    }
15282
15283    /**
15284     * Ask a given process to GC right now.
15285     */
15286    final void performAppGcLocked(ProcessRecord app) {
15287        try {
15288            app.lastRequestedGc = SystemClock.uptimeMillis();
15289            if (app.thread != null) {
15290                if (app.reportLowMemory) {
15291                    app.reportLowMemory = false;
15292                    app.thread.scheduleLowMemory();
15293                } else {
15294                    app.thread.processInBackground();
15295                }
15296            }
15297        } catch (Exception e) {
15298            // whatever.
15299        }
15300    }
15301
15302    /**
15303     * Returns true if things are idle enough to perform GCs.
15304     */
15305    private final boolean canGcNowLocked() {
15306        boolean processingBroadcasts = false;
15307        for (BroadcastQueue q : mBroadcastQueues) {
15308            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15309                processingBroadcasts = true;
15310            }
15311        }
15312        return !processingBroadcasts
15313                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15314    }
15315
15316    /**
15317     * Perform GCs on all processes that are waiting for it, but only
15318     * if things are idle.
15319     */
15320    final void performAppGcsLocked() {
15321        final int N = mProcessesToGc.size();
15322        if (N <= 0) {
15323            return;
15324        }
15325        if (canGcNowLocked()) {
15326            while (mProcessesToGc.size() > 0) {
15327                ProcessRecord proc = mProcessesToGc.remove(0);
15328                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15329                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15330                            <= SystemClock.uptimeMillis()) {
15331                        // To avoid spamming the system, we will GC processes one
15332                        // at a time, waiting a few seconds between each.
15333                        performAppGcLocked(proc);
15334                        scheduleAppGcsLocked();
15335                        return;
15336                    } else {
15337                        // It hasn't been long enough since we last GCed this
15338                        // process...  put it in the list to wait for its time.
15339                        addProcessToGcListLocked(proc);
15340                        break;
15341                    }
15342                }
15343            }
15344
15345            scheduleAppGcsLocked();
15346        }
15347    }
15348
15349    /**
15350     * If all looks good, perform GCs on all processes waiting for them.
15351     */
15352    final void performAppGcsIfAppropriateLocked() {
15353        if (canGcNowLocked()) {
15354            performAppGcsLocked();
15355            return;
15356        }
15357        // Still not idle, wait some more.
15358        scheduleAppGcsLocked();
15359    }
15360
15361    /**
15362     * Schedule the execution of all pending app GCs.
15363     */
15364    final void scheduleAppGcsLocked() {
15365        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15366
15367        if (mProcessesToGc.size() > 0) {
15368            // Schedule a GC for the time to the next process.
15369            ProcessRecord proc = mProcessesToGc.get(0);
15370            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15371
15372            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15373            long now = SystemClock.uptimeMillis();
15374            if (when < (now+GC_TIMEOUT)) {
15375                when = now + GC_TIMEOUT;
15376            }
15377            mHandler.sendMessageAtTime(msg, when);
15378        }
15379    }
15380
15381    /**
15382     * Add a process to the array of processes waiting to be GCed.  Keeps the
15383     * list in sorted order by the last GC time.  The process can't already be
15384     * on the list.
15385     */
15386    final void addProcessToGcListLocked(ProcessRecord proc) {
15387        boolean added = false;
15388        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15389            if (mProcessesToGc.get(i).lastRequestedGc <
15390                    proc.lastRequestedGc) {
15391                added = true;
15392                mProcessesToGc.add(i+1, proc);
15393                break;
15394            }
15395        }
15396        if (!added) {
15397            mProcessesToGc.add(0, proc);
15398        }
15399    }
15400
15401    /**
15402     * Set up to ask a process to GC itself.  This will either do it
15403     * immediately, or put it on the list of processes to gc the next
15404     * time things are idle.
15405     */
15406    final void scheduleAppGcLocked(ProcessRecord app) {
15407        long now = SystemClock.uptimeMillis();
15408        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15409            return;
15410        }
15411        if (!mProcessesToGc.contains(app)) {
15412            addProcessToGcListLocked(app);
15413            scheduleAppGcsLocked();
15414        }
15415    }
15416
15417    final void checkExcessivePowerUsageLocked(boolean doKills) {
15418        updateCpuStatsNow();
15419
15420        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15421        boolean doWakeKills = doKills;
15422        boolean doCpuKills = doKills;
15423        if (mLastPowerCheckRealtime == 0) {
15424            doWakeKills = false;
15425        }
15426        if (mLastPowerCheckUptime == 0) {
15427            doCpuKills = false;
15428        }
15429        if (stats.isScreenOn()) {
15430            doWakeKills = false;
15431        }
15432        final long curRealtime = SystemClock.elapsedRealtime();
15433        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15434        final long curUptime = SystemClock.uptimeMillis();
15435        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15436        mLastPowerCheckRealtime = curRealtime;
15437        mLastPowerCheckUptime = curUptime;
15438        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15439            doWakeKills = false;
15440        }
15441        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15442            doCpuKills = false;
15443        }
15444        int i = mLruProcesses.size();
15445        while (i > 0) {
15446            i--;
15447            ProcessRecord app = mLruProcesses.get(i);
15448            if (!app.keeping) {
15449                long wtime;
15450                synchronized (stats) {
15451                    wtime = stats.getProcessWakeTime(app.info.uid,
15452                            app.pid, curRealtime);
15453                }
15454                long wtimeUsed = wtime - app.lastWakeTime;
15455                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15456                if (DEBUG_POWER) {
15457                    StringBuilder sb = new StringBuilder(128);
15458                    sb.append("Wake for ");
15459                    app.toShortString(sb);
15460                    sb.append(": over ");
15461                    TimeUtils.formatDuration(realtimeSince, sb);
15462                    sb.append(" used ");
15463                    TimeUtils.formatDuration(wtimeUsed, sb);
15464                    sb.append(" (");
15465                    sb.append((wtimeUsed*100)/realtimeSince);
15466                    sb.append("%)");
15467                    Slog.i(TAG, sb.toString());
15468                    sb.setLength(0);
15469                    sb.append("CPU for ");
15470                    app.toShortString(sb);
15471                    sb.append(": over ");
15472                    TimeUtils.formatDuration(uptimeSince, sb);
15473                    sb.append(" used ");
15474                    TimeUtils.formatDuration(cputimeUsed, sb);
15475                    sb.append(" (");
15476                    sb.append((cputimeUsed*100)/uptimeSince);
15477                    sb.append("%)");
15478                    Slog.i(TAG, sb.toString());
15479                }
15480                // If a process has held a wake lock for more
15481                // than 50% of the time during this period,
15482                // that sounds bad.  Kill!
15483                if (doWakeKills && realtimeSince > 0
15484                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15485                    synchronized (stats) {
15486                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15487                                realtimeSince, wtimeUsed);
15488                    }
15489                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15490                            + " during " + realtimeSince);
15491                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15492                } else if (doCpuKills && uptimeSince > 0
15493                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15494                    synchronized (stats) {
15495                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15496                                uptimeSince, cputimeUsed);
15497                    }
15498                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15499                            + " during " + uptimeSince);
15500                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15501                } else {
15502                    app.lastWakeTime = wtime;
15503                    app.lastCpuTime = app.curCpuTime;
15504                }
15505            }
15506        }
15507    }
15508
15509    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15510            ProcessRecord TOP_APP, boolean doingAll, long now) {
15511        boolean success = true;
15512
15513        if (app.curRawAdj != app.setRawAdj) {
15514            if (wasKeeping && !app.keeping) {
15515                // This app is no longer something we want to keep.  Note
15516                // its current wake lock time to later know to kill it if
15517                // it is not behaving well.
15518                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15519                synchronized (stats) {
15520                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15521                            app.pid, SystemClock.elapsedRealtime());
15522                }
15523                app.lastCpuTime = app.curCpuTime;
15524            }
15525
15526            app.setRawAdj = app.curRawAdj;
15527        }
15528
15529        int changes = 0;
15530
15531        if (app.curAdj != app.setAdj) {
15532            ProcessList.setOomAdj(app.pid, app.curAdj);
15533            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15534                TAG, "Set " + app.pid + " " + app.processName +
15535                " adj " + app.curAdj + ": " + app.adjType);
15536            app.setAdj = app.curAdj;
15537        }
15538
15539        if (app.setSchedGroup != app.curSchedGroup) {
15540            app.setSchedGroup = app.curSchedGroup;
15541            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15542                    "Setting process group of " + app.processName
15543                    + " to " + app.curSchedGroup);
15544            if (app.waitingToKill != null &&
15545                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15546                killUnneededProcessLocked(app, app.waitingToKill);
15547                success = false;
15548            } else {
15549                if (true) {
15550                    long oldId = Binder.clearCallingIdentity();
15551                    try {
15552                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15553                    } catch (Exception e) {
15554                        Slog.w(TAG, "Failed setting process group of " + app.pid
15555                                + " to " + app.curSchedGroup);
15556                        e.printStackTrace();
15557                    } finally {
15558                        Binder.restoreCallingIdentity(oldId);
15559                    }
15560                } else {
15561                    if (app.thread != null) {
15562                        try {
15563                            app.thread.setSchedulingGroup(app.curSchedGroup);
15564                        } catch (RemoteException e) {
15565                        }
15566                    }
15567                }
15568                Process.setSwappiness(app.pid,
15569                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15570            }
15571        }
15572        if (app.repForegroundActivities != app.foregroundActivities) {
15573            app.repForegroundActivities = app.foregroundActivities;
15574            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15575        }
15576        if (app.repProcState != app.curProcState) {
15577            app.repProcState = app.curProcState;
15578            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
15579            if (app.thread != null) {
15580                try {
15581                    if (false) {
15582                        //RuntimeException h = new RuntimeException("here");
15583                        Slog.i(TAG, "Sending new process state " + app.repProcState
15584                                + " to " + app /*, h*/);
15585                    }
15586                    app.thread.setProcessState(app.repProcState);
15587                } catch (RemoteException e) {
15588                }
15589            }
15590        }
15591        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15592                app.setProcState)) {
15593            app.lastStateTime = now;
15594            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15595                    isSleeping(), now);
15596            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15597                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15598                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15599                    + (app.nextPssTime-now) + ": " + app);
15600        } else {
15601            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15602                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15603                requestPssLocked(app, app.setProcState);
15604                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15605                        isSleeping(), now);
15606            } else if (false && DEBUG_PSS) {
15607                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15608            }
15609        }
15610        if (app.setProcState != app.curProcState) {
15611            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15612                    "Proc state change of " + app.processName
15613                    + " to " + app.curProcState);
15614            app.setProcState = app.curProcState;
15615            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15616                app.notCachedSinceIdle = false;
15617            }
15618            if (!doingAll) {
15619                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15620            } else {
15621                app.procStateChanged = true;
15622            }
15623        }
15624
15625        if (changes != 0) {
15626            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15627            int i = mPendingProcessChanges.size()-1;
15628            ProcessChangeItem item = null;
15629            while (i >= 0) {
15630                item = mPendingProcessChanges.get(i);
15631                if (item.pid == app.pid) {
15632                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15633                    break;
15634                }
15635                i--;
15636            }
15637            if (i < 0) {
15638                // No existing item in pending changes; need a new one.
15639                final int NA = mAvailProcessChanges.size();
15640                if (NA > 0) {
15641                    item = mAvailProcessChanges.remove(NA-1);
15642                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15643                } else {
15644                    item = new ProcessChangeItem();
15645                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15646                }
15647                item.changes = 0;
15648                item.pid = app.pid;
15649                item.uid = app.info.uid;
15650                if (mPendingProcessChanges.size() == 0) {
15651                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15652                            "*** Enqueueing dispatch processes changed!");
15653                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15654                }
15655                mPendingProcessChanges.add(item);
15656            }
15657            item.changes |= changes;
15658            item.processState = app.repProcState;
15659            item.foregroundActivities = app.repForegroundActivities;
15660            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
15661                    + Integer.toHexString(System.identityHashCode(item))
15662                    + " " + app.toShortString() + ": changes=" + item.changes
15663                    + " procState=" + item.processState
15664                    + " foreground=" + item.foregroundActivities
15665                    + " type=" + app.adjType + " source=" + app.adjSource
15666                    + " target=" + app.adjTarget);
15667        }
15668
15669        return success;
15670    }
15671
15672    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15673        if (proc.thread != null && proc.baseProcessTracker != null) {
15674            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15675        }
15676    }
15677
15678    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15679            ProcessRecord TOP_APP, boolean doingAll, long now) {
15680        if (app.thread == null) {
15681            return false;
15682        }
15683
15684        final boolean wasKeeping = app.keeping;
15685
15686        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15687
15688        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now);
15689    }
15690
15691    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15692            boolean oomAdj) {
15693        if (isForeground != proc.foregroundServices) {
15694            proc.foregroundServices = isForeground;
15695            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15696                    proc.info.uid);
15697            if (isForeground) {
15698                if (curProcs == null) {
15699                    curProcs = new ArrayList<ProcessRecord>();
15700                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15701                }
15702                if (!curProcs.contains(proc)) {
15703                    curProcs.add(proc);
15704                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15705                            proc.info.packageName, proc.info.uid);
15706                }
15707            } else {
15708                if (curProcs != null) {
15709                    if (curProcs.remove(proc)) {
15710                        mBatteryStatsService.noteEvent(
15711                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15712                                proc.info.packageName, proc.info.uid);
15713                        if (curProcs.size() <= 0) {
15714                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15715                        }
15716                    }
15717                }
15718            }
15719            if (oomAdj) {
15720                updateOomAdjLocked();
15721            }
15722        }
15723    }
15724
15725    private final ActivityRecord resumedAppLocked() {
15726        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15727        String pkg;
15728        int uid;
15729        if (act != null && !act.sleeping) {
15730            pkg = act.packageName;
15731            uid = act.info.applicationInfo.uid;
15732        } else {
15733            pkg = null;
15734            uid = -1;
15735        }
15736        // Has the UID or resumed package name changed?
15737        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15738                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15739            if (mCurResumedPackage != null) {
15740                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15741                        mCurResumedPackage, mCurResumedUid);
15742            }
15743            mCurResumedPackage = pkg;
15744            mCurResumedUid = uid;
15745            if (mCurResumedPackage != null) {
15746                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15747                        mCurResumedPackage, mCurResumedUid);
15748            }
15749        }
15750        return act;
15751    }
15752
15753    final boolean updateOomAdjLocked(ProcessRecord app) {
15754        final ActivityRecord TOP_ACT = resumedAppLocked();
15755        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15756        final boolean wasCached = app.cached;
15757
15758        mAdjSeq++;
15759
15760        // This is the desired cached adjusment we want to tell it to use.
15761        // If our app is currently cached, we know it, and that is it.  Otherwise,
15762        // we don't know it yet, and it needs to now be cached we will then
15763        // need to do a complete oom adj.
15764        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15765                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15766        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
15767                SystemClock.uptimeMillis());
15768        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15769            // Changed to/from cached state, so apps after it in the LRU
15770            // list may also be changed.
15771            updateOomAdjLocked();
15772        }
15773        return success;
15774    }
15775
15776    final void updateOomAdjLocked() {
15777        final ActivityRecord TOP_ACT = resumedAppLocked();
15778        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15779        final long now = SystemClock.uptimeMillis();
15780        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15781        final int N = mLruProcesses.size();
15782
15783        if (false) {
15784            RuntimeException e = new RuntimeException();
15785            e.fillInStackTrace();
15786            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15787        }
15788
15789        mAdjSeq++;
15790        mNewNumServiceProcs = 0;
15791        mNewNumAServiceProcs = 0;
15792
15793        final int emptyProcessLimit;
15794        final int cachedProcessLimit;
15795        if (mProcessLimit <= 0) {
15796            emptyProcessLimit = cachedProcessLimit = 0;
15797        } else if (mProcessLimit == 1) {
15798            emptyProcessLimit = 1;
15799            cachedProcessLimit = 0;
15800        } else {
15801            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15802            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15803        }
15804
15805        // Let's determine how many processes we have running vs.
15806        // how many slots we have for background processes; we may want
15807        // to put multiple processes in a slot of there are enough of
15808        // them.
15809        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15810                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15811        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15812        if (numEmptyProcs > cachedProcessLimit) {
15813            // If there are more empty processes than our limit on cached
15814            // processes, then use the cached process limit for the factor.
15815            // This ensures that the really old empty processes get pushed
15816            // down to the bottom, so if we are running low on memory we will
15817            // have a better chance at keeping around more cached processes
15818            // instead of a gazillion empty processes.
15819            numEmptyProcs = cachedProcessLimit;
15820        }
15821        int emptyFactor = numEmptyProcs/numSlots;
15822        if (emptyFactor < 1) emptyFactor = 1;
15823        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15824        if (cachedFactor < 1) cachedFactor = 1;
15825        int stepCached = 0;
15826        int stepEmpty = 0;
15827        int numCached = 0;
15828        int numEmpty = 0;
15829        int numTrimming = 0;
15830
15831        mNumNonCachedProcs = 0;
15832        mNumCachedHiddenProcs = 0;
15833
15834        // First update the OOM adjustment for each of the
15835        // application processes based on their current state.
15836        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15837        int nextCachedAdj = curCachedAdj+1;
15838        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15839        int nextEmptyAdj = curEmptyAdj+2;
15840        for (int i=N-1; i>=0; i--) {
15841            ProcessRecord app = mLruProcesses.get(i);
15842            if (!app.killedByAm && app.thread != null) {
15843                app.procStateChanged = false;
15844                final boolean wasKeeping = app.keeping;
15845                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15846
15847                // If we haven't yet assigned the final cached adj
15848                // to the process, do that now.
15849                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15850                    switch (app.curProcState) {
15851                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15852                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15853                            // This process is a cached process holding activities...
15854                            // assign it the next cached value for that type, and then
15855                            // step that cached level.
15856                            app.curRawAdj = curCachedAdj;
15857                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15858                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15859                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15860                                    + ")");
15861                            if (curCachedAdj != nextCachedAdj) {
15862                                stepCached++;
15863                                if (stepCached >= cachedFactor) {
15864                                    stepCached = 0;
15865                                    curCachedAdj = nextCachedAdj;
15866                                    nextCachedAdj += 2;
15867                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15868                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15869                                    }
15870                                }
15871                            }
15872                            break;
15873                        default:
15874                            // For everything else, assign next empty cached process
15875                            // level and bump that up.  Note that this means that
15876                            // long-running services that have dropped down to the
15877                            // cached level will be treated as empty (since their process
15878                            // state is still as a service), which is what we want.
15879                            app.curRawAdj = curEmptyAdj;
15880                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15881                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15882                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15883                                    + ")");
15884                            if (curEmptyAdj != nextEmptyAdj) {
15885                                stepEmpty++;
15886                                if (stepEmpty >= emptyFactor) {
15887                                    stepEmpty = 0;
15888                                    curEmptyAdj = nextEmptyAdj;
15889                                    nextEmptyAdj += 2;
15890                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15891                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15892                                    }
15893                                }
15894                            }
15895                            break;
15896                    }
15897                }
15898
15899                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now);
15900
15901                // Count the number of process types.
15902                switch (app.curProcState) {
15903                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15904                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15905                        mNumCachedHiddenProcs++;
15906                        numCached++;
15907                        if (numCached > cachedProcessLimit) {
15908                            killUnneededProcessLocked(app, "cached #" + numCached);
15909                        }
15910                        break;
15911                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15912                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15913                                && app.lastActivityTime < oldTime) {
15914                            killUnneededProcessLocked(app, "empty for "
15915                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15916                                    / 1000) + "s");
15917                        } else {
15918                            numEmpty++;
15919                            if (numEmpty > emptyProcessLimit) {
15920                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15921                            }
15922                        }
15923                        break;
15924                    default:
15925                        mNumNonCachedProcs++;
15926                        break;
15927                }
15928
15929                if (app.isolated && app.services.size() <= 0) {
15930                    // If this is an isolated process, and there are no
15931                    // services running in it, then the process is no longer
15932                    // needed.  We agressively kill these because we can by
15933                    // definition not re-use the same process again, and it is
15934                    // good to avoid having whatever code was running in them
15935                    // left sitting around after no longer needed.
15936                    killUnneededProcessLocked(app, "isolated not needed");
15937                }
15938
15939                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15940                        && !app.killedByAm) {
15941                    numTrimming++;
15942                }
15943            }
15944        }
15945
15946        mNumServiceProcs = mNewNumServiceProcs;
15947
15948        // Now determine the memory trimming level of background processes.
15949        // Unfortunately we need to start at the back of the list to do this
15950        // properly.  We only do this if the number of background apps we
15951        // are managing to keep around is less than half the maximum we desire;
15952        // if we are keeping a good number around, we'll let them use whatever
15953        // memory they want.
15954        final int numCachedAndEmpty = numCached + numEmpty;
15955        int memFactor;
15956        if (numCached <= ProcessList.TRIM_CACHED_APPS
15957                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
15958            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
15959                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
15960            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
15961                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
15962            } else {
15963                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
15964            }
15965        } else {
15966            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
15967        }
15968        // We always allow the memory level to go up (better).  We only allow it to go
15969        // down if we are in a state where that is allowed, *and* the total number of processes
15970        // has gone down since last time.
15971        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
15972                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
15973                + " last=" + mLastNumProcesses);
15974        if (memFactor > mLastMemoryLevel) {
15975            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
15976                memFactor = mLastMemoryLevel;
15977                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
15978            }
15979        }
15980        mLastMemoryLevel = memFactor;
15981        mLastNumProcesses = mLruProcesses.size();
15982        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
15983        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
15984        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
15985            if (mLowRamStartTime == 0) {
15986                mLowRamStartTime = now;
15987            }
15988            int step = 0;
15989            int fgTrimLevel;
15990            switch (memFactor) {
15991                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15992                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
15993                    break;
15994                case ProcessStats.ADJ_MEM_FACTOR_LOW:
15995                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
15996                    break;
15997                default:
15998                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
15999                    break;
16000            }
16001            int factor = numTrimming/3;
16002            int minFactor = 2;
16003            if (mHomeProcess != null) minFactor++;
16004            if (mPreviousProcess != null) minFactor++;
16005            if (factor < minFactor) factor = minFactor;
16006            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16007            for (int i=N-1; i>=0; i--) {
16008                ProcessRecord app = mLruProcesses.get(i);
16009                if (allChanged || app.procStateChanged) {
16010                    setProcessTrackerState(app, trackerMemFactor, now);
16011                    app.procStateChanged = false;
16012                }
16013                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16014                        && !app.killedByAm) {
16015                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16016                        try {
16017                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16018                                    "Trimming memory of " + app.processName
16019                                    + " to " + curLevel);
16020                            app.thread.scheduleTrimMemory(curLevel);
16021                        } catch (RemoteException e) {
16022                        }
16023                        if (false) {
16024                            // For now we won't do this; our memory trimming seems
16025                            // to be good enough at this point that destroying
16026                            // activities causes more harm than good.
16027                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16028                                    && app != mHomeProcess && app != mPreviousProcess) {
16029                                // Need to do this on its own message because the stack may not
16030                                // be in a consistent state at this point.
16031                                // For these apps we will also finish their activities
16032                                // to help them free memory.
16033                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16034                            }
16035                        }
16036                    }
16037                    app.trimMemoryLevel = curLevel;
16038                    step++;
16039                    if (step >= factor) {
16040                        step = 0;
16041                        switch (curLevel) {
16042                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16043                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16044                                break;
16045                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16046                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16047                                break;
16048                        }
16049                    }
16050                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16051                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16052                            && app.thread != null) {
16053                        try {
16054                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16055                                    "Trimming memory of heavy-weight " + app.processName
16056                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16057                            app.thread.scheduleTrimMemory(
16058                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16059                        } catch (RemoteException e) {
16060                        }
16061                    }
16062                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16063                } else {
16064                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16065                            || app.systemNoUi) && app.pendingUiClean) {
16066                        // If this application is now in the background and it
16067                        // had done UI, then give it the special trim level to
16068                        // have it free UI resources.
16069                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16070                        if (app.trimMemoryLevel < level && app.thread != null) {
16071                            try {
16072                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16073                                        "Trimming memory of bg-ui " + app.processName
16074                                        + " to " + level);
16075                                app.thread.scheduleTrimMemory(level);
16076                            } catch (RemoteException e) {
16077                            }
16078                        }
16079                        app.pendingUiClean = false;
16080                    }
16081                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16082                        try {
16083                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16084                                    "Trimming memory of fg " + app.processName
16085                                    + " to " + fgTrimLevel);
16086                            app.thread.scheduleTrimMemory(fgTrimLevel);
16087                        } catch (RemoteException e) {
16088                        }
16089                    }
16090                    app.trimMemoryLevel = fgTrimLevel;
16091                }
16092            }
16093        } else {
16094            if (mLowRamStartTime != 0) {
16095                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16096                mLowRamStartTime = 0;
16097            }
16098            for (int i=N-1; i>=0; i--) {
16099                ProcessRecord app = mLruProcesses.get(i);
16100                if (allChanged || app.procStateChanged) {
16101                    setProcessTrackerState(app, trackerMemFactor, now);
16102                    app.procStateChanged = false;
16103                }
16104                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16105                        || app.systemNoUi) && app.pendingUiClean) {
16106                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16107                            && app.thread != null) {
16108                        try {
16109                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16110                                    "Trimming memory of ui hidden " + app.processName
16111                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16112                            app.thread.scheduleTrimMemory(
16113                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16114                        } catch (RemoteException e) {
16115                        }
16116                    }
16117                    app.pendingUiClean = false;
16118                }
16119                app.trimMemoryLevel = 0;
16120            }
16121        }
16122
16123        if (mAlwaysFinishActivities) {
16124            // Need to do this on its own message because the stack may not
16125            // be in a consistent state at this point.
16126            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16127        }
16128
16129        if (allChanged) {
16130            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16131        }
16132
16133        if (mProcessStats.shouldWriteNowLocked(now)) {
16134            mHandler.post(new Runnable() {
16135                @Override public void run() {
16136                    synchronized (ActivityManagerService.this) {
16137                        mProcessStats.writeStateAsyncLocked();
16138                    }
16139                }
16140            });
16141        }
16142
16143        if (DEBUG_OOM_ADJ) {
16144            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16145        }
16146    }
16147
16148    final void trimApplications() {
16149        synchronized (this) {
16150            int i;
16151
16152            // First remove any unused application processes whose package
16153            // has been removed.
16154            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16155                final ProcessRecord app = mRemovedProcesses.get(i);
16156                if (app.activities.size() == 0
16157                        && app.curReceiver == null && app.services.size() == 0) {
16158                    Slog.i(
16159                        TAG, "Exiting empty application process "
16160                        + app.processName + " ("
16161                        + (app.thread != null ? app.thread.asBinder() : null)
16162                        + ")\n");
16163                    if (app.pid > 0 && app.pid != MY_PID) {
16164                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16165                                app.processName, app.setAdj, "empty");
16166                        app.killedByAm = true;
16167                        Process.killProcessQuiet(app.pid);
16168                    } else {
16169                        try {
16170                            app.thread.scheduleExit();
16171                        } catch (Exception e) {
16172                            // Ignore exceptions.
16173                        }
16174                    }
16175                    cleanUpApplicationRecordLocked(app, false, true, -1);
16176                    mRemovedProcesses.remove(i);
16177
16178                    if (app.persistent) {
16179                        if (app.persistent) {
16180                            addAppLocked(app.info, false);
16181                        }
16182                    }
16183                }
16184            }
16185
16186            // Now update the oom adj for all processes.
16187            updateOomAdjLocked();
16188        }
16189    }
16190
16191    /** This method sends the specified signal to each of the persistent apps */
16192    public void signalPersistentProcesses(int sig) throws RemoteException {
16193        if (sig != Process.SIGNAL_USR1) {
16194            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16195        }
16196
16197        synchronized (this) {
16198            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16199                    != PackageManager.PERMISSION_GRANTED) {
16200                throw new SecurityException("Requires permission "
16201                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16202            }
16203
16204            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16205                ProcessRecord r = mLruProcesses.get(i);
16206                if (r.thread != null && r.persistent) {
16207                    Process.sendSignal(r.pid, sig);
16208                }
16209            }
16210        }
16211    }
16212
16213    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16214        if (proc == null || proc == mProfileProc) {
16215            proc = mProfileProc;
16216            path = mProfileFile;
16217            profileType = mProfileType;
16218            clearProfilerLocked();
16219        }
16220        if (proc == null) {
16221            return;
16222        }
16223        try {
16224            proc.thread.profilerControl(false, path, null, profileType);
16225        } catch (RemoteException e) {
16226            throw new IllegalStateException("Process disappeared");
16227        }
16228    }
16229
16230    private void clearProfilerLocked() {
16231        if (mProfileFd != null) {
16232            try {
16233                mProfileFd.close();
16234            } catch (IOException e) {
16235            }
16236        }
16237        mProfileApp = null;
16238        mProfileProc = null;
16239        mProfileFile = null;
16240        mProfileType = 0;
16241        mAutoStopProfiler = false;
16242    }
16243
16244    public boolean profileControl(String process, int userId, boolean start,
16245            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16246
16247        try {
16248            synchronized (this) {
16249                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16250                // its own permission.
16251                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16252                        != PackageManager.PERMISSION_GRANTED) {
16253                    throw new SecurityException("Requires permission "
16254                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16255                }
16256
16257                if (start && fd == null) {
16258                    throw new IllegalArgumentException("null fd");
16259                }
16260
16261                ProcessRecord proc = null;
16262                if (process != null) {
16263                    proc = findProcessLocked(process, userId, "profileControl");
16264                }
16265
16266                if (start && (proc == null || proc.thread == null)) {
16267                    throw new IllegalArgumentException("Unknown process: " + process);
16268                }
16269
16270                if (start) {
16271                    stopProfilerLocked(null, null, 0);
16272                    setProfileApp(proc.info, proc.processName, path, fd, false);
16273                    mProfileProc = proc;
16274                    mProfileType = profileType;
16275                    try {
16276                        fd = fd.dup();
16277                    } catch (IOException e) {
16278                        fd = null;
16279                    }
16280                    proc.thread.profilerControl(start, path, fd, profileType);
16281                    fd = null;
16282                    mProfileFd = null;
16283                } else {
16284                    stopProfilerLocked(proc, path, profileType);
16285                    if (fd != null) {
16286                        try {
16287                            fd.close();
16288                        } catch (IOException e) {
16289                        }
16290                    }
16291                }
16292
16293                return true;
16294            }
16295        } catch (RemoteException e) {
16296            throw new IllegalStateException("Process disappeared");
16297        } finally {
16298            if (fd != null) {
16299                try {
16300                    fd.close();
16301                } catch (IOException e) {
16302                }
16303            }
16304        }
16305    }
16306
16307    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16308        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16309                userId, true, true, callName, null);
16310        ProcessRecord proc = null;
16311        try {
16312            int pid = Integer.parseInt(process);
16313            synchronized (mPidsSelfLocked) {
16314                proc = mPidsSelfLocked.get(pid);
16315            }
16316        } catch (NumberFormatException e) {
16317        }
16318
16319        if (proc == null) {
16320            ArrayMap<String, SparseArray<ProcessRecord>> all
16321                    = mProcessNames.getMap();
16322            SparseArray<ProcessRecord> procs = all.get(process);
16323            if (procs != null && procs.size() > 0) {
16324                proc = procs.valueAt(0);
16325                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16326                    for (int i=1; i<procs.size(); i++) {
16327                        ProcessRecord thisProc = procs.valueAt(i);
16328                        if (thisProc.userId == userId) {
16329                            proc = thisProc;
16330                            break;
16331                        }
16332                    }
16333                }
16334            }
16335        }
16336
16337        return proc;
16338    }
16339
16340    public boolean dumpHeap(String process, int userId, boolean managed,
16341            String path, ParcelFileDescriptor fd) throws RemoteException {
16342
16343        try {
16344            synchronized (this) {
16345                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16346                // its own permission (same as profileControl).
16347                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16348                        != PackageManager.PERMISSION_GRANTED) {
16349                    throw new SecurityException("Requires permission "
16350                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16351                }
16352
16353                if (fd == null) {
16354                    throw new IllegalArgumentException("null fd");
16355                }
16356
16357                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16358                if (proc == null || proc.thread == null) {
16359                    throw new IllegalArgumentException("Unknown process: " + process);
16360                }
16361
16362                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16363                if (!isDebuggable) {
16364                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16365                        throw new SecurityException("Process not debuggable: " + proc);
16366                    }
16367                }
16368
16369                proc.thread.dumpHeap(managed, path, fd);
16370                fd = null;
16371                return true;
16372            }
16373        } catch (RemoteException e) {
16374            throw new IllegalStateException("Process disappeared");
16375        } finally {
16376            if (fd != null) {
16377                try {
16378                    fd.close();
16379                } catch (IOException e) {
16380                }
16381            }
16382        }
16383    }
16384
16385    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16386    public void monitor() {
16387        synchronized (this) { }
16388    }
16389
16390    void onCoreSettingsChange(Bundle settings) {
16391        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16392            ProcessRecord processRecord = mLruProcesses.get(i);
16393            try {
16394                if (processRecord.thread != null) {
16395                    processRecord.thread.setCoreSettings(settings);
16396                }
16397            } catch (RemoteException re) {
16398                /* ignore */
16399            }
16400        }
16401    }
16402
16403    // Multi-user methods
16404
16405    /**
16406     * Start user, if its not already running, but don't bring it to foreground.
16407     */
16408    @Override
16409    public boolean startUserInBackground(final int userId) {
16410        return startUser(userId, /* foreground */ false);
16411    }
16412
16413    /**
16414     * Refreshes the list of users related to the current user when either a
16415     * user switch happens or when a new related user is started in the
16416     * background.
16417     */
16418    private void updateCurrentProfileIdsLocked() {
16419        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16420                mCurrentUserId, false /* enabledOnly */);
16421        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16422        for (int i = 0; i < currentProfileIds.length; i++) {
16423            currentProfileIds[i] = profiles.get(i).id;
16424        }
16425        mCurrentProfileIds = currentProfileIds;
16426    }
16427
16428    private Set getProfileIdsLocked(int userId) {
16429        Set userIds = new HashSet<Integer>();
16430        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16431                userId, false /* enabledOnly */);
16432        for (UserInfo user : profiles) {
16433            userIds.add(Integer.valueOf(user.id));
16434        }
16435        return userIds;
16436    }
16437
16438    @Override
16439    public boolean switchUser(final int userId) {
16440        return startUser(userId, /* foregound */ true);
16441    }
16442
16443    private boolean startUser(final int userId, boolean foreground) {
16444        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16445                != PackageManager.PERMISSION_GRANTED) {
16446            String msg = "Permission Denial: switchUser() from pid="
16447                    + Binder.getCallingPid()
16448                    + ", uid=" + Binder.getCallingUid()
16449                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16450            Slog.w(TAG, msg);
16451            throw new SecurityException(msg);
16452        }
16453
16454        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16455
16456        final long ident = Binder.clearCallingIdentity();
16457        try {
16458            synchronized (this) {
16459                final int oldUserId = mCurrentUserId;
16460                if (oldUserId == userId) {
16461                    return true;
16462                }
16463
16464                mStackSupervisor.setLockTaskModeLocked(null);
16465
16466                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16467                if (userInfo == null) {
16468                    Slog.w(TAG, "No user info for user #" + userId);
16469                    return false;
16470                }
16471
16472                if (foreground) {
16473                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16474                            R.anim.screen_user_enter);
16475                }
16476
16477                boolean needStart = false;
16478
16479                // If the user we are switching to is not currently started, then
16480                // we need to start it now.
16481                if (mStartedUsers.get(userId) == null) {
16482                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16483                    updateStartedUserArrayLocked();
16484                    needStart = true;
16485                }
16486
16487                final Integer userIdInt = Integer.valueOf(userId);
16488                mUserLru.remove(userIdInt);
16489                mUserLru.add(userIdInt);
16490
16491                if (foreground) {
16492                    mCurrentUserId = userId;
16493                    updateCurrentProfileIdsLocked();
16494                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16495                    // Once the internal notion of the active user has switched, we lock the device
16496                    // with the option to show the user switcher on the keyguard.
16497                    mWindowManager.lockNow(null);
16498                } else {
16499                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16500                    updateCurrentProfileIdsLocked();
16501                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16502                    mUserLru.remove(currentUserIdInt);
16503                    mUserLru.add(currentUserIdInt);
16504                }
16505
16506                final UserStartedState uss = mStartedUsers.get(userId);
16507
16508                // Make sure user is in the started state.  If it is currently
16509                // stopping, we need to knock that off.
16510                if (uss.mState == UserStartedState.STATE_STOPPING) {
16511                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16512                    // so we can just fairly silently bring the user back from
16513                    // the almost-dead.
16514                    uss.mState = UserStartedState.STATE_RUNNING;
16515                    updateStartedUserArrayLocked();
16516                    needStart = true;
16517                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16518                    // This means ACTION_SHUTDOWN has been sent, so we will
16519                    // need to treat this as a new boot of the user.
16520                    uss.mState = UserStartedState.STATE_BOOTING;
16521                    updateStartedUserArrayLocked();
16522                    needStart = true;
16523                }
16524
16525                if (uss.mState == UserStartedState.STATE_BOOTING) {
16526                    // Booting up a new user, need to tell system services about it.
16527                    // Note that this is on the same handler as scheduling of broadcasts,
16528                    // which is important because it needs to go first.
16529                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
16530                }
16531
16532                if (foreground) {
16533                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId));
16534                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16535                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16536                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16537                            oldUserId, userId, uss));
16538                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16539                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16540                }
16541
16542                if (needStart) {
16543                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16544                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16545                            | Intent.FLAG_RECEIVER_FOREGROUND);
16546                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16547                    broadcastIntentLocked(null, null, intent,
16548                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16549                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16550                }
16551
16552                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16553                    if (userId != UserHandle.USER_OWNER) {
16554                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16555                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16556                        broadcastIntentLocked(null, null, intent, null,
16557                                new IIntentReceiver.Stub() {
16558                                    public void performReceive(Intent intent, int resultCode,
16559                                            String data, Bundle extras, boolean ordered,
16560                                            boolean sticky, int sendingUser) {
16561                                        userInitialized(uss, userId);
16562                                    }
16563                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16564                                true, false, MY_PID, Process.SYSTEM_UID,
16565                                userId);
16566                        uss.initializing = true;
16567                    } else {
16568                        getUserManagerLocked().makeInitialized(userInfo.id);
16569                    }
16570                }
16571
16572                if (foreground) {
16573                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16574                    if (homeInFront) {
16575                        startHomeActivityLocked(userId);
16576                    } else {
16577                        mStackSupervisor.resumeTopActivitiesLocked();
16578                    }
16579                    EventLogTags.writeAmSwitchUser(userId);
16580                    getUserManagerLocked().userForeground(userId);
16581                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16582                } else {
16583                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
16584                }
16585
16586                if (needStart) {
16587                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16588                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16589                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16590                    broadcastIntentLocked(null, null, intent,
16591                            null, new IIntentReceiver.Stub() {
16592                                @Override
16593                                public void performReceive(Intent intent, int resultCode, String data,
16594                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16595                                        throws RemoteException {
16596                                }
16597                            }, 0, null, null,
16598                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16599                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16600                }
16601            }
16602        } finally {
16603            Binder.restoreCallingIdentity(ident);
16604        }
16605
16606        return true;
16607    }
16608
16609    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16610        long ident = Binder.clearCallingIdentity();
16611        try {
16612            Intent intent;
16613            if (oldUserId >= 0) {
16614                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16615                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16616                        | Intent.FLAG_RECEIVER_FOREGROUND);
16617                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16618                broadcastIntentLocked(null, null, intent,
16619                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16620                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16621            }
16622            if (newUserId >= 0) {
16623                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16624                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16625                        | Intent.FLAG_RECEIVER_FOREGROUND);
16626                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16627                broadcastIntentLocked(null, null, intent,
16628                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16629                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16630                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16631                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16632                        | Intent.FLAG_RECEIVER_FOREGROUND);
16633                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16634                broadcastIntentLocked(null, null, intent,
16635                        null, null, 0, null, null,
16636                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16637                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16638            }
16639        } finally {
16640            Binder.restoreCallingIdentity(ident);
16641        }
16642    }
16643
16644    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16645            final int newUserId) {
16646        final int N = mUserSwitchObservers.beginBroadcast();
16647        if (N > 0) {
16648            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16649                int mCount = 0;
16650                @Override
16651                public void sendResult(Bundle data) throws RemoteException {
16652                    synchronized (ActivityManagerService.this) {
16653                        if (mCurUserSwitchCallback == this) {
16654                            mCount++;
16655                            if (mCount == N) {
16656                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16657                            }
16658                        }
16659                    }
16660                }
16661            };
16662            synchronized (this) {
16663                uss.switching = true;
16664                mCurUserSwitchCallback = callback;
16665            }
16666            for (int i=0; i<N; i++) {
16667                try {
16668                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16669                            newUserId, callback);
16670                } catch (RemoteException e) {
16671                }
16672            }
16673        } else {
16674            synchronized (this) {
16675                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16676            }
16677        }
16678        mUserSwitchObservers.finishBroadcast();
16679    }
16680
16681    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16682        synchronized (this) {
16683            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16684            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16685        }
16686    }
16687
16688    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16689        mCurUserSwitchCallback = null;
16690        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16691        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16692                oldUserId, newUserId, uss));
16693    }
16694
16695    void userInitialized(UserStartedState uss, int newUserId) {
16696        completeSwitchAndInitalize(uss, newUserId, true, false);
16697    }
16698
16699    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16700        completeSwitchAndInitalize(uss, newUserId, false, true);
16701    }
16702
16703    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16704            boolean clearInitializing, boolean clearSwitching) {
16705        boolean unfrozen = false;
16706        synchronized (this) {
16707            if (clearInitializing) {
16708                uss.initializing = false;
16709                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16710            }
16711            if (clearSwitching) {
16712                uss.switching = false;
16713            }
16714            if (!uss.switching && !uss.initializing) {
16715                mWindowManager.stopFreezingScreen();
16716                unfrozen = true;
16717            }
16718        }
16719        if (unfrozen) {
16720            final int N = mUserSwitchObservers.beginBroadcast();
16721            for (int i=0; i<N; i++) {
16722                try {
16723                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16724                } catch (RemoteException e) {
16725                }
16726            }
16727            mUserSwitchObservers.finishBroadcast();
16728        }
16729    }
16730
16731    void scheduleStartProfilesLocked() {
16732        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
16733            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
16734                    DateUtils.SECOND_IN_MILLIS);
16735        }
16736    }
16737
16738    void startProfilesLocked() {
16739        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
16740        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16741                mCurrentUserId, false /* enabledOnly */);
16742        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
16743        for (UserInfo user : profiles) {
16744            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
16745                    && user.id != mCurrentUserId) {
16746                toStart.add(user);
16747            }
16748        }
16749        final int n = toStart.size();
16750        int i = 0;
16751        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
16752            startUserInBackground(toStart.get(i).id);
16753        }
16754        if (i < n) {
16755            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
16756        }
16757    }
16758
16759    void finishUserBoot(UserStartedState uss) {
16760        synchronized (this) {
16761            if (uss.mState == UserStartedState.STATE_BOOTING
16762                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16763                uss.mState = UserStartedState.STATE_RUNNING;
16764                final int userId = uss.mHandle.getIdentifier();
16765                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16766                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16767                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16768                broadcastIntentLocked(null, null, intent,
16769                        null, null, 0, null, null,
16770                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16771                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16772            }
16773        }
16774    }
16775
16776    void finishUserSwitch(UserStartedState uss) {
16777        synchronized (this) {
16778            finishUserBoot(uss);
16779
16780            startProfilesLocked();
16781
16782            int num = mUserLru.size();
16783            int i = 0;
16784            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16785                Integer oldUserId = mUserLru.get(i);
16786                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16787                if (oldUss == null) {
16788                    // Shouldn't happen, but be sane if it does.
16789                    mUserLru.remove(i);
16790                    num--;
16791                    continue;
16792                }
16793                if (oldUss.mState == UserStartedState.STATE_STOPPING
16794                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16795                    // This user is already stopping, doesn't count.
16796                    num--;
16797                    i++;
16798                    continue;
16799                }
16800                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16801                    // Owner and current can't be stopped, but count as running.
16802                    i++;
16803                    continue;
16804                }
16805                // This is a user to be stopped.
16806                stopUserLocked(oldUserId, null);
16807                num--;
16808                i++;
16809            }
16810        }
16811    }
16812
16813    @Override
16814    public int stopUser(final int userId, final IStopUserCallback callback) {
16815        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16816                != PackageManager.PERMISSION_GRANTED) {
16817            String msg = "Permission Denial: switchUser() from pid="
16818                    + Binder.getCallingPid()
16819                    + ", uid=" + Binder.getCallingUid()
16820                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16821            Slog.w(TAG, msg);
16822            throw new SecurityException(msg);
16823        }
16824        if (userId <= 0) {
16825            throw new IllegalArgumentException("Can't stop primary user " + userId);
16826        }
16827        synchronized (this) {
16828            return stopUserLocked(userId, callback);
16829        }
16830    }
16831
16832    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16833        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
16834        if (mCurrentUserId == userId) {
16835            return ActivityManager.USER_OP_IS_CURRENT;
16836        }
16837
16838        final UserStartedState uss = mStartedUsers.get(userId);
16839        if (uss == null) {
16840            // User is not started, nothing to do...  but we do need to
16841            // callback if requested.
16842            if (callback != null) {
16843                mHandler.post(new Runnable() {
16844                    @Override
16845                    public void run() {
16846                        try {
16847                            callback.userStopped(userId);
16848                        } catch (RemoteException e) {
16849                        }
16850                    }
16851                });
16852            }
16853            return ActivityManager.USER_OP_SUCCESS;
16854        }
16855
16856        if (callback != null) {
16857            uss.mStopCallbacks.add(callback);
16858        }
16859
16860        if (uss.mState != UserStartedState.STATE_STOPPING
16861                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16862            uss.mState = UserStartedState.STATE_STOPPING;
16863            updateStartedUserArrayLocked();
16864
16865            long ident = Binder.clearCallingIdentity();
16866            try {
16867                // We are going to broadcast ACTION_USER_STOPPING and then
16868                // once that is done send a final ACTION_SHUTDOWN and then
16869                // stop the user.
16870                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16871                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16872                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16873                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16874                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16875                // This is the result receiver for the final shutdown broadcast.
16876                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16877                    @Override
16878                    public void performReceive(Intent intent, int resultCode, String data,
16879                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16880                        finishUserStop(uss);
16881                    }
16882                };
16883                // This is the result receiver for the initial stopping broadcast.
16884                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16885                    @Override
16886                    public void performReceive(Intent intent, int resultCode, String data,
16887                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16888                        // On to the next.
16889                        synchronized (ActivityManagerService.this) {
16890                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16891                                // Whoops, we are being started back up.  Abort, abort!
16892                                return;
16893                            }
16894                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16895                        }
16896                        mSystemServiceManager.stopUser(userId);
16897                        broadcastIntentLocked(null, null, shutdownIntent,
16898                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16899                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16900                    }
16901                };
16902                // Kick things off.
16903                broadcastIntentLocked(null, null, stoppingIntent,
16904                        null, stoppingReceiver, 0, null, null,
16905                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16906                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16907            } finally {
16908                Binder.restoreCallingIdentity(ident);
16909            }
16910        }
16911
16912        return ActivityManager.USER_OP_SUCCESS;
16913    }
16914
16915    void finishUserStop(UserStartedState uss) {
16916        final int userId = uss.mHandle.getIdentifier();
16917        boolean stopped;
16918        ArrayList<IStopUserCallback> callbacks;
16919        synchronized (this) {
16920            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16921            if (mStartedUsers.get(userId) != uss) {
16922                stopped = false;
16923            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16924                stopped = false;
16925            } else {
16926                stopped = true;
16927                // User can no longer run.
16928                mStartedUsers.remove(userId);
16929                mUserLru.remove(Integer.valueOf(userId));
16930                updateStartedUserArrayLocked();
16931
16932                // Clean up all state and processes associated with the user.
16933                // Kill all the processes for the user.
16934                forceStopUserLocked(userId, "finish user");
16935            }
16936        }
16937
16938        for (int i=0; i<callbacks.size(); i++) {
16939            try {
16940                if (stopped) callbacks.get(i).userStopped(userId);
16941                else callbacks.get(i).userStopAborted(userId);
16942            } catch (RemoteException e) {
16943            }
16944        }
16945
16946        if (stopped) {
16947            mSystemServiceManager.cleanupUser(userId);
16948            synchronized (this) {
16949                mStackSupervisor.removeUserLocked(userId);
16950            }
16951        }
16952    }
16953
16954    @Override
16955    public UserInfo getCurrentUser() {
16956        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16957                != PackageManager.PERMISSION_GRANTED) && (
16958                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16959                != PackageManager.PERMISSION_GRANTED)) {
16960            String msg = "Permission Denial: getCurrentUser() from pid="
16961                    + Binder.getCallingPid()
16962                    + ", uid=" + Binder.getCallingUid()
16963                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16964            Slog.w(TAG, msg);
16965            throw new SecurityException(msg);
16966        }
16967        synchronized (this) {
16968            return getUserManagerLocked().getUserInfo(mCurrentUserId);
16969        }
16970    }
16971
16972    int getCurrentUserIdLocked() {
16973        return mCurrentUserId;
16974    }
16975
16976    @Override
16977    public boolean isUserRunning(int userId, boolean orStopped) {
16978        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16979                != PackageManager.PERMISSION_GRANTED) {
16980            String msg = "Permission Denial: isUserRunning() from pid="
16981                    + Binder.getCallingPid()
16982                    + ", uid=" + Binder.getCallingUid()
16983                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16984            Slog.w(TAG, msg);
16985            throw new SecurityException(msg);
16986        }
16987        synchronized (this) {
16988            return isUserRunningLocked(userId, orStopped);
16989        }
16990    }
16991
16992    boolean isUserRunningLocked(int userId, boolean orStopped) {
16993        UserStartedState state = mStartedUsers.get(userId);
16994        if (state == null) {
16995            return false;
16996        }
16997        if (orStopped) {
16998            return true;
16999        }
17000        return state.mState != UserStartedState.STATE_STOPPING
17001                && state.mState != UserStartedState.STATE_SHUTDOWN;
17002    }
17003
17004    @Override
17005    public int[] getRunningUserIds() {
17006        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17007                != PackageManager.PERMISSION_GRANTED) {
17008            String msg = "Permission Denial: isUserRunning() from pid="
17009                    + Binder.getCallingPid()
17010                    + ", uid=" + Binder.getCallingUid()
17011                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17012            Slog.w(TAG, msg);
17013            throw new SecurityException(msg);
17014        }
17015        synchronized (this) {
17016            return mStartedUserArray;
17017        }
17018    }
17019
17020    private void updateStartedUserArrayLocked() {
17021        int num = 0;
17022        for (int i=0; i<mStartedUsers.size();  i++) {
17023            UserStartedState uss = mStartedUsers.valueAt(i);
17024            // This list does not include stopping users.
17025            if (uss.mState != UserStartedState.STATE_STOPPING
17026                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17027                num++;
17028            }
17029        }
17030        mStartedUserArray = new int[num];
17031        num = 0;
17032        for (int i=0; i<mStartedUsers.size();  i++) {
17033            UserStartedState uss = mStartedUsers.valueAt(i);
17034            if (uss.mState != UserStartedState.STATE_STOPPING
17035                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17036                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17037                num++;
17038            }
17039        }
17040    }
17041
17042    @Override
17043    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17044        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
17045                != PackageManager.PERMISSION_GRANTED) {
17046            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17047                    + Binder.getCallingPid()
17048                    + ", uid=" + Binder.getCallingUid()
17049                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
17050            Slog.w(TAG, msg);
17051            throw new SecurityException(msg);
17052        }
17053
17054        mUserSwitchObservers.register(observer);
17055    }
17056
17057    @Override
17058    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17059        mUserSwitchObservers.unregister(observer);
17060    }
17061
17062    private boolean userExists(int userId) {
17063        if (userId == 0) {
17064            return true;
17065        }
17066        UserManagerService ums = getUserManagerLocked();
17067        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17068    }
17069
17070    int[] getUsersLocked() {
17071        UserManagerService ums = getUserManagerLocked();
17072        return ums != null ? ums.getUserIds() : new int[] { 0 };
17073    }
17074
17075    UserManagerService getUserManagerLocked() {
17076        if (mUserManager == null) {
17077            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17078            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17079        }
17080        return mUserManager;
17081    }
17082
17083    private int applyUserId(int uid, int userId) {
17084        return UserHandle.getUid(userId, uid);
17085    }
17086
17087    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17088        if (info == null) return null;
17089        ApplicationInfo newInfo = new ApplicationInfo(info);
17090        newInfo.uid = applyUserId(info.uid, userId);
17091        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17092                + info.packageName;
17093        return newInfo;
17094    }
17095
17096    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17097        if (aInfo == null
17098                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17099            return aInfo;
17100        }
17101
17102        ActivityInfo info = new ActivityInfo(aInfo);
17103        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17104        return info;
17105    }
17106
17107    private final class LocalService extends ActivityManagerInternal {
17108        @Override
17109        public void goingToSleep() {
17110            ActivityManagerService.this.goingToSleep();
17111        }
17112
17113        @Override
17114        public void wakingUp() {
17115            ActivityManagerService.this.wakingUp();
17116        }
17117    }
17118}
17119