ActivityManagerService.java revision a449dc033b79775b8945d9cc5a035a6deb145065
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.app.IAppTask;
36import android.appwidget.AppWidgetManager;
37import android.graphics.Rect;
38import android.os.BatteryStats;
39import android.os.PersistableBundle;
40import android.service.voice.IVoiceInteractionSession;
41import android.util.ArrayMap;
42
43import com.android.internal.R;
44import com.android.internal.annotations.GuardedBy;
45import com.android.internal.app.IAppOpsService;
46import com.android.internal.app.IVoiceInteractor;
47import com.android.internal.app.ProcessMap;
48import com.android.internal.app.ProcessStats;
49import com.android.internal.content.PackageMonitor;
50import com.android.internal.os.BackgroundThread;
51import com.android.internal.os.BatteryStatsImpl;
52import com.android.internal.os.ProcessCpuTracker;
53import com.android.internal.os.TransferPipe;
54import com.android.internal.os.Zygote;
55import com.android.internal.util.FastPrintWriter;
56import com.android.internal.util.FastXmlSerializer;
57import com.android.internal.util.MemInfoReader;
58import com.android.internal.util.Preconditions;
59import com.android.server.AppOpsService;
60import com.android.server.AttributeCache;
61import com.android.server.IntentResolver;
62import com.android.server.LocalServices;
63import com.android.server.ServiceThread;
64import com.android.server.SystemService;
65import com.android.server.SystemServiceManager;
66import com.android.server.Watchdog;
67import com.android.server.am.ActivityStack.ActivityState;
68import com.android.server.firewall.IntentFirewall;
69import com.android.server.pm.UserManagerService;
70import com.android.server.wm.AppTransition;
71import com.android.server.wm.WindowManagerService;
72import com.google.android.collect.Lists;
73import com.google.android.collect.Maps;
74
75import libcore.io.IoUtils;
76
77import org.xmlpull.v1.XmlPullParser;
78import org.xmlpull.v1.XmlPullParserException;
79import org.xmlpull.v1.XmlSerializer;
80
81import android.app.Activity;
82import android.app.ActivityManager;
83import android.app.ActivityManager.RunningTaskInfo;
84import android.app.ActivityManager.StackInfo;
85import android.app.ActivityManagerInternal;
86import android.app.ActivityManagerNative;
87import android.app.ActivityOptions;
88import android.app.ActivityThread;
89import android.app.AlertDialog;
90import android.app.AppGlobals;
91import android.app.ApplicationErrorReport;
92import android.app.Dialog;
93import android.app.IActivityController;
94import android.app.IApplicationThread;
95import android.app.IInstrumentationWatcher;
96import android.app.INotificationManager;
97import android.app.IProcessObserver;
98import android.app.IServiceConnection;
99import android.app.IStopUserCallback;
100import android.app.IUiAutomationConnection;
101import android.app.IUserSwitchObserver;
102import android.app.Instrumentation;
103import android.app.Notification;
104import android.app.NotificationManager;
105import android.app.PendingIntent;
106import android.app.backup.IBackupManager;
107import android.content.ActivityNotFoundException;
108import android.content.BroadcastReceiver;
109import android.content.ClipData;
110import android.content.ComponentCallbacks2;
111import android.content.ComponentName;
112import android.content.ContentProvider;
113import android.content.ContentResolver;
114import android.content.Context;
115import android.content.DialogInterface;
116import android.content.IContentProvider;
117import android.content.IIntentReceiver;
118import android.content.IIntentSender;
119import android.content.Intent;
120import android.content.IntentFilter;
121import android.content.IntentSender;
122import android.content.pm.ActivityInfo;
123import android.content.pm.ApplicationInfo;
124import android.content.pm.ConfigurationInfo;
125import android.content.pm.IPackageDataObserver;
126import android.content.pm.IPackageManager;
127import android.content.pm.InstrumentationInfo;
128import android.content.pm.PackageInfo;
129import android.content.pm.PackageManager;
130import android.content.pm.ParceledListSlice;
131import android.content.pm.UserInfo;
132import android.content.pm.PackageManager.NameNotFoundException;
133import android.content.pm.PathPermission;
134import android.content.pm.ProviderInfo;
135import android.content.pm.ResolveInfo;
136import android.content.pm.ServiceInfo;
137import android.content.res.CompatibilityInfo;
138import android.content.res.Configuration;
139import android.graphics.Bitmap;
140import android.net.Proxy;
141import android.net.ProxyInfo;
142import android.net.Uri;
143import android.os.Binder;
144import android.os.Build;
145import android.os.Bundle;
146import android.os.Debug;
147import android.os.DropBoxManager;
148import android.os.Environment;
149import android.os.FactoryTest;
150import android.os.FileObserver;
151import android.os.FileUtils;
152import android.os.Handler;
153import android.os.IBinder;
154import android.os.IPermissionController;
155import android.os.IRemoteCallback;
156import android.os.IUserManager;
157import android.os.Looper;
158import android.os.Message;
159import android.os.Parcel;
160import android.os.ParcelFileDescriptor;
161import android.os.Process;
162import android.os.RemoteCallbackList;
163import android.os.RemoteException;
164import android.os.SELinux;
165import android.os.ServiceManager;
166import android.os.StrictMode;
167import android.os.SystemClock;
168import android.os.SystemProperties;
169import android.os.UpdateLock;
170import android.os.UserHandle;
171import android.provider.Settings;
172import android.text.format.DateUtils;
173import android.text.format.Time;
174import android.util.AtomicFile;
175import android.util.EventLog;
176import android.util.Log;
177import android.util.Pair;
178import android.util.PrintWriterPrinter;
179import android.util.Slog;
180import android.util.SparseArray;
181import android.util.TimeUtils;
182import android.util.Xml;
183import android.view.Gravity;
184import android.view.LayoutInflater;
185import android.view.View;
186import android.view.WindowManager;
187
188import java.io.BufferedInputStream;
189import java.io.BufferedOutputStream;
190import java.io.DataInputStream;
191import java.io.DataOutputStream;
192import java.io.File;
193import java.io.FileDescriptor;
194import java.io.FileInputStream;
195import java.io.FileNotFoundException;
196import java.io.FileOutputStream;
197import java.io.IOException;
198import java.io.InputStreamReader;
199import java.io.PrintWriter;
200import java.io.StringWriter;
201import java.lang.ref.WeakReference;
202import java.util.ArrayList;
203import java.util.Arrays;
204import java.util.Collections;
205import java.util.Comparator;
206import java.util.HashMap;
207import java.util.HashSet;
208import java.util.Iterator;
209import java.util.List;
210import java.util.Locale;
211import java.util.Map;
212import java.util.Set;
213import java.util.concurrent.atomic.AtomicBoolean;
214import java.util.concurrent.atomic.AtomicLong;
215
216public final class ActivityManagerService extends ActivityManagerNative
217        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
218    private static final String USER_DATA_DIR = "/data/user/";
219    static final String TAG = "ActivityManager";
220    static final String TAG_MU = "ActivityManagerServiceMU";
221    static final boolean DEBUG = false;
222    static final boolean localLOGV = DEBUG;
223    static final boolean DEBUG_BACKUP = localLOGV || false;
224    static final boolean DEBUG_BROADCAST = localLOGV || false;
225    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
226    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
227    static final boolean DEBUG_CLEANUP = localLOGV || false;
228    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
229    static final boolean DEBUG_FOCUS = false;
230    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
231    static final boolean DEBUG_MU = localLOGV || false;
232    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
233    static final boolean DEBUG_LRU = localLOGV || false;
234    static final boolean DEBUG_PAUSE = localLOGV || false;
235    static final boolean DEBUG_POWER = localLOGV || false;
236    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
237    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
238    static final boolean DEBUG_PROCESSES = localLOGV || false;
239    static final boolean DEBUG_PROVIDER = localLOGV || false;
240    static final boolean DEBUG_RESULTS = localLOGV || false;
241    static final boolean DEBUG_SERVICE = localLOGV || false;
242    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
243    static final boolean DEBUG_STACK = localLOGV || false;
244    static final boolean DEBUG_SWITCH = localLOGV || false;
245    static final boolean DEBUG_TASKS = localLOGV || false;
246    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
247    static final boolean DEBUG_TRANSITION = localLOGV || false;
248    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
249    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
250    static final boolean DEBUG_VISBILITY = localLOGV || false;
251    static final boolean DEBUG_PSS = localLOGV || false;
252    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
253    static final boolean VALIDATE_TOKENS = false;
254    static final boolean SHOW_ACTIVITY_START_TIME = true;
255
256    // Control over CPU and battery monitoring.
257    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
258    static final boolean MONITOR_CPU_USAGE = true;
259    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
260    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
261    static final boolean MONITOR_THREAD_CPU_USAGE = false;
262
263    // The flags that are set for all calls we make to the package manager.
264    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
265
266    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
267
268    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
269
270    // Maximum number of recent tasks that we can remember.
271    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20;
272
273    // Amount of time after a call to stopAppSwitches() during which we will
274    // prevent further untrusted switches from happening.
275    static final long APP_SWITCH_DELAY_TIME = 5*1000;
276
277    // How long we wait for a launched process to attach to the activity manager
278    // before we decide it's never going to come up for real.
279    static final int PROC_START_TIMEOUT = 10*1000;
280
281    // How long we wait for a launched process to attach to the activity manager
282    // before we decide it's never going to come up for real, when the process was
283    // started with a wrapper for instrumentation (such as Valgrind) because it
284    // could take much longer than usual.
285    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
286
287    // How long to wait after going idle before forcing apps to GC.
288    static final int GC_TIMEOUT = 5*1000;
289
290    // The minimum amount of time between successive GC requests for a process.
291    static final int GC_MIN_INTERVAL = 60*1000;
292
293    // The minimum amount of time between successive PSS requests for a process.
294    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
295
296    // The minimum amount of time between successive PSS requests for a process
297    // when the request is due to the memory state being lowered.
298    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
299
300    // The rate at which we check for apps using excessive power -- 15 mins.
301    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
302
303    // The minimum sample duration we will allow before deciding we have
304    // enough data on wake locks to start killing things.
305    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
306
307    // The minimum sample duration we will allow before deciding we have
308    // enough data on CPU usage to start killing things.
309    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
310
311    // How long we allow a receiver to run before giving up on it.
312    static final int BROADCAST_FG_TIMEOUT = 10*1000;
313    static final int BROADCAST_BG_TIMEOUT = 60*1000;
314
315    // How long we wait until we timeout on key dispatching.
316    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
317
318    // How long we wait until we timeout on key dispatching during instrumentation.
319    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
320
321    // Amount of time we wait for observers to handle a user switch before
322    // giving up on them and unfreezing the screen.
323    static final int USER_SWITCH_TIMEOUT = 2*1000;
324
325    // Maximum number of users we allow to be running at a time.
326    static final int MAX_RUNNING_USERS = 3;
327
328    // How long to wait in getAssistContextExtras for the activity and foreground services
329    // to respond with the result.
330    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
331
332    // Maximum number of persisted Uri grants a package is allowed
333    static final int MAX_PERSISTED_URI_GRANTS = 128;
334
335    static final int MY_PID = Process.myPid();
336
337    static final String[] EMPTY_STRING_ARRAY = new String[0];
338
339    // How many bytes to write into the dropbox log before truncating
340    static final int DROPBOX_MAX_SIZE = 256 * 1024;
341
342    /** All system services */
343    SystemServiceManager mSystemServiceManager;
344
345    /** Run all ActivityStacks through this */
346    ActivityStackSupervisor mStackSupervisor;
347
348    public IntentFirewall mIntentFirewall;
349
350    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
351    // default actuion automatically.  Important for devices without direct input
352    // devices.
353    private boolean mShowDialogs = true;
354
355    /**
356     * Description of a request to start a new activity, which has been held
357     * due to app switches being disabled.
358     */
359    static class PendingActivityLaunch {
360        final ActivityRecord r;
361        final ActivityRecord sourceRecord;
362        final int startFlags;
363        final ActivityStack stack;
364
365        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
366                int _startFlags, ActivityStack _stack) {
367            r = _r;
368            sourceRecord = _sourceRecord;
369            startFlags = _startFlags;
370            stack = _stack;
371        }
372    }
373
374    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
375            = new ArrayList<PendingActivityLaunch>();
376
377    BroadcastQueue mFgBroadcastQueue;
378    BroadcastQueue mBgBroadcastQueue;
379    // Convenient for easy iteration over the queues. Foreground is first
380    // so that dispatch of foreground broadcasts gets precedence.
381    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
382
383    BroadcastQueue broadcastQueueForIntent(Intent intent) {
384        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
385        if (DEBUG_BACKGROUND_BROADCAST) {
386            Slog.i(TAG, "Broadcast intent " + intent + " on "
387                    + (isFg ? "foreground" : "background")
388                    + " queue");
389        }
390        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
391    }
392
393    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
394        for (BroadcastQueue queue : mBroadcastQueues) {
395            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
396            if (r != null) {
397                return r;
398            }
399        }
400        return null;
401    }
402
403    /**
404     * Activity we have told the window manager to have key focus.
405     */
406    ActivityRecord mFocusedActivity = null;
407
408    /**
409     * List of intents that were used to start the most recent tasks.
410     */
411    final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
412
413    public class PendingAssistExtras extends Binder implements Runnable {
414        public final ActivityRecord activity;
415        public boolean haveResult = false;
416        public Bundle result = null;
417        public PendingAssistExtras(ActivityRecord _activity) {
418            activity = _activity;
419        }
420        @Override
421        public void run() {
422            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
423            synchronized (this) {
424                haveResult = true;
425                notifyAll();
426            }
427        }
428    }
429
430    final ArrayList<PendingAssistExtras> mPendingAssistExtras
431            = new ArrayList<PendingAssistExtras>();
432
433    /**
434     * Process management.
435     */
436    final ProcessList mProcessList = new ProcessList();
437
438    /**
439     * All of the applications we currently have running organized by name.
440     * The keys are strings of the application package name (as
441     * returned by the package manager), and the keys are ApplicationRecord
442     * objects.
443     */
444    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
445
446    /**
447     * Tracking long-term execution of processes to look for abuse and other
448     * bad app behavior.
449     */
450    final ProcessStatsService mProcessStats;
451
452    /**
453     * The currently running isolated processes.
454     */
455    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
456
457    /**
458     * Counter for assigning isolated process uids, to avoid frequently reusing the
459     * same ones.
460     */
461    int mNextIsolatedProcessUid = 0;
462
463    /**
464     * The currently running heavy-weight process, if any.
465     */
466    ProcessRecord mHeavyWeightProcess = null;
467
468    /**
469     * The last time that various processes have crashed.
470     */
471    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
472
473    /**
474     * Information about a process that is currently marked as bad.
475     */
476    static final class BadProcessInfo {
477        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
478            this.time = time;
479            this.shortMsg = shortMsg;
480            this.longMsg = longMsg;
481            this.stack = stack;
482        }
483
484        final long time;
485        final String shortMsg;
486        final String longMsg;
487        final String stack;
488    }
489
490    /**
491     * Set of applications that we consider to be bad, and will reject
492     * incoming broadcasts from (which the user has no control over).
493     * Processes are added to this set when they have crashed twice within
494     * a minimum amount of time; they are removed from it when they are
495     * later restarted (hopefully due to some user action).  The value is the
496     * time it was added to the list.
497     */
498    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
499
500    /**
501     * All of the processes we currently have running organized by pid.
502     * The keys are the pid running the application.
503     *
504     * <p>NOTE: This object is protected by its own lock, NOT the global
505     * activity manager lock!
506     */
507    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
508
509    /**
510     * All of the processes that have been forced to be foreground.  The key
511     * is the pid of the caller who requested it (we hold a death
512     * link on it).
513     */
514    abstract class ForegroundToken implements IBinder.DeathRecipient {
515        int pid;
516        IBinder token;
517    }
518    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
519
520    /**
521     * List of records for processes that someone had tried to start before the
522     * system was ready.  We don't start them at that point, but ensure they
523     * are started by the time booting is complete.
524     */
525    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
526
527    /**
528     * List of persistent applications that are in the process
529     * of being started.
530     */
531    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
532
533    /**
534     * Processes that are being forcibly torn down.
535     */
536    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
537
538    /**
539     * List of running applications, sorted by recent usage.
540     * The first entry in the list is the least recently used.
541     */
542    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
543
544    /**
545     * Where in mLruProcesses that the processes hosting activities start.
546     */
547    int mLruProcessActivityStart = 0;
548
549    /**
550     * Where in mLruProcesses that the processes hosting services start.
551     * This is after (lower index) than mLruProcessesActivityStart.
552     */
553    int mLruProcessServiceStart = 0;
554
555    /**
556     * List of processes that should gc as soon as things are idle.
557     */
558    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
559
560    /**
561     * Processes we want to collect PSS data from.
562     */
563    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
564
565    /**
566     * Last time we requested PSS data of all processes.
567     */
568    long mLastFullPssTime = SystemClock.uptimeMillis();
569
570    /**
571     * This is the process holding what we currently consider to be
572     * the "home" activity.
573     */
574    ProcessRecord mHomeProcess;
575
576    /**
577     * This is the process holding the activity the user last visited that
578     * is in a different process from the one they are currently in.
579     */
580    ProcessRecord mPreviousProcess;
581
582    /**
583     * The time at which the previous process was last visible.
584     */
585    long mPreviousProcessVisibleTime;
586
587    /**
588     * Which uses have been started, so are allowed to run code.
589     */
590    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
591
592    /**
593     * LRU list of history of current users.  Most recently current is at the end.
594     */
595    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
596
597    /**
598     * Constant array of the users that are currently started.
599     */
600    int[] mStartedUserArray = new int[] { 0 };
601
602    /**
603     * Registered observers of the user switching mechanics.
604     */
605    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
606            = new RemoteCallbackList<IUserSwitchObserver>();
607
608    /**
609     * Currently active user switch.
610     */
611    Object mCurUserSwitchCallback;
612
613    /**
614     * Packages that the user has asked to have run in screen size
615     * compatibility mode instead of filling the screen.
616     */
617    final CompatModePackages mCompatModePackages;
618
619    /**
620     * Set of IntentSenderRecord objects that are currently active.
621     */
622    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
623            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
624
625    /**
626     * Fingerprints (hashCode()) of stack traces that we've
627     * already logged DropBox entries for.  Guarded by itself.  If
628     * something (rogue user app) forces this over
629     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
630     */
631    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
632    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
633
634    /**
635     * Strict Mode background batched logging state.
636     *
637     * The string buffer is guarded by itself, and its lock is also
638     * used to determine if another batched write is already
639     * in-flight.
640     */
641    private final StringBuilder mStrictModeBuffer = new StringBuilder();
642
643    /**
644     * Keeps track of all IIntentReceivers that have been registered for
645     * broadcasts.  Hash keys are the receiver IBinder, hash value is
646     * a ReceiverList.
647     */
648    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
649            new HashMap<IBinder, ReceiverList>();
650
651    /**
652     * Resolver for broadcast intents to registered receivers.
653     * Holds BroadcastFilter (subclass of IntentFilter).
654     */
655    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
656            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
657        @Override
658        protected boolean allowFilterResult(
659                BroadcastFilter filter, List<BroadcastFilter> dest) {
660            IBinder target = filter.receiverList.receiver.asBinder();
661            for (int i=dest.size()-1; i>=0; i--) {
662                if (dest.get(i).receiverList.receiver.asBinder() == target) {
663                    return false;
664                }
665            }
666            return true;
667        }
668
669        @Override
670        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
671            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
672                    || userId == filter.owningUserId) {
673                return super.newResult(filter, match, userId);
674            }
675            return null;
676        }
677
678        @Override
679        protected BroadcastFilter[] newArray(int size) {
680            return new BroadcastFilter[size];
681        }
682
683        @Override
684        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
685            return packageName.equals(filter.packageName);
686        }
687    };
688
689    /**
690     * State of all active sticky broadcasts per user.  Keys are the action of the
691     * sticky Intent, values are an ArrayList of all broadcasted intents with
692     * that action (which should usually be one).  The SparseArray is keyed
693     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
694     * for stickies that are sent to all users.
695     */
696    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
697            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
698
699    final ActiveServices mServices;
700
701    /**
702     * Backup/restore process management
703     */
704    String mBackupAppName = null;
705    BackupRecord mBackupTarget = null;
706
707    final ProviderMap mProviderMap;
708
709    /**
710     * List of content providers who have clients waiting for them.  The
711     * application is currently being launched and the provider will be
712     * removed from this list once it is published.
713     */
714    final ArrayList<ContentProviderRecord> mLaunchingProviders
715            = new ArrayList<ContentProviderRecord>();
716
717    /**
718     * File storing persisted {@link #mGrantedUriPermissions}.
719     */
720    private final AtomicFile mGrantFile;
721
722    /** XML constants used in {@link #mGrantFile} */
723    private static final String TAG_URI_GRANTS = "uri-grants";
724    private static final String TAG_URI_GRANT = "uri-grant";
725    private static final String ATTR_USER_HANDLE = "userHandle";
726    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
727    private static final String ATTR_TARGET_USER_ID = "targetUserId";
728    private static final String ATTR_SOURCE_PKG = "sourcePkg";
729    private static final String ATTR_TARGET_PKG = "targetPkg";
730    private static final String ATTR_URI = "uri";
731    private static final String ATTR_MODE_FLAGS = "modeFlags";
732    private static final String ATTR_CREATED_TIME = "createdTime";
733    private static final String ATTR_PREFIX = "prefix";
734
735    /**
736     * Global set of specific {@link Uri} permissions that have been granted.
737     * This optimized lookup structure maps from {@link UriPermission#targetUid}
738     * to {@link UriPermission#uri} to {@link UriPermission}.
739     */
740    @GuardedBy("this")
741    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
742            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
743
744    public static class GrantUri {
745        public final int sourceUserId;
746        public final Uri uri;
747        public boolean prefix;
748
749        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
750            this.sourceUserId = sourceUserId;
751            this.uri = uri;
752            this.prefix = prefix;
753        }
754
755        @Override
756        public int hashCode() {
757            return toString().hashCode();
758        }
759
760        @Override
761        public boolean equals(Object o) {
762            if (o instanceof GrantUri) {
763                GrantUri other = (GrantUri) o;
764                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
765                        && prefix == other.prefix;
766            }
767            return false;
768        }
769
770        @Override
771        public String toString() {
772            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
773            if (prefix) result += " [prefix]";
774            return result;
775        }
776
777        public String toSafeString() {
778            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
779            if (prefix) result += " [prefix]";
780            return result;
781        }
782
783        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
784            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
785                    ContentProvider.getUriWithoutUserId(uri), false);
786        }
787    }
788
789    CoreSettingsObserver mCoreSettingsObserver;
790
791    /**
792     * Thread-local storage used to carry caller permissions over through
793     * indirect content-provider access.
794     */
795    private class Identity {
796        public int pid;
797        public int uid;
798
799        Identity(int _pid, int _uid) {
800            pid = _pid;
801            uid = _uid;
802        }
803    }
804
805    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
806
807    /**
808     * All information we have collected about the runtime performance of
809     * any user id that can impact battery performance.
810     */
811    final BatteryStatsService mBatteryStatsService;
812
813    /**
814     * Information about component usage
815     */
816    final UsageStatsService mUsageStatsService;
817
818    /**
819     * Information about and control over application operations
820     */
821    final AppOpsService mAppOpsService;
822
823    /**
824     * Current configuration information.  HistoryRecord objects are given
825     * a reference to this object to indicate which configuration they are
826     * currently running in, so this object must be kept immutable.
827     */
828    Configuration mConfiguration = new Configuration();
829
830    /**
831     * Current sequencing integer of the configuration, for skipping old
832     * configurations.
833     */
834    int mConfigurationSeq = 0;
835
836    /**
837     * Hardware-reported OpenGLES version.
838     */
839    final int GL_ES_VERSION;
840
841    /**
842     * List of initialization arguments to pass to all processes when binding applications to them.
843     * For example, references to the commonly used services.
844     */
845    HashMap<String, IBinder> mAppBindArgs;
846
847    /**
848     * Temporary to avoid allocations.  Protected by main lock.
849     */
850    final StringBuilder mStringBuilder = new StringBuilder(256);
851
852    /**
853     * Used to control how we initialize the service.
854     */
855    ComponentName mTopComponent;
856    String mTopAction = Intent.ACTION_MAIN;
857    String mTopData;
858    boolean mProcessesReady = false;
859    boolean mSystemReady = false;
860    boolean mBooting = false;
861    boolean mWaitingUpdate = false;
862    boolean mDidUpdate = false;
863    boolean mOnBattery = false;
864    boolean mLaunchWarningShown = false;
865
866    Context mContext;
867
868    int mFactoryTest;
869
870    boolean mCheckedForSetup;
871
872    /**
873     * The time at which we will allow normal application switches again,
874     * after a call to {@link #stopAppSwitches()}.
875     */
876    long mAppSwitchesAllowedTime;
877
878    /**
879     * This is set to true after the first switch after mAppSwitchesAllowedTime
880     * is set; any switches after that will clear the time.
881     */
882    boolean mDidAppSwitch;
883
884    /**
885     * Last time (in realtime) at which we checked for power usage.
886     */
887    long mLastPowerCheckRealtime;
888
889    /**
890     * Last time (in uptime) at which we checked for power usage.
891     */
892    long mLastPowerCheckUptime;
893
894    /**
895     * Set while we are wanting to sleep, to prevent any
896     * activities from being started/resumed.
897     */
898    private boolean mSleeping = false;
899
900    /**
901     * Set while we are running a voice interaction.  This overrides
902     * sleeping while it is active.
903     */
904    private boolean mRunningVoice = false;
905
906    /**
907     * State of external calls telling us if the device is asleep.
908     */
909    private boolean mWentToSleep = false;
910
911    /**
912     * State of external call telling us if the lock screen is shown.
913     */
914    private boolean mLockScreenShown = false;
915
916    /**
917     * Set if we are shutting down the system, similar to sleeping.
918     */
919    boolean mShuttingDown = false;
920
921    /**
922     * Current sequence id for oom_adj computation traversal.
923     */
924    int mAdjSeq = 0;
925
926    /**
927     * Current sequence id for process LRU updating.
928     */
929    int mLruSeq = 0;
930
931    /**
932     * Keep track of the non-cached/empty process we last found, to help
933     * determine how to distribute cached/empty processes next time.
934     */
935    int mNumNonCachedProcs = 0;
936
937    /**
938     * Keep track of the number of cached hidden procs, to balance oom adj
939     * distribution between those and empty procs.
940     */
941    int mNumCachedHiddenProcs = 0;
942
943    /**
944     * Keep track of the number of service processes we last found, to
945     * determine on the next iteration which should be B services.
946     */
947    int mNumServiceProcs = 0;
948    int mNewNumAServiceProcs = 0;
949    int mNewNumServiceProcs = 0;
950
951    /**
952     * Allow the current computed overall memory level of the system to go down?
953     * This is set to false when we are killing processes for reasons other than
954     * memory management, so that the now smaller process list will not be taken as
955     * an indication that memory is tighter.
956     */
957    boolean mAllowLowerMemLevel = false;
958
959    /**
960     * The last computed memory level, for holding when we are in a state that
961     * processes are going away for other reasons.
962     */
963    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
964
965    /**
966     * The last total number of process we have, to determine if changes actually look
967     * like a shrinking number of process due to lower RAM.
968     */
969    int mLastNumProcesses;
970
971    /**
972     * The uptime of the last time we performed idle maintenance.
973     */
974    long mLastIdleTime = SystemClock.uptimeMillis();
975
976    /**
977     * Total time spent with RAM that has been added in the past since the last idle time.
978     */
979    long mLowRamTimeSinceLastIdle = 0;
980
981    /**
982     * If RAM is currently low, when that horrible situation started.
983     */
984    long mLowRamStartTime = 0;
985
986    /**
987     * For reporting to battery stats the current top application.
988     */
989    private String mCurResumedPackage = null;
990    private int mCurResumedUid = -1;
991
992    /**
993     * For reporting to battery stats the apps currently running foreground
994     * service.  The ProcessMap is package/uid tuples; each of these contain
995     * an array of the currently foreground processes.
996     */
997    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
998            = new ProcessMap<ArrayList<ProcessRecord>>();
999
1000    /**
1001     * This is set if we had to do a delayed dexopt of an app before launching
1002     * it, to increase the ANR timeouts in that case.
1003     */
1004    boolean mDidDexOpt;
1005
1006    /**
1007     * Set if the systemServer made a call to enterSafeMode.
1008     */
1009    boolean mSafeMode;
1010
1011    String mDebugApp = null;
1012    boolean mWaitForDebugger = false;
1013    boolean mDebugTransient = false;
1014    String mOrigDebugApp = null;
1015    boolean mOrigWaitForDebugger = false;
1016    boolean mAlwaysFinishActivities = false;
1017    IActivityController mController = null;
1018    String mProfileApp = null;
1019    ProcessRecord mProfileProc = null;
1020    String mProfileFile;
1021    ParcelFileDescriptor mProfileFd;
1022    int mProfileType = 0;
1023    boolean mAutoStopProfiler = false;
1024    String mOpenGlTraceApp = null;
1025
1026    static class ProcessChangeItem {
1027        static final int CHANGE_ACTIVITIES = 1<<0;
1028        static final int CHANGE_PROCESS_STATE = 1<<1;
1029        int changes;
1030        int uid;
1031        int pid;
1032        int processState;
1033        boolean foregroundActivities;
1034    }
1035
1036    final RemoteCallbackList<IProcessObserver> mProcessObservers
1037            = new RemoteCallbackList<IProcessObserver>();
1038    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1039
1040    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1041            = new ArrayList<ProcessChangeItem>();
1042    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1043            = new ArrayList<ProcessChangeItem>();
1044
1045    /**
1046     * Runtime CPU use collection thread.  This object's lock is used to
1047     * protect all related state.
1048     */
1049    final Thread mProcessCpuThread;
1050
1051    /**
1052     * Used to collect process stats when showing not responding dialog.
1053     * Protected by mProcessCpuThread.
1054     */
1055    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1056            MONITOR_THREAD_CPU_USAGE);
1057    final AtomicLong mLastCpuTime = new AtomicLong(0);
1058    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1059
1060    long mLastWriteTime = 0;
1061
1062    /**
1063     * Used to retain an update lock when the foreground activity is in
1064     * immersive mode.
1065     */
1066    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1067
1068    /**
1069     * Set to true after the system has finished booting.
1070     */
1071    boolean mBooted = false;
1072
1073    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1074    int mProcessLimitOverride = -1;
1075
1076    WindowManagerService mWindowManager;
1077
1078    final ActivityThread mSystemThread;
1079
1080    int mCurrentUserId = 0;
1081    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1082    private UserManagerService mUserManager;
1083
1084    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1085        final ProcessRecord mApp;
1086        final int mPid;
1087        final IApplicationThread mAppThread;
1088
1089        AppDeathRecipient(ProcessRecord app, int pid,
1090                IApplicationThread thread) {
1091            if (localLOGV) Slog.v(
1092                TAG, "New death recipient " + this
1093                + " for thread " + thread.asBinder());
1094            mApp = app;
1095            mPid = pid;
1096            mAppThread = thread;
1097        }
1098
1099        @Override
1100        public void binderDied() {
1101            if (localLOGV) Slog.v(
1102                TAG, "Death received in " + this
1103                + " for thread " + mAppThread.asBinder());
1104            synchronized(ActivityManagerService.this) {
1105                appDiedLocked(mApp, mPid, mAppThread);
1106            }
1107        }
1108    }
1109
1110    static final int SHOW_ERROR_MSG = 1;
1111    static final int SHOW_NOT_RESPONDING_MSG = 2;
1112    static final int SHOW_FACTORY_ERROR_MSG = 3;
1113    static final int UPDATE_CONFIGURATION_MSG = 4;
1114    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1115    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1116    static final int SERVICE_TIMEOUT_MSG = 12;
1117    static final int UPDATE_TIME_ZONE = 13;
1118    static final int SHOW_UID_ERROR_MSG = 14;
1119    static final int IM_FEELING_LUCKY_MSG = 15;
1120    static final int PROC_START_TIMEOUT_MSG = 20;
1121    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1122    static final int KILL_APPLICATION_MSG = 22;
1123    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1124    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1125    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1126    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1127    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1128    static final int CLEAR_DNS_CACHE_MSG = 28;
1129    static final int UPDATE_HTTP_PROXY_MSG = 29;
1130    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1131    static final int DISPATCH_PROCESSES_CHANGED = 31;
1132    static final int DISPATCH_PROCESS_DIED = 32;
1133    static final int REPORT_MEM_USAGE_MSG = 33;
1134    static final int REPORT_USER_SWITCH_MSG = 34;
1135    static final int CONTINUE_USER_SWITCH_MSG = 35;
1136    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1137    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1138    static final int PERSIST_URI_GRANTS_MSG = 38;
1139    static final int REQUEST_ALL_PSS_MSG = 39;
1140    static final int START_PROFILES_MSG = 40;
1141    static final int UPDATE_TIME = 41;
1142    static final int SYSTEM_USER_START_MSG = 42;
1143    static final int SYSTEM_USER_CURRENT_MSG = 43;
1144
1145    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1146    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1147    static final int FIRST_COMPAT_MODE_MSG = 300;
1148    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1149
1150    AlertDialog mUidAlert;
1151    CompatModeDialog mCompatModeDialog;
1152    long mLastMemUsageReportTime = 0;
1153
1154    /**
1155     * Flag whether the current user is a "monkey", i.e. whether
1156     * the UI is driven by a UI automation tool.
1157     */
1158    private boolean mUserIsMonkey;
1159
1160    final ServiceThread mHandlerThread;
1161    final MainHandler mHandler;
1162
1163    final class MainHandler extends Handler {
1164        public MainHandler(Looper looper) {
1165            super(looper, null, true);
1166        }
1167
1168        @Override
1169        public void handleMessage(Message msg) {
1170            switch (msg.what) {
1171            case SHOW_ERROR_MSG: {
1172                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1173                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1174                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1175                synchronized (ActivityManagerService.this) {
1176                    ProcessRecord proc = (ProcessRecord)data.get("app");
1177                    AppErrorResult res = (AppErrorResult) data.get("result");
1178                    if (proc != null && proc.crashDialog != null) {
1179                        Slog.e(TAG, "App already has crash dialog: " + proc);
1180                        if (res != null) {
1181                            res.set(0);
1182                        }
1183                        return;
1184                    }
1185                    if (!showBackground && UserHandle.getAppId(proc.uid)
1186                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1187                            && proc.pid != MY_PID) {
1188                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1189                        if (res != null) {
1190                            res.set(0);
1191                        }
1192                        return;
1193                    }
1194                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1195                        Dialog d = new AppErrorDialog(mContext,
1196                                ActivityManagerService.this, res, proc);
1197                        d.show();
1198                        proc.crashDialog = d;
1199                    } else {
1200                        // The device is asleep, so just pretend that the user
1201                        // saw a crash dialog and hit "force quit".
1202                        if (res != null) {
1203                            res.set(0);
1204                        }
1205                    }
1206                }
1207
1208                ensureBootCompleted();
1209            } break;
1210            case SHOW_NOT_RESPONDING_MSG: {
1211                synchronized (ActivityManagerService.this) {
1212                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1213                    ProcessRecord proc = (ProcessRecord)data.get("app");
1214                    if (proc != null && proc.anrDialog != null) {
1215                        Slog.e(TAG, "App already has anr dialog: " + proc);
1216                        return;
1217                    }
1218
1219                    Intent intent = new Intent("android.intent.action.ANR");
1220                    if (!mProcessesReady) {
1221                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1222                                | Intent.FLAG_RECEIVER_FOREGROUND);
1223                    }
1224                    broadcastIntentLocked(null, null, intent,
1225                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1226                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1227
1228                    if (mShowDialogs) {
1229                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1230                                mContext, proc, (ActivityRecord)data.get("activity"),
1231                                msg.arg1 != 0);
1232                        d.show();
1233                        proc.anrDialog = d;
1234                    } else {
1235                        // Just kill the app if there is no dialog to be shown.
1236                        killAppAtUsersRequest(proc, null);
1237                    }
1238                }
1239
1240                ensureBootCompleted();
1241            } break;
1242            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1243                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1244                synchronized (ActivityManagerService.this) {
1245                    ProcessRecord proc = (ProcessRecord) data.get("app");
1246                    if (proc == null) {
1247                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1248                        break;
1249                    }
1250                    if (proc.crashDialog != null) {
1251                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1252                        return;
1253                    }
1254                    AppErrorResult res = (AppErrorResult) data.get("result");
1255                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1256                        Dialog d = new StrictModeViolationDialog(mContext,
1257                                ActivityManagerService.this, res, proc);
1258                        d.show();
1259                        proc.crashDialog = d;
1260                    } else {
1261                        // The device is asleep, so just pretend that the user
1262                        // saw a crash dialog and hit "force quit".
1263                        res.set(0);
1264                    }
1265                }
1266                ensureBootCompleted();
1267            } break;
1268            case SHOW_FACTORY_ERROR_MSG: {
1269                Dialog d = new FactoryErrorDialog(
1270                    mContext, msg.getData().getCharSequence("msg"));
1271                d.show();
1272                ensureBootCompleted();
1273            } break;
1274            case UPDATE_CONFIGURATION_MSG: {
1275                final ContentResolver resolver = mContext.getContentResolver();
1276                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1277            } break;
1278            case GC_BACKGROUND_PROCESSES_MSG: {
1279                synchronized (ActivityManagerService.this) {
1280                    performAppGcsIfAppropriateLocked();
1281                }
1282            } break;
1283            case WAIT_FOR_DEBUGGER_MSG: {
1284                synchronized (ActivityManagerService.this) {
1285                    ProcessRecord app = (ProcessRecord)msg.obj;
1286                    if (msg.arg1 != 0) {
1287                        if (!app.waitedForDebugger) {
1288                            Dialog d = new AppWaitingForDebuggerDialog(
1289                                    ActivityManagerService.this,
1290                                    mContext, app);
1291                            app.waitDialog = d;
1292                            app.waitedForDebugger = true;
1293                            d.show();
1294                        }
1295                    } else {
1296                        if (app.waitDialog != null) {
1297                            app.waitDialog.dismiss();
1298                            app.waitDialog = null;
1299                        }
1300                    }
1301                }
1302            } break;
1303            case SERVICE_TIMEOUT_MSG: {
1304                if (mDidDexOpt) {
1305                    mDidDexOpt = false;
1306                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1307                    nmsg.obj = msg.obj;
1308                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1309                    return;
1310                }
1311                mServices.serviceTimeout((ProcessRecord)msg.obj);
1312            } break;
1313            case UPDATE_TIME_ZONE: {
1314                synchronized (ActivityManagerService.this) {
1315                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1316                        ProcessRecord r = mLruProcesses.get(i);
1317                        if (r.thread != null) {
1318                            try {
1319                                r.thread.updateTimeZone();
1320                            } catch (RemoteException ex) {
1321                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1322                            }
1323                        }
1324                    }
1325                }
1326            } break;
1327            case CLEAR_DNS_CACHE_MSG: {
1328                synchronized (ActivityManagerService.this) {
1329                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1330                        ProcessRecord r = mLruProcesses.get(i);
1331                        if (r.thread != null) {
1332                            try {
1333                                r.thread.clearDnsCache();
1334                            } catch (RemoteException ex) {
1335                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1336                            }
1337                        }
1338                    }
1339                }
1340            } break;
1341            case UPDATE_HTTP_PROXY_MSG: {
1342                ProxyInfo proxy = (ProxyInfo)msg.obj;
1343                String host = "";
1344                String port = "";
1345                String exclList = "";
1346                Uri pacFileUrl = Uri.EMPTY;
1347                if (proxy != null) {
1348                    host = proxy.getHost();
1349                    port = Integer.toString(proxy.getPort());
1350                    exclList = proxy.getExclusionListAsString();
1351                    pacFileUrl = proxy.getPacFileUrl();
1352                }
1353                synchronized (ActivityManagerService.this) {
1354                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1355                        ProcessRecord r = mLruProcesses.get(i);
1356                        if (r.thread != null) {
1357                            try {
1358                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1359                            } catch (RemoteException ex) {
1360                                Slog.w(TAG, "Failed to update http proxy for: " +
1361                                        r.info.processName);
1362                            }
1363                        }
1364                    }
1365                }
1366            } break;
1367            case SHOW_UID_ERROR_MSG: {
1368                String title = "System UIDs Inconsistent";
1369                String text = "UIDs on the system are inconsistent, you need to wipe your"
1370                        + " data partition or your device will be unstable.";
1371                Log.e(TAG, title + ": " + text);
1372                if (mShowDialogs) {
1373                    // XXX This is a temporary dialog, no need to localize.
1374                    AlertDialog d = new BaseErrorDialog(mContext);
1375                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1376                    d.setCancelable(false);
1377                    d.setTitle(title);
1378                    d.setMessage(text);
1379                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1380                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1381                    mUidAlert = d;
1382                    d.show();
1383                }
1384            } break;
1385            case IM_FEELING_LUCKY_MSG: {
1386                if (mUidAlert != null) {
1387                    mUidAlert.dismiss();
1388                    mUidAlert = null;
1389                }
1390            } break;
1391            case PROC_START_TIMEOUT_MSG: {
1392                if (mDidDexOpt) {
1393                    mDidDexOpt = false;
1394                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1395                    nmsg.obj = msg.obj;
1396                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1397                    return;
1398                }
1399                ProcessRecord app = (ProcessRecord)msg.obj;
1400                synchronized (ActivityManagerService.this) {
1401                    processStartTimedOutLocked(app);
1402                }
1403            } break;
1404            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1405                synchronized (ActivityManagerService.this) {
1406                    doPendingActivityLaunchesLocked(true);
1407                }
1408            } break;
1409            case KILL_APPLICATION_MSG: {
1410                synchronized (ActivityManagerService.this) {
1411                    int appid = msg.arg1;
1412                    boolean restart = (msg.arg2 == 1);
1413                    Bundle bundle = (Bundle)msg.obj;
1414                    String pkg = bundle.getString("pkg");
1415                    String reason = bundle.getString("reason");
1416                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1417                            false, UserHandle.USER_ALL, reason);
1418                }
1419            } break;
1420            case FINALIZE_PENDING_INTENT_MSG: {
1421                ((PendingIntentRecord)msg.obj).completeFinalize();
1422            } break;
1423            case POST_HEAVY_NOTIFICATION_MSG: {
1424                INotificationManager inm = NotificationManager.getService();
1425                if (inm == null) {
1426                    return;
1427                }
1428
1429                ActivityRecord root = (ActivityRecord)msg.obj;
1430                ProcessRecord process = root.app;
1431                if (process == null) {
1432                    return;
1433                }
1434
1435                try {
1436                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1437                    String text = mContext.getString(R.string.heavy_weight_notification,
1438                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1439                    Notification notification = new Notification();
1440                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1441                    notification.when = 0;
1442                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1443                    notification.tickerText = text;
1444                    notification.defaults = 0; // please be quiet
1445                    notification.sound = null;
1446                    notification.vibrate = null;
1447                    notification.setLatestEventInfo(context, text,
1448                            mContext.getText(R.string.heavy_weight_notification_detail),
1449                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1450                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1451                                    new UserHandle(root.userId)));
1452
1453                    try {
1454                        int[] outId = new int[1];
1455                        inm.enqueueNotificationWithTag("android", "android", null,
1456                                R.string.heavy_weight_notification,
1457                                notification, outId, root.userId);
1458                    } catch (RuntimeException e) {
1459                        Slog.w(ActivityManagerService.TAG,
1460                                "Error showing notification for heavy-weight app", e);
1461                    } catch (RemoteException e) {
1462                    }
1463                } catch (NameNotFoundException e) {
1464                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1465                }
1466            } break;
1467            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1468                INotificationManager inm = NotificationManager.getService();
1469                if (inm == null) {
1470                    return;
1471                }
1472                try {
1473                    inm.cancelNotificationWithTag("android", null,
1474                            R.string.heavy_weight_notification,  msg.arg1);
1475                } catch (RuntimeException e) {
1476                    Slog.w(ActivityManagerService.TAG,
1477                            "Error canceling notification for service", e);
1478                } catch (RemoteException e) {
1479                }
1480            } break;
1481            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1482                synchronized (ActivityManagerService.this) {
1483                    checkExcessivePowerUsageLocked(true);
1484                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1485                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1486                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1487                }
1488            } break;
1489            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1490                synchronized (ActivityManagerService.this) {
1491                    ActivityRecord ar = (ActivityRecord)msg.obj;
1492                    if (mCompatModeDialog != null) {
1493                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1494                                ar.info.applicationInfo.packageName)) {
1495                            return;
1496                        }
1497                        mCompatModeDialog.dismiss();
1498                        mCompatModeDialog = null;
1499                    }
1500                    if (ar != null && false) {
1501                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1502                                ar.packageName)) {
1503                            int mode = mCompatModePackages.computeCompatModeLocked(
1504                                    ar.info.applicationInfo);
1505                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1506                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1507                                mCompatModeDialog = new CompatModeDialog(
1508                                        ActivityManagerService.this, mContext,
1509                                        ar.info.applicationInfo);
1510                                mCompatModeDialog.show();
1511                            }
1512                        }
1513                    }
1514                }
1515                break;
1516            }
1517            case DISPATCH_PROCESSES_CHANGED: {
1518                dispatchProcessesChanged();
1519                break;
1520            }
1521            case DISPATCH_PROCESS_DIED: {
1522                final int pid = msg.arg1;
1523                final int uid = msg.arg2;
1524                dispatchProcessDied(pid, uid);
1525                break;
1526            }
1527            case REPORT_MEM_USAGE_MSG: {
1528                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1529                Thread thread = new Thread() {
1530                    @Override public void run() {
1531                        final SparseArray<ProcessMemInfo> infoMap
1532                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1533                        for (int i=0, N=memInfos.size(); i<N; i++) {
1534                            ProcessMemInfo mi = memInfos.get(i);
1535                            infoMap.put(mi.pid, mi);
1536                        }
1537                        updateCpuStatsNow();
1538                        synchronized (mProcessCpuThread) {
1539                            final int N = mProcessCpuTracker.countStats();
1540                            for (int i=0; i<N; i++) {
1541                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1542                                if (st.vsize > 0) {
1543                                    long pss = Debug.getPss(st.pid, null);
1544                                    if (pss > 0) {
1545                                        if (infoMap.indexOfKey(st.pid) < 0) {
1546                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1547                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1548                                            mi.pss = pss;
1549                                            memInfos.add(mi);
1550                                        }
1551                                    }
1552                                }
1553                            }
1554                        }
1555
1556                        long totalPss = 0;
1557                        for (int i=0, N=memInfos.size(); i<N; i++) {
1558                            ProcessMemInfo mi = memInfos.get(i);
1559                            if (mi.pss == 0) {
1560                                mi.pss = Debug.getPss(mi.pid, null);
1561                            }
1562                            totalPss += mi.pss;
1563                        }
1564                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1565                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1566                                if (lhs.oomAdj != rhs.oomAdj) {
1567                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1568                                }
1569                                if (lhs.pss != rhs.pss) {
1570                                    return lhs.pss < rhs.pss ? 1 : -1;
1571                                }
1572                                return 0;
1573                            }
1574                        });
1575
1576                        StringBuilder tag = new StringBuilder(128);
1577                        StringBuilder stack = new StringBuilder(128);
1578                        tag.append("Low on memory -- ");
1579                        appendMemBucket(tag, totalPss, "total", false);
1580                        appendMemBucket(stack, totalPss, "total", true);
1581
1582                        StringBuilder logBuilder = new StringBuilder(1024);
1583                        logBuilder.append("Low on memory:\n");
1584
1585                        boolean firstLine = true;
1586                        int lastOomAdj = Integer.MIN_VALUE;
1587                        for (int i=0, N=memInfos.size(); i<N; i++) {
1588                            ProcessMemInfo mi = memInfos.get(i);
1589
1590                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1591                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1592                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1593                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1594                                if (lastOomAdj != mi.oomAdj) {
1595                                    lastOomAdj = mi.oomAdj;
1596                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1597                                        tag.append(" / ");
1598                                    }
1599                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1600                                        if (firstLine) {
1601                                            stack.append(":");
1602                                            firstLine = false;
1603                                        }
1604                                        stack.append("\n\t at ");
1605                                    } else {
1606                                        stack.append("$");
1607                                    }
1608                                } else {
1609                                    tag.append(" ");
1610                                    stack.append("$");
1611                                }
1612                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1613                                    appendMemBucket(tag, mi.pss, mi.name, false);
1614                                }
1615                                appendMemBucket(stack, mi.pss, mi.name, true);
1616                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1617                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1618                                    stack.append("(");
1619                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1620                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1621                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1622                                            stack.append(":");
1623                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1624                                        }
1625                                    }
1626                                    stack.append(")");
1627                                }
1628                            }
1629
1630                            logBuilder.append("  ");
1631                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1632                            logBuilder.append(' ');
1633                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1634                            logBuilder.append(' ');
1635                            ProcessList.appendRamKb(logBuilder, mi.pss);
1636                            logBuilder.append(" kB: ");
1637                            logBuilder.append(mi.name);
1638                            logBuilder.append(" (");
1639                            logBuilder.append(mi.pid);
1640                            logBuilder.append(") ");
1641                            logBuilder.append(mi.adjType);
1642                            logBuilder.append('\n');
1643                            if (mi.adjReason != null) {
1644                                logBuilder.append("                      ");
1645                                logBuilder.append(mi.adjReason);
1646                                logBuilder.append('\n');
1647                            }
1648                        }
1649
1650                        logBuilder.append("           ");
1651                        ProcessList.appendRamKb(logBuilder, totalPss);
1652                        logBuilder.append(" kB: TOTAL\n");
1653
1654                        long[] infos = new long[Debug.MEMINFO_COUNT];
1655                        Debug.getMemInfo(infos);
1656                        logBuilder.append("  MemInfo: ");
1657                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1658                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1659                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1660                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1661                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1662                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1663                            logBuilder.append("  ZRAM: ");
1664                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1665                            logBuilder.append(" kB RAM, ");
1666                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1667                            logBuilder.append(" kB swap total, ");
1668                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1669                            logBuilder.append(" kB swap free\n");
1670                        }
1671                        Slog.i(TAG, logBuilder.toString());
1672
1673                        StringBuilder dropBuilder = new StringBuilder(1024);
1674                        /*
1675                        StringWriter oomSw = new StringWriter();
1676                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1677                        StringWriter catSw = new StringWriter();
1678                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1679                        String[] emptyArgs = new String[] { };
1680                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1681                        oomPw.flush();
1682                        String oomString = oomSw.toString();
1683                        */
1684                        dropBuilder.append(stack);
1685                        dropBuilder.append('\n');
1686                        dropBuilder.append('\n');
1687                        dropBuilder.append(logBuilder);
1688                        dropBuilder.append('\n');
1689                        /*
1690                        dropBuilder.append(oomString);
1691                        dropBuilder.append('\n');
1692                        */
1693                        StringWriter catSw = new StringWriter();
1694                        synchronized (ActivityManagerService.this) {
1695                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1696                            String[] emptyArgs = new String[] { };
1697                            catPw.println();
1698                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1699                            catPw.println();
1700                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1701                                    false, false, null);
1702                            catPw.println();
1703                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1704                            catPw.flush();
1705                        }
1706                        dropBuilder.append(catSw.toString());
1707                        addErrorToDropBox("lowmem", null, "system_server", null,
1708                                null, tag.toString(), dropBuilder.toString(), null, null);
1709                        //Slog.i(TAG, "Sent to dropbox:");
1710                        //Slog.i(TAG, dropBuilder.toString());
1711                        synchronized (ActivityManagerService.this) {
1712                            long now = SystemClock.uptimeMillis();
1713                            if (mLastMemUsageReportTime < now) {
1714                                mLastMemUsageReportTime = now;
1715                            }
1716                        }
1717                    }
1718                };
1719                thread.start();
1720                break;
1721            }
1722            case REPORT_USER_SWITCH_MSG: {
1723                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1724                break;
1725            }
1726            case CONTINUE_USER_SWITCH_MSG: {
1727                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1728                break;
1729            }
1730            case USER_SWITCH_TIMEOUT_MSG: {
1731                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1732                break;
1733            }
1734            case IMMERSIVE_MODE_LOCK_MSG: {
1735                final boolean nextState = (msg.arg1 != 0);
1736                if (mUpdateLock.isHeld() != nextState) {
1737                    if (DEBUG_IMMERSIVE) {
1738                        final ActivityRecord r = (ActivityRecord) msg.obj;
1739                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1740                    }
1741                    if (nextState) {
1742                        mUpdateLock.acquire();
1743                    } else {
1744                        mUpdateLock.release();
1745                    }
1746                }
1747                break;
1748            }
1749            case PERSIST_URI_GRANTS_MSG: {
1750                writeGrantedUriPermissions();
1751                break;
1752            }
1753            case REQUEST_ALL_PSS_MSG: {
1754                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1755                break;
1756            }
1757            case START_PROFILES_MSG: {
1758                synchronized (ActivityManagerService.this) {
1759                    startProfilesLocked();
1760                }
1761                break;
1762            }
1763            case UPDATE_TIME: {
1764                synchronized (ActivityManagerService.this) {
1765                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1766                        ProcessRecord r = mLruProcesses.get(i);
1767                        if (r.thread != null) {
1768                            try {
1769                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1770                            } catch (RemoteException ex) {
1771                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1772                            }
1773                        }
1774                    }
1775                }
1776                break;
1777            }
1778            case SYSTEM_USER_START_MSG: {
1779                mSystemServiceManager.startUser(msg.arg1);
1780                break;
1781            }
1782            case SYSTEM_USER_CURRENT_MSG: {
1783                mSystemServiceManager.switchUser(msg.arg1);
1784                break;
1785            }
1786            }
1787        }
1788    };
1789
1790    static final int COLLECT_PSS_BG_MSG = 1;
1791
1792    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1793        @Override
1794        public void handleMessage(Message msg) {
1795            switch (msg.what) {
1796            case COLLECT_PSS_BG_MSG: {
1797                int i=0, num=0;
1798                long start = SystemClock.uptimeMillis();
1799                long[] tmp = new long[1];
1800                do {
1801                    ProcessRecord proc;
1802                    int procState;
1803                    int pid;
1804                    synchronized (ActivityManagerService.this) {
1805                        if (i >= mPendingPssProcesses.size()) {
1806                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1807                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1808                            mPendingPssProcesses.clear();
1809                            return;
1810                        }
1811                        proc = mPendingPssProcesses.get(i);
1812                        procState = proc.pssProcState;
1813                        if (proc.thread != null && procState == proc.setProcState) {
1814                            pid = proc.pid;
1815                        } else {
1816                            proc = null;
1817                            pid = 0;
1818                        }
1819                        i++;
1820                    }
1821                    if (proc != null) {
1822                        long pss = Debug.getPss(pid, tmp);
1823                        synchronized (ActivityManagerService.this) {
1824                            if (proc.thread != null && proc.setProcState == procState
1825                                    && proc.pid == pid) {
1826                                num++;
1827                                proc.lastPssTime = SystemClock.uptimeMillis();
1828                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1829                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1830                                        + ": " + pss + " lastPss=" + proc.lastPss
1831                                        + " state=" + ProcessList.makeProcStateString(procState));
1832                                if (proc.initialIdlePss == 0) {
1833                                    proc.initialIdlePss = pss;
1834                                }
1835                                proc.lastPss = pss;
1836                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1837                                    proc.lastCachedPss = pss;
1838                                }
1839                            }
1840                        }
1841                    }
1842                } while (true);
1843            }
1844            }
1845        }
1846    };
1847
1848    /**
1849     * Monitor for package changes and update our internal state.
1850     */
1851    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1852        @Override
1853        public void onPackageRemoved(String packageName, int uid) {
1854            // Remove all tasks with activities in the specified package from the list of recent tasks
1855            synchronized (ActivityManagerService.this) {
1856                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1857                    TaskRecord tr = mRecentTasks.get(i);
1858                    ComponentName cn = tr.intent.getComponent();
1859                    if (cn != null && cn.getPackageName().equals(packageName)) {
1860                        // If the package name matches, remove the task and kill the process
1861                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1862                    }
1863                }
1864            }
1865        }
1866
1867        @Override
1868        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1869            onPackageModified(packageName);
1870            return true;
1871        }
1872
1873        @Override
1874        public void onPackageModified(String packageName) {
1875            final PackageManager pm = mContext.getPackageManager();
1876            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1877                    new ArrayList<Pair<Intent, Integer>>();
1878            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1879            // Copy the list of recent tasks so that we don't hold onto the lock on
1880            // ActivityManagerService for long periods while checking if components exist.
1881            synchronized (ActivityManagerService.this) {
1882                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1883                    TaskRecord tr = mRecentTasks.get(i);
1884                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1885                }
1886            }
1887            // Check the recent tasks and filter out all tasks with components that no longer exist.
1888            Intent tmpI = new Intent();
1889            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1890                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1891                ComponentName cn = p.first.getComponent();
1892                if (cn != null && cn.getPackageName().equals(packageName)) {
1893                    try {
1894                        // Add the task to the list to remove if the component no longer exists
1895                        tmpI.setComponent(cn);
1896                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1897                            tasksToRemove.add(p.second);
1898                        }
1899                    } catch (Exception e) {}
1900                }
1901            }
1902            // Prune all the tasks with removed components from the list of recent tasks
1903            synchronized (ActivityManagerService.this) {
1904                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1905                    // Remove the task but don't kill the process (since other components in that
1906                    // package may still be running and in the background)
1907                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1908                }
1909            }
1910        }
1911
1912        @Override
1913        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1914            // Force stop the specified packages
1915            if (packages != null) {
1916                for (String pkg : packages) {
1917                    synchronized (ActivityManagerService.this) {
1918                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
1919                                "finished booting")) {
1920                            return true;
1921                        }
1922                    }
1923                }
1924            }
1925            return false;
1926        }
1927    };
1928
1929    public void setSystemProcess() {
1930        try {
1931            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1932            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1933            ServiceManager.addService("meminfo", new MemBinder(this));
1934            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1935            ServiceManager.addService("dbinfo", new DbBinder(this));
1936            if (MONITOR_CPU_USAGE) {
1937                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1938            }
1939            ServiceManager.addService("permission", new PermissionController(this));
1940
1941            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1942                    "android", STOCK_PM_FLAGS);
1943            mSystemThread.installSystemApplicationInfo(info);
1944
1945            synchronized (this) {
1946                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
1947                app.persistent = true;
1948                app.pid = MY_PID;
1949                app.maxAdj = ProcessList.SYSTEM_ADJ;
1950                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1951                mProcessNames.put(app.processName, app.uid, app);
1952                synchronized (mPidsSelfLocked) {
1953                    mPidsSelfLocked.put(app.pid, app);
1954                }
1955                updateLruProcessLocked(app, false, null);
1956                updateOomAdjLocked();
1957            }
1958        } catch (PackageManager.NameNotFoundException e) {
1959            throw new RuntimeException(
1960                    "Unable to find android system package", e);
1961        }
1962    }
1963
1964    public void setWindowManager(WindowManagerService wm) {
1965        mWindowManager = wm;
1966        mStackSupervisor.setWindowManager(wm);
1967    }
1968
1969    public void startObservingNativeCrashes() {
1970        final NativeCrashListener ncl = new NativeCrashListener(this);
1971        ncl.start();
1972    }
1973
1974    public IAppOpsService getAppOpsService() {
1975        return mAppOpsService;
1976    }
1977
1978    static class MemBinder extends Binder {
1979        ActivityManagerService mActivityManagerService;
1980        MemBinder(ActivityManagerService activityManagerService) {
1981            mActivityManagerService = activityManagerService;
1982        }
1983
1984        @Override
1985        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1986            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1987                    != PackageManager.PERMISSION_GRANTED) {
1988                pw.println("Permission Denial: can't dump meminfo from from pid="
1989                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1990                        + " without permission " + android.Manifest.permission.DUMP);
1991                return;
1992            }
1993
1994            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1995        }
1996    }
1997
1998    static class GraphicsBinder extends Binder {
1999        ActivityManagerService mActivityManagerService;
2000        GraphicsBinder(ActivityManagerService activityManagerService) {
2001            mActivityManagerService = activityManagerService;
2002        }
2003
2004        @Override
2005        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2006            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2007                    != PackageManager.PERMISSION_GRANTED) {
2008                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2009                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2010                        + " without permission " + android.Manifest.permission.DUMP);
2011                return;
2012            }
2013
2014            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2015        }
2016    }
2017
2018    static class DbBinder extends Binder {
2019        ActivityManagerService mActivityManagerService;
2020        DbBinder(ActivityManagerService activityManagerService) {
2021            mActivityManagerService = activityManagerService;
2022        }
2023
2024        @Override
2025        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2026            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2027                    != PackageManager.PERMISSION_GRANTED) {
2028                pw.println("Permission Denial: can't dump dbinfo from from pid="
2029                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2030                        + " without permission " + android.Manifest.permission.DUMP);
2031                return;
2032            }
2033
2034            mActivityManagerService.dumpDbInfo(fd, pw, args);
2035        }
2036    }
2037
2038    static class CpuBinder extends Binder {
2039        ActivityManagerService mActivityManagerService;
2040        CpuBinder(ActivityManagerService activityManagerService) {
2041            mActivityManagerService = activityManagerService;
2042        }
2043
2044        @Override
2045        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2046            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2047                    != PackageManager.PERMISSION_GRANTED) {
2048                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2049                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2050                        + " without permission " + android.Manifest.permission.DUMP);
2051                return;
2052            }
2053
2054            synchronized (mActivityManagerService.mProcessCpuThread) {
2055                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2056                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2057                        SystemClock.uptimeMillis()));
2058            }
2059        }
2060    }
2061
2062    public static final class Lifecycle extends SystemService {
2063        private final ActivityManagerService mService;
2064
2065        public Lifecycle(Context context) {
2066            super(context);
2067            mService = new ActivityManagerService(context);
2068        }
2069
2070        @Override
2071        public void onStart() {
2072            mService.start();
2073        }
2074
2075        public ActivityManagerService getService() {
2076            return mService;
2077        }
2078    }
2079
2080    // Note: This method is invoked on the main thread but may need to attach various
2081    // handlers to other threads.  So take care to be explicit about the looper.
2082    public ActivityManagerService(Context systemContext) {
2083        mContext = systemContext;
2084        mFactoryTest = FactoryTest.getMode();
2085        mSystemThread = ActivityThread.currentActivityThread();
2086
2087        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2088
2089        mHandlerThread = new ServiceThread(TAG,
2090                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2091        mHandlerThread.start();
2092        mHandler = new MainHandler(mHandlerThread.getLooper());
2093
2094        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2095                "foreground", BROADCAST_FG_TIMEOUT, false);
2096        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2097                "background", BROADCAST_BG_TIMEOUT, true);
2098        mBroadcastQueues[0] = mFgBroadcastQueue;
2099        mBroadcastQueues[1] = mBgBroadcastQueue;
2100
2101        mServices = new ActiveServices(this);
2102        mProviderMap = new ProviderMap(this);
2103
2104        // TODO: Move creation of battery stats service outside of activity manager service.
2105        File dataDir = Environment.getDataDirectory();
2106        File systemDir = new File(dataDir, "system");
2107        systemDir.mkdirs();
2108        mBatteryStatsService = new BatteryStatsService(new File(
2109                systemDir, "batterystats.bin").toString(), mHandler);
2110        mBatteryStatsService.getActiveStatistics().readLocked();
2111        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2112        mOnBattery = DEBUG_POWER ? true
2113                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2114        mBatteryStatsService.getActiveStatistics().setCallback(this);
2115
2116        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2117
2118        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
2119        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2120
2121        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2122
2123        // User 0 is the first and only user that runs at boot.
2124        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2125        mUserLru.add(Integer.valueOf(0));
2126        updateStartedUserArrayLocked();
2127
2128        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2129            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2130
2131        mConfiguration.setToDefaults();
2132        mConfiguration.setLocale(Locale.getDefault());
2133
2134        mConfigurationSeq = mConfiguration.seq = 1;
2135        mProcessCpuTracker.init();
2136
2137        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2138        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2139        mStackSupervisor = new ActivityStackSupervisor(this);
2140
2141        mProcessCpuThread = new Thread("CpuTracker") {
2142            @Override
2143            public void run() {
2144                while (true) {
2145                    try {
2146                        try {
2147                            synchronized(this) {
2148                                final long now = SystemClock.uptimeMillis();
2149                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2150                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2151                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2152                                //        + ", write delay=" + nextWriteDelay);
2153                                if (nextWriteDelay < nextCpuDelay) {
2154                                    nextCpuDelay = nextWriteDelay;
2155                                }
2156                                if (nextCpuDelay > 0) {
2157                                    mProcessCpuMutexFree.set(true);
2158                                    this.wait(nextCpuDelay);
2159                                }
2160                            }
2161                        } catch (InterruptedException e) {
2162                        }
2163                        updateCpuStatsNow();
2164                    } catch (Exception e) {
2165                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2166                    }
2167                }
2168            }
2169        };
2170
2171        Watchdog.getInstance().addMonitor(this);
2172        Watchdog.getInstance().addThread(mHandler);
2173    }
2174
2175    public void setSystemServiceManager(SystemServiceManager mgr) {
2176        mSystemServiceManager = mgr;
2177    }
2178
2179    private void start() {
2180        mProcessCpuThread.start();
2181
2182        mBatteryStatsService.publish(mContext);
2183        mUsageStatsService.publish(mContext);
2184        mAppOpsService.publish(mContext);
2185
2186        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2187    }
2188
2189    @Override
2190    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2191            throws RemoteException {
2192        if (code == SYSPROPS_TRANSACTION) {
2193            // We need to tell all apps about the system property change.
2194            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2195            synchronized(this) {
2196                final int NP = mProcessNames.getMap().size();
2197                for (int ip=0; ip<NP; ip++) {
2198                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2199                    final int NA = apps.size();
2200                    for (int ia=0; ia<NA; ia++) {
2201                        ProcessRecord app = apps.valueAt(ia);
2202                        if (app.thread != null) {
2203                            procs.add(app.thread.asBinder());
2204                        }
2205                    }
2206                }
2207            }
2208
2209            int N = procs.size();
2210            for (int i=0; i<N; i++) {
2211                Parcel data2 = Parcel.obtain();
2212                try {
2213                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2214                } catch (RemoteException e) {
2215                }
2216                data2.recycle();
2217            }
2218        }
2219        try {
2220            return super.onTransact(code, data, reply, flags);
2221        } catch (RuntimeException e) {
2222            // The activity manager only throws security exceptions, so let's
2223            // log all others.
2224            if (!(e instanceof SecurityException)) {
2225                Slog.wtf(TAG, "Activity Manager Crash", e);
2226            }
2227            throw e;
2228        }
2229    }
2230
2231    void updateCpuStats() {
2232        final long now = SystemClock.uptimeMillis();
2233        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2234            return;
2235        }
2236        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2237            synchronized (mProcessCpuThread) {
2238                mProcessCpuThread.notify();
2239            }
2240        }
2241    }
2242
2243    void updateCpuStatsNow() {
2244        synchronized (mProcessCpuThread) {
2245            mProcessCpuMutexFree.set(false);
2246            final long now = SystemClock.uptimeMillis();
2247            boolean haveNewCpuStats = false;
2248
2249            if (MONITOR_CPU_USAGE &&
2250                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2251                mLastCpuTime.set(now);
2252                haveNewCpuStats = true;
2253                mProcessCpuTracker.update();
2254                //Slog.i(TAG, mProcessCpu.printCurrentState());
2255                //Slog.i(TAG, "Total CPU usage: "
2256                //        + mProcessCpu.getTotalCpuPercent() + "%");
2257
2258                // Slog the cpu usage if the property is set.
2259                if ("true".equals(SystemProperties.get("events.cpu"))) {
2260                    int user = mProcessCpuTracker.getLastUserTime();
2261                    int system = mProcessCpuTracker.getLastSystemTime();
2262                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2263                    int irq = mProcessCpuTracker.getLastIrqTime();
2264                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2265                    int idle = mProcessCpuTracker.getLastIdleTime();
2266
2267                    int total = user + system + iowait + irq + softIrq + idle;
2268                    if (total == 0) total = 1;
2269
2270                    EventLog.writeEvent(EventLogTags.CPU,
2271                            ((user+system+iowait+irq+softIrq) * 100) / total,
2272                            (user * 100) / total,
2273                            (system * 100) / total,
2274                            (iowait * 100) / total,
2275                            (irq * 100) / total,
2276                            (softIrq * 100) / total);
2277                }
2278            }
2279
2280            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2281            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2282            synchronized(bstats) {
2283                synchronized(mPidsSelfLocked) {
2284                    if (haveNewCpuStats) {
2285                        if (mOnBattery) {
2286                            int perc = bstats.startAddingCpuLocked();
2287                            int totalUTime = 0;
2288                            int totalSTime = 0;
2289                            final int N = mProcessCpuTracker.countStats();
2290                            for (int i=0; i<N; i++) {
2291                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2292                                if (!st.working) {
2293                                    continue;
2294                                }
2295                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2296                                int otherUTime = (st.rel_utime*perc)/100;
2297                                int otherSTime = (st.rel_stime*perc)/100;
2298                                totalUTime += otherUTime;
2299                                totalSTime += otherSTime;
2300                                if (pr != null) {
2301                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2302                                    if (ps == null || !ps.isActive()) {
2303                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2304                                                pr.info.uid, pr.processName);
2305                                    }
2306                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2307                                            st.rel_stime-otherSTime);
2308                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2309                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2310                                } else {
2311                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2312                                    if (ps == null || !ps.isActive()) {
2313                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2314                                                bstats.mapUid(st.uid), st.name);
2315                                    }
2316                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2317                                            st.rel_stime-otherSTime);
2318                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2319                                }
2320                            }
2321                            bstats.finishAddingCpuLocked(perc, totalUTime,
2322                                    totalSTime, cpuSpeedTimes);
2323                        }
2324                    }
2325                }
2326
2327                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2328                    mLastWriteTime = now;
2329                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2330                }
2331            }
2332        }
2333    }
2334
2335    @Override
2336    public void batteryNeedsCpuUpdate() {
2337        updateCpuStatsNow();
2338    }
2339
2340    @Override
2341    public void batteryPowerChanged(boolean onBattery) {
2342        // When plugging in, update the CPU stats first before changing
2343        // the plug state.
2344        updateCpuStatsNow();
2345        synchronized (this) {
2346            synchronized(mPidsSelfLocked) {
2347                mOnBattery = DEBUG_POWER ? true : onBattery;
2348            }
2349        }
2350    }
2351
2352    /**
2353     * Initialize the application bind args. These are passed to each
2354     * process when the bindApplication() IPC is sent to the process. They're
2355     * lazily setup to make sure the services are running when they're asked for.
2356     */
2357    private HashMap<String, IBinder> getCommonServicesLocked() {
2358        if (mAppBindArgs == null) {
2359            mAppBindArgs = new HashMap<String, IBinder>();
2360
2361            // Setup the application init args
2362            mAppBindArgs.put("package", ServiceManager.getService("package"));
2363            mAppBindArgs.put("window", ServiceManager.getService("window"));
2364            mAppBindArgs.put(Context.ALARM_SERVICE,
2365                    ServiceManager.getService(Context.ALARM_SERVICE));
2366        }
2367        return mAppBindArgs;
2368    }
2369
2370    final void setFocusedActivityLocked(ActivityRecord r) {
2371        if (mFocusedActivity != r) {
2372            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2373            mFocusedActivity = r;
2374            if (r.task != null && r.task.voiceInteractor != null) {
2375                startRunningVoiceLocked();
2376            } else {
2377                finishRunningVoiceLocked();
2378            }
2379            mStackSupervisor.setFocusedStack(r);
2380            if (r != null) {
2381                mWindowManager.setFocusedApp(r.appToken, true);
2382            }
2383            applyUpdateLockStateLocked(r);
2384        }
2385    }
2386
2387    final void clearFocusedActivity(ActivityRecord r) {
2388        if (mFocusedActivity == r) {
2389            mFocusedActivity = null;
2390        }
2391    }
2392
2393    @Override
2394    public void setFocusedStack(int stackId) {
2395        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2396        synchronized (ActivityManagerService.this) {
2397            ActivityStack stack = mStackSupervisor.getStack(stackId);
2398            if (stack != null) {
2399                ActivityRecord r = stack.topRunningActivityLocked(null);
2400                if (r != null) {
2401                    setFocusedActivityLocked(r);
2402                }
2403            }
2404        }
2405    }
2406
2407    @Override
2408    public void notifyActivityDrawn(IBinder token) {
2409        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2410        synchronized (this) {
2411            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2412            if (r != null) {
2413                r.task.stack.notifyActivityDrawnLocked(r);
2414            }
2415        }
2416    }
2417
2418    final void applyUpdateLockStateLocked(ActivityRecord r) {
2419        // Modifications to the UpdateLock state are done on our handler, outside
2420        // the activity manager's locks.  The new state is determined based on the
2421        // state *now* of the relevant activity record.  The object is passed to
2422        // the handler solely for logging detail, not to be consulted/modified.
2423        final boolean nextState = r != null && r.immersive;
2424        mHandler.sendMessage(
2425                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2426    }
2427
2428    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2429        Message msg = Message.obtain();
2430        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2431        msg.obj = r.task.askedCompatMode ? null : r;
2432        mHandler.sendMessage(msg);
2433    }
2434
2435    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2436            String what, Object obj, ProcessRecord srcApp) {
2437        app.lastActivityTime = now;
2438
2439        if (app.activities.size() > 0) {
2440            // Don't want to touch dependent processes that are hosting activities.
2441            return index;
2442        }
2443
2444        int lrui = mLruProcesses.lastIndexOf(app);
2445        if (lrui < 0) {
2446            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2447                    + what + " " + obj + " from " + srcApp);
2448            return index;
2449        }
2450
2451        if (lrui >= index) {
2452            // Don't want to cause this to move dependent processes *back* in the
2453            // list as if they were less frequently used.
2454            return index;
2455        }
2456
2457        if (lrui >= mLruProcessActivityStart) {
2458            // Don't want to touch dependent processes that are hosting activities.
2459            return index;
2460        }
2461
2462        mLruProcesses.remove(lrui);
2463        if (index > 0) {
2464            index--;
2465        }
2466        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2467                + " in LRU list: " + app);
2468        mLruProcesses.add(index, app);
2469        return index;
2470    }
2471
2472    final void removeLruProcessLocked(ProcessRecord app) {
2473        int lrui = mLruProcesses.lastIndexOf(app);
2474        if (lrui >= 0) {
2475            if (lrui <= mLruProcessActivityStart) {
2476                mLruProcessActivityStart--;
2477            }
2478            if (lrui <= mLruProcessServiceStart) {
2479                mLruProcessServiceStart--;
2480            }
2481            mLruProcesses.remove(lrui);
2482        }
2483    }
2484
2485    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2486            ProcessRecord client) {
2487        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2488                || app.treatLikeActivity;
2489        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2490        if (!activityChange && hasActivity) {
2491            // The process has activities, so we are only allowing activity-based adjustments
2492            // to move it.  It should be kept in the front of the list with other
2493            // processes that have activities, and we don't want those to change their
2494            // order except due to activity operations.
2495            return;
2496        }
2497
2498        mLruSeq++;
2499        final long now = SystemClock.uptimeMillis();
2500        app.lastActivityTime = now;
2501
2502        // First a quick reject: if the app is already at the position we will
2503        // put it, then there is nothing to do.
2504        if (hasActivity) {
2505            final int N = mLruProcesses.size();
2506            if (N > 0 && mLruProcesses.get(N-1) == app) {
2507                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2508                return;
2509            }
2510        } else {
2511            if (mLruProcessServiceStart > 0
2512                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2513                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2514                return;
2515            }
2516        }
2517
2518        int lrui = mLruProcesses.lastIndexOf(app);
2519
2520        if (app.persistent && lrui >= 0) {
2521            // We don't care about the position of persistent processes, as long as
2522            // they are in the list.
2523            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2524            return;
2525        }
2526
2527        /* In progress: compute new position first, so we can avoid doing work
2528           if the process is not actually going to move.  Not yet working.
2529        int addIndex;
2530        int nextIndex;
2531        boolean inActivity = false, inService = false;
2532        if (hasActivity) {
2533            // Process has activities, put it at the very tipsy-top.
2534            addIndex = mLruProcesses.size();
2535            nextIndex = mLruProcessServiceStart;
2536            inActivity = true;
2537        } else if (hasService) {
2538            // Process has services, put it at the top of the service list.
2539            addIndex = mLruProcessActivityStart;
2540            nextIndex = mLruProcessServiceStart;
2541            inActivity = true;
2542            inService = true;
2543        } else  {
2544            // Process not otherwise of interest, it goes to the top of the non-service area.
2545            addIndex = mLruProcessServiceStart;
2546            if (client != null) {
2547                int clientIndex = mLruProcesses.lastIndexOf(client);
2548                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2549                        + app);
2550                if (clientIndex >= 0 && addIndex > clientIndex) {
2551                    addIndex = clientIndex;
2552                }
2553            }
2554            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2555        }
2556
2557        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2558                + mLruProcessActivityStart + "): " + app);
2559        */
2560
2561        if (lrui >= 0) {
2562            if (lrui < mLruProcessActivityStart) {
2563                mLruProcessActivityStart--;
2564            }
2565            if (lrui < mLruProcessServiceStart) {
2566                mLruProcessServiceStart--;
2567            }
2568            /*
2569            if (addIndex > lrui) {
2570                addIndex--;
2571            }
2572            if (nextIndex > lrui) {
2573                nextIndex--;
2574            }
2575            */
2576            mLruProcesses.remove(lrui);
2577        }
2578
2579        /*
2580        mLruProcesses.add(addIndex, app);
2581        if (inActivity) {
2582            mLruProcessActivityStart++;
2583        }
2584        if (inService) {
2585            mLruProcessActivityStart++;
2586        }
2587        */
2588
2589        int nextIndex;
2590        if (hasActivity) {
2591            final int N = mLruProcesses.size();
2592            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2593                // Process doesn't have activities, but has clients with
2594                // activities...  move it up, but one below the top (the top
2595                // should always have a real activity).
2596                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2597                mLruProcesses.add(N-1, app);
2598                // To keep it from spamming the LRU list (by making a bunch of clients),
2599                // we will push down any other entries owned by the app.
2600                final int uid = app.info.uid;
2601                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2602                    ProcessRecord subProc = mLruProcesses.get(i);
2603                    if (subProc.info.uid == uid) {
2604                        // We want to push this one down the list.  If the process after
2605                        // it is for the same uid, however, don't do so, because we don't
2606                        // want them internally to be re-ordered.
2607                        if (mLruProcesses.get(i-1).info.uid != uid) {
2608                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2609                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2610                            ProcessRecord tmp = mLruProcesses.get(i);
2611                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2612                            mLruProcesses.set(i-1, tmp);
2613                            i--;
2614                        }
2615                    } else {
2616                        // A gap, we can stop here.
2617                        break;
2618                    }
2619                }
2620            } else {
2621                // Process has activities, put it at the very tipsy-top.
2622                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2623                mLruProcesses.add(app);
2624            }
2625            nextIndex = mLruProcessServiceStart;
2626        } else if (hasService) {
2627            // Process has services, put it at the top of the service list.
2628            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2629            mLruProcesses.add(mLruProcessActivityStart, app);
2630            nextIndex = mLruProcessServiceStart;
2631            mLruProcessActivityStart++;
2632        } else  {
2633            // Process not otherwise of interest, it goes to the top of the non-service area.
2634            int index = mLruProcessServiceStart;
2635            if (client != null) {
2636                // If there is a client, don't allow the process to be moved up higher
2637                // in the list than that client.
2638                int clientIndex = mLruProcesses.lastIndexOf(client);
2639                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2640                        + " when updating " + app);
2641                if (clientIndex <= lrui) {
2642                    // Don't allow the client index restriction to push it down farther in the
2643                    // list than it already is.
2644                    clientIndex = lrui;
2645                }
2646                if (clientIndex >= 0 && index > clientIndex) {
2647                    index = clientIndex;
2648                }
2649            }
2650            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2651            mLruProcesses.add(index, app);
2652            nextIndex = index-1;
2653            mLruProcessActivityStart++;
2654            mLruProcessServiceStart++;
2655        }
2656
2657        // If the app is currently using a content provider or service,
2658        // bump those processes as well.
2659        for (int j=app.connections.size()-1; j>=0; j--) {
2660            ConnectionRecord cr = app.connections.valueAt(j);
2661            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2662                    && cr.binding.service.app != null
2663                    && cr.binding.service.app.lruSeq != mLruSeq
2664                    && !cr.binding.service.app.persistent) {
2665                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2666                        "service connection", cr, app);
2667            }
2668        }
2669        for (int j=app.conProviders.size()-1; j>=0; j--) {
2670            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2671            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2672                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2673                        "provider reference", cpr, app);
2674            }
2675        }
2676    }
2677
2678    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2679        if (uid == Process.SYSTEM_UID) {
2680            // The system gets to run in any process.  If there are multiple
2681            // processes with the same uid, just pick the first (this
2682            // should never happen).
2683            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2684            if (procs == null) return null;
2685            final int N = procs.size();
2686            for (int i = 0; i < N; i++) {
2687                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2688            }
2689        }
2690        ProcessRecord proc = mProcessNames.get(processName, uid);
2691        if (false && proc != null && !keepIfLarge
2692                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2693                && proc.lastCachedPss >= 4000) {
2694            // Turn this condition on to cause killing to happen regularly, for testing.
2695            if (proc.baseProcessTracker != null) {
2696                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2697            }
2698            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2699                    + "k from cached");
2700        } else if (proc != null && !keepIfLarge
2701                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2702                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2703            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2704            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2705                if (proc.baseProcessTracker != null) {
2706                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2707                }
2708                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2709                        + "k from cached");
2710            }
2711        }
2712        return proc;
2713    }
2714
2715    void ensurePackageDexOpt(String packageName) {
2716        IPackageManager pm = AppGlobals.getPackageManager();
2717        try {
2718            if (pm.performDexOpt(packageName)) {
2719                mDidDexOpt = true;
2720            }
2721        } catch (RemoteException e) {
2722        }
2723    }
2724
2725    boolean isNextTransitionForward() {
2726        int transit = mWindowManager.getPendingAppTransition();
2727        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2728                || transit == AppTransition.TRANSIT_TASK_OPEN
2729                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2730    }
2731
2732    final ProcessRecord startProcessLocked(String processName,
2733            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2734            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2735            boolean isolated, boolean keepIfLarge) {
2736        ProcessRecord app;
2737        if (!isolated) {
2738            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2739        } else {
2740            // If this is an isolated process, it can't re-use an existing process.
2741            app = null;
2742        }
2743        // We don't have to do anything more if:
2744        // (1) There is an existing application record; and
2745        // (2) The caller doesn't think it is dead, OR there is no thread
2746        //     object attached to it so we know it couldn't have crashed; and
2747        // (3) There is a pid assigned to it, so it is either starting or
2748        //     already running.
2749        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2750                + " app=" + app + " knownToBeDead=" + knownToBeDead
2751                + " thread=" + (app != null ? app.thread : null)
2752                + " pid=" + (app != null ? app.pid : -1));
2753        if (app != null && app.pid > 0) {
2754            if (!knownToBeDead || app.thread == null) {
2755                // We already have the app running, or are waiting for it to
2756                // come up (we have a pid but not yet its thread), so keep it.
2757                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2758                // If this is a new package in the process, add the package to the list
2759                app.addPackage(info.packageName, mProcessStats);
2760                return app;
2761            }
2762
2763            // An application record is attached to a previous process,
2764            // clean it up now.
2765            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2766            handleAppDiedLocked(app, true, true);
2767        }
2768
2769        String hostingNameStr = hostingName != null
2770                ? hostingName.flattenToShortString() : null;
2771
2772        if (!isolated) {
2773            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2774                // If we are in the background, then check to see if this process
2775                // is bad.  If so, we will just silently fail.
2776                if (mBadProcesses.get(info.processName, info.uid) != null) {
2777                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2778                            + "/" + info.processName);
2779                    return null;
2780                }
2781            } else {
2782                // When the user is explicitly starting a process, then clear its
2783                // crash count so that we won't make it bad until they see at
2784                // least one crash dialog again, and make the process good again
2785                // if it had been bad.
2786                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2787                        + "/" + info.processName);
2788                mProcessCrashTimes.remove(info.processName, info.uid);
2789                if (mBadProcesses.get(info.processName, info.uid) != null) {
2790                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2791                            UserHandle.getUserId(info.uid), info.uid,
2792                            info.processName);
2793                    mBadProcesses.remove(info.processName, info.uid);
2794                    if (app != null) {
2795                        app.bad = false;
2796                    }
2797                }
2798            }
2799        }
2800
2801        if (app == null) {
2802            app = newProcessRecordLocked(info, processName, isolated);
2803            if (app == null) {
2804                Slog.w(TAG, "Failed making new process record for "
2805                        + processName + "/" + info.uid + " isolated=" + isolated);
2806                return null;
2807            }
2808            mProcessNames.put(processName, app.uid, app);
2809            if (isolated) {
2810                mIsolatedProcesses.put(app.uid, app);
2811            }
2812        } else {
2813            // If this is a new package in the process, add the package to the list
2814            app.addPackage(info.packageName, mProcessStats);
2815        }
2816
2817        // If the system is not ready yet, then hold off on starting this
2818        // process until it is.
2819        if (!mProcessesReady
2820                && !isAllowedWhileBooting(info)
2821                && !allowWhileBooting) {
2822            if (!mProcessesOnHold.contains(app)) {
2823                mProcessesOnHold.add(app);
2824            }
2825            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2826            return app;
2827        }
2828
2829        startProcessLocked(app, hostingType, hostingNameStr);
2830        return (app.pid != 0) ? app : null;
2831    }
2832
2833    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2834        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2835    }
2836
2837    private final void startProcessLocked(ProcessRecord app,
2838            String hostingType, String hostingNameStr) {
2839        if (app.pid > 0 && app.pid != MY_PID) {
2840            synchronized (mPidsSelfLocked) {
2841                mPidsSelfLocked.remove(app.pid);
2842                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2843            }
2844            app.setPid(0);
2845        }
2846
2847        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2848                "startProcessLocked removing on hold: " + app);
2849        mProcessesOnHold.remove(app);
2850
2851        updateCpuStats();
2852
2853        try {
2854            int uid = app.uid;
2855
2856            int[] gids = null;
2857            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2858            if (!app.isolated) {
2859                int[] permGids = null;
2860                try {
2861                    final PackageManager pm = mContext.getPackageManager();
2862                    permGids = pm.getPackageGids(app.info.packageName);
2863
2864                    if (Environment.isExternalStorageEmulated()) {
2865                        if (pm.checkPermission(
2866                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2867                                app.info.packageName) == PERMISSION_GRANTED) {
2868                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2869                        } else {
2870                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2871                        }
2872                    }
2873                } catch (PackageManager.NameNotFoundException e) {
2874                    Slog.w(TAG, "Unable to retrieve gids", e);
2875                }
2876
2877                /*
2878                 * Add shared application GID so applications can share some
2879                 * resources like shared libraries
2880                 */
2881                if (permGids == null) {
2882                    gids = new int[1];
2883                } else {
2884                    gids = new int[permGids.length + 1];
2885                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2886                }
2887                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2888            }
2889            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2890                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2891                        && mTopComponent != null
2892                        && app.processName.equals(mTopComponent.getPackageName())) {
2893                    uid = 0;
2894                }
2895                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2896                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2897                    uid = 0;
2898                }
2899            }
2900            int debugFlags = 0;
2901            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2902                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2903                // Also turn on CheckJNI for debuggable apps. It's quite
2904                // awkward to turn on otherwise.
2905                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2906            }
2907            // Run the app in safe mode if its manifest requests so or the
2908            // system is booted in safe mode.
2909            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2910                mSafeMode == true) {
2911                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2912            }
2913            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2914                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2915            }
2916            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2917                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2918            }
2919            if ("1".equals(SystemProperties.get("debug.assert"))) {
2920                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2921            }
2922
2923            String requiredAbi = app.info.cpuAbi;
2924            if (requiredAbi == null) {
2925                requiredAbi = Build.SUPPORTED_ABIS[0];
2926            }
2927
2928            // Start the process.  It will either succeed and return a result containing
2929            // the PID of the new process, or else throw a RuntimeException.
2930            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2931                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2932                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
2933
2934            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2935            synchronized (bs) {
2936                if (bs.isOnBattery()) {
2937                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2938                }
2939            }
2940
2941            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2942                    UserHandle.getUserId(uid), startResult.pid, uid,
2943                    app.processName, hostingType,
2944                    hostingNameStr != null ? hostingNameStr : "");
2945
2946            if (app.persistent) {
2947                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2948            }
2949
2950            StringBuilder buf = mStringBuilder;
2951            buf.setLength(0);
2952            buf.append("Start proc ");
2953            buf.append(app.processName);
2954            buf.append(" for ");
2955            buf.append(hostingType);
2956            if (hostingNameStr != null) {
2957                buf.append(" ");
2958                buf.append(hostingNameStr);
2959            }
2960            buf.append(": pid=");
2961            buf.append(startResult.pid);
2962            buf.append(" uid=");
2963            buf.append(uid);
2964            buf.append(" gids={");
2965            if (gids != null) {
2966                for (int gi=0; gi<gids.length; gi++) {
2967                    if (gi != 0) buf.append(", ");
2968                    buf.append(gids[gi]);
2969
2970                }
2971            }
2972            buf.append("}");
2973            Slog.i(TAG, buf.toString());
2974            app.setPid(startResult.pid);
2975            app.usingWrapper = startResult.usingWrapper;
2976            app.removed = false;
2977            synchronized (mPidsSelfLocked) {
2978                this.mPidsSelfLocked.put(startResult.pid, app);
2979                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2980                msg.obj = app;
2981                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2982                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2983            }
2984            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
2985                    app.processName, app.info.uid);
2986            if (app.isolated) {
2987                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2988            }
2989        } catch (RuntimeException e) {
2990            // XXX do better error recovery.
2991            app.setPid(0);
2992            Slog.e(TAG, "Failure starting process " + app.processName, e);
2993        }
2994    }
2995
2996    void updateUsageStats(ActivityRecord component, boolean resumed) {
2997        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
2998        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2999        if (resumed) {
3000            mUsageStatsService.noteResumeComponent(component.realActivity);
3001            synchronized (stats) {
3002                stats.noteActivityResumedLocked(component.app.uid);
3003            }
3004        } else {
3005            mUsageStatsService.notePauseComponent(component.realActivity);
3006            synchronized (stats) {
3007                stats.noteActivityPausedLocked(component.app.uid);
3008            }
3009        }
3010    }
3011
3012    Intent getHomeIntent() {
3013        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3014        intent.setComponent(mTopComponent);
3015        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3016            intent.addCategory(Intent.CATEGORY_HOME);
3017        }
3018        return intent;
3019    }
3020
3021    boolean startHomeActivityLocked(int userId) {
3022        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3023                && mTopAction == null) {
3024            // We are running in factory test mode, but unable to find
3025            // the factory test app, so just sit around displaying the
3026            // error message and don't try to start anything.
3027            return false;
3028        }
3029        Intent intent = getHomeIntent();
3030        ActivityInfo aInfo =
3031            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3032        if (aInfo != null) {
3033            intent.setComponent(new ComponentName(
3034                    aInfo.applicationInfo.packageName, aInfo.name));
3035            // Don't do this if the home app is currently being
3036            // instrumented.
3037            aInfo = new ActivityInfo(aInfo);
3038            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3039            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3040                    aInfo.applicationInfo.uid, true);
3041            if (app == null || app.instrumentationClass == null) {
3042                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3043                mStackSupervisor.startHomeActivity(intent, aInfo);
3044            }
3045        }
3046
3047        return true;
3048    }
3049
3050    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3051        ActivityInfo ai = null;
3052        ComponentName comp = intent.getComponent();
3053        try {
3054            if (comp != null) {
3055                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3056            } else {
3057                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3058                        intent,
3059                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3060                            flags, userId);
3061
3062                if (info != null) {
3063                    ai = info.activityInfo;
3064                }
3065            }
3066        } catch (RemoteException e) {
3067            // ignore
3068        }
3069
3070        return ai;
3071    }
3072
3073    /**
3074     * Starts the "new version setup screen" if appropriate.
3075     */
3076    void startSetupActivityLocked() {
3077        // Only do this once per boot.
3078        if (mCheckedForSetup) {
3079            return;
3080        }
3081
3082        // We will show this screen if the current one is a different
3083        // version than the last one shown, and we are not running in
3084        // low-level factory test mode.
3085        final ContentResolver resolver = mContext.getContentResolver();
3086        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3087                Settings.Global.getInt(resolver,
3088                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3089            mCheckedForSetup = true;
3090
3091            // See if we should be showing the platform update setup UI.
3092            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3093            List<ResolveInfo> ris = mContext.getPackageManager()
3094                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3095
3096            // We don't allow third party apps to replace this.
3097            ResolveInfo ri = null;
3098            for (int i=0; ris != null && i<ris.size(); i++) {
3099                if ((ris.get(i).activityInfo.applicationInfo.flags
3100                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3101                    ri = ris.get(i);
3102                    break;
3103                }
3104            }
3105
3106            if (ri != null) {
3107                String vers = ri.activityInfo.metaData != null
3108                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3109                        : null;
3110                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3111                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3112                            Intent.METADATA_SETUP_VERSION);
3113                }
3114                String lastVers = Settings.Secure.getString(
3115                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3116                if (vers != null && !vers.equals(lastVers)) {
3117                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3118                    intent.setComponent(new ComponentName(
3119                            ri.activityInfo.packageName, ri.activityInfo.name));
3120                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3121                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3122                }
3123            }
3124        }
3125    }
3126
3127    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3128        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3129    }
3130
3131    void enforceNotIsolatedCaller(String caller) {
3132        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3133            throw new SecurityException("Isolated process not allowed to call " + caller);
3134        }
3135    }
3136
3137    @Override
3138    public int getFrontActivityScreenCompatMode() {
3139        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3140        synchronized (this) {
3141            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3142        }
3143    }
3144
3145    @Override
3146    public void setFrontActivityScreenCompatMode(int mode) {
3147        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3148                "setFrontActivityScreenCompatMode");
3149        synchronized (this) {
3150            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3151        }
3152    }
3153
3154    @Override
3155    public int getPackageScreenCompatMode(String packageName) {
3156        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3157        synchronized (this) {
3158            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3159        }
3160    }
3161
3162    @Override
3163    public void setPackageScreenCompatMode(String packageName, int mode) {
3164        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3165                "setPackageScreenCompatMode");
3166        synchronized (this) {
3167            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3168        }
3169    }
3170
3171    @Override
3172    public boolean getPackageAskScreenCompat(String packageName) {
3173        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3174        synchronized (this) {
3175            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3176        }
3177    }
3178
3179    @Override
3180    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3181        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3182                "setPackageAskScreenCompat");
3183        synchronized (this) {
3184            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3185        }
3186    }
3187
3188    private void dispatchProcessesChanged() {
3189        int N;
3190        synchronized (this) {
3191            N = mPendingProcessChanges.size();
3192            if (mActiveProcessChanges.length < N) {
3193                mActiveProcessChanges = new ProcessChangeItem[N];
3194            }
3195            mPendingProcessChanges.toArray(mActiveProcessChanges);
3196            mAvailProcessChanges.addAll(mPendingProcessChanges);
3197            mPendingProcessChanges.clear();
3198            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3199        }
3200
3201        int i = mProcessObservers.beginBroadcast();
3202        while (i > 0) {
3203            i--;
3204            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3205            if (observer != null) {
3206                try {
3207                    for (int j=0; j<N; j++) {
3208                        ProcessChangeItem item = mActiveProcessChanges[j];
3209                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3210                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3211                                    + item.pid + " uid=" + item.uid + ": "
3212                                    + item.foregroundActivities);
3213                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3214                                    item.foregroundActivities);
3215                        }
3216                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3217                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3218                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3219                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3220                        }
3221                    }
3222                } catch (RemoteException e) {
3223                }
3224            }
3225        }
3226        mProcessObservers.finishBroadcast();
3227    }
3228
3229    private void dispatchProcessDied(int pid, int uid) {
3230        int i = mProcessObservers.beginBroadcast();
3231        while (i > 0) {
3232            i--;
3233            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3234            if (observer != null) {
3235                try {
3236                    observer.onProcessDied(pid, uid);
3237                } catch (RemoteException e) {
3238                }
3239            }
3240        }
3241        mProcessObservers.finishBroadcast();
3242    }
3243
3244    final void doPendingActivityLaunchesLocked(boolean doResume) {
3245        final int N = mPendingActivityLaunches.size();
3246        if (N <= 0) {
3247            return;
3248        }
3249        for (int i=0; i<N; i++) {
3250            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3251            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
3252                    doResume && i == (N-1), null);
3253        }
3254        mPendingActivityLaunches.clear();
3255    }
3256
3257    @Override
3258    public final int startActivity(IApplicationThread caller, String callingPackage,
3259            Intent intent, String resolvedType, IBinder resultTo,
3260            String resultWho, int requestCode, int startFlags,
3261            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3262        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3263                resultWho, requestCode,
3264                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3265    }
3266
3267    @Override
3268    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3269            Intent intent, String resolvedType, IBinder resultTo,
3270            String resultWho, int requestCode, int startFlags,
3271            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3272        enforceNotIsolatedCaller("startActivity");
3273        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3274                false, true, "startActivity", null);
3275        // TODO: Switch to user app stacks here.
3276        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3277                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3278                null, null, options, userId, null);
3279    }
3280
3281    @Override
3282    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3283            Intent intent, String resolvedType, IBinder resultTo,
3284            String resultWho, int requestCode, int startFlags, String profileFile,
3285            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3286        enforceNotIsolatedCaller("startActivityAndWait");
3287        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3288                false, true, "startActivityAndWait", null);
3289        WaitResult res = new WaitResult();
3290        // TODO: Switch to user app stacks here.
3291        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3292                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3293                res, null, options, UserHandle.getCallingUserId(), null);
3294        return res;
3295    }
3296
3297    @Override
3298    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3299            Intent intent, String resolvedType, IBinder resultTo,
3300            String resultWho, int requestCode, int startFlags, Configuration config,
3301            Bundle options, int userId) {
3302        enforceNotIsolatedCaller("startActivityWithConfig");
3303        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3304                false, true, "startActivityWithConfig", null);
3305        // TODO: Switch to user app stacks here.
3306        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3307                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3308                null, null, null, config, options, userId, null);
3309        return ret;
3310    }
3311
3312    @Override
3313    public int startActivityIntentSender(IApplicationThread caller,
3314            IntentSender intent, Intent fillInIntent, String resolvedType,
3315            IBinder resultTo, String resultWho, int requestCode,
3316            int flagsMask, int flagsValues, Bundle options) {
3317        enforceNotIsolatedCaller("startActivityIntentSender");
3318        // Refuse possible leaked file descriptors
3319        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3320            throw new IllegalArgumentException("File descriptors passed in Intent");
3321        }
3322
3323        IIntentSender sender = intent.getTarget();
3324        if (!(sender instanceof PendingIntentRecord)) {
3325            throw new IllegalArgumentException("Bad PendingIntent object");
3326        }
3327
3328        PendingIntentRecord pir = (PendingIntentRecord)sender;
3329
3330        synchronized (this) {
3331            // If this is coming from the currently resumed activity, it is
3332            // effectively saying that app switches are allowed at this point.
3333            final ActivityStack stack = getFocusedStack();
3334            if (stack.mResumedActivity != null &&
3335                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3336                mAppSwitchesAllowedTime = 0;
3337            }
3338        }
3339        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3340                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3341        return ret;
3342    }
3343
3344    @Override
3345    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3346            Intent intent, String resolvedType, IVoiceInteractionSession session,
3347            IVoiceInteractor interactor, int startFlags, String profileFile,
3348            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3349        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3350                != PackageManager.PERMISSION_GRANTED) {
3351            String msg = "Permission Denial: startVoiceActivity() from pid="
3352                    + Binder.getCallingPid()
3353                    + ", uid=" + Binder.getCallingUid()
3354                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3355            Slog.w(TAG, msg);
3356            throw new SecurityException(msg);
3357        }
3358        if (session == null || interactor == null) {
3359            throw new NullPointerException("null session or interactor");
3360        }
3361        userId = handleIncomingUser(callingPid, callingUid, userId,
3362                false, true, "startVoiceActivity", null);
3363        // TODO: Switch to user app stacks here.
3364        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3365                resolvedType, session, interactor, null, null, 0, startFlags,
3366                profileFile, profileFd, null, null, options, userId, null);
3367    }
3368
3369    @Override
3370    public boolean startNextMatchingActivity(IBinder callingActivity,
3371            Intent intent, Bundle options) {
3372        // Refuse possible leaked file descriptors
3373        if (intent != null && intent.hasFileDescriptors() == true) {
3374            throw new IllegalArgumentException("File descriptors passed in Intent");
3375        }
3376
3377        synchronized (this) {
3378            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3379            if (r == null) {
3380                ActivityOptions.abort(options);
3381                return false;
3382            }
3383            if (r.app == null || r.app.thread == null) {
3384                // The caller is not running...  d'oh!
3385                ActivityOptions.abort(options);
3386                return false;
3387            }
3388            intent = new Intent(intent);
3389            // The caller is not allowed to change the data.
3390            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3391            // And we are resetting to find the next component...
3392            intent.setComponent(null);
3393
3394            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3395
3396            ActivityInfo aInfo = null;
3397            try {
3398                List<ResolveInfo> resolves =
3399                    AppGlobals.getPackageManager().queryIntentActivities(
3400                            intent, r.resolvedType,
3401                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3402                            UserHandle.getCallingUserId());
3403
3404                // Look for the original activity in the list...
3405                final int N = resolves != null ? resolves.size() : 0;
3406                for (int i=0; i<N; i++) {
3407                    ResolveInfo rInfo = resolves.get(i);
3408                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3409                            && rInfo.activityInfo.name.equals(r.info.name)) {
3410                        // We found the current one...  the next matching is
3411                        // after it.
3412                        i++;
3413                        if (i<N) {
3414                            aInfo = resolves.get(i).activityInfo;
3415                        }
3416                        if (debug) {
3417                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3418                                    + "/" + r.info.name);
3419                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3420                                    + "/" + aInfo.name);
3421                        }
3422                        break;
3423                    }
3424                }
3425            } catch (RemoteException e) {
3426            }
3427
3428            if (aInfo == null) {
3429                // Nobody who is next!
3430                ActivityOptions.abort(options);
3431                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3432                return false;
3433            }
3434
3435            intent.setComponent(new ComponentName(
3436                    aInfo.applicationInfo.packageName, aInfo.name));
3437            intent.setFlags(intent.getFlags()&~(
3438                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3439                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3440                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3441                    Intent.FLAG_ACTIVITY_NEW_TASK));
3442
3443            // Okay now we need to start the new activity, replacing the
3444            // currently running activity.  This is a little tricky because
3445            // we want to start the new one as if the current one is finished,
3446            // but not finish the current one first so that there is no flicker.
3447            // And thus...
3448            final boolean wasFinishing = r.finishing;
3449            r.finishing = true;
3450
3451            // Propagate reply information over to the new activity.
3452            final ActivityRecord resultTo = r.resultTo;
3453            final String resultWho = r.resultWho;
3454            final int requestCode = r.requestCode;
3455            r.resultTo = null;
3456            if (resultTo != null) {
3457                resultTo.removeResultsLocked(r, resultWho, requestCode);
3458            }
3459
3460            final long origId = Binder.clearCallingIdentity();
3461            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3462                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3463                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3464                    options, false, null, null);
3465            Binder.restoreCallingIdentity(origId);
3466
3467            r.finishing = wasFinishing;
3468            if (res != ActivityManager.START_SUCCESS) {
3469                return false;
3470            }
3471            return true;
3472        }
3473    }
3474
3475    final int startActivityInPackage(int uid, String callingPackage,
3476            Intent intent, String resolvedType, IBinder resultTo,
3477            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3478                    IActivityContainer container) {
3479
3480        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3481                false, true, "startActivityInPackage", null);
3482
3483        // TODO: Switch to user app stacks here.
3484        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3485                null, null, resultTo, resultWho, requestCode, startFlags,
3486                null, null, null, null, options, userId, container);
3487        return ret;
3488    }
3489
3490    @Override
3491    public final int startActivities(IApplicationThread caller, String callingPackage,
3492            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3493            int userId) {
3494        enforceNotIsolatedCaller("startActivities");
3495        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3496                false, true, "startActivity", null);
3497        // TODO: Switch to user app stacks here.
3498        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3499                resolvedTypes, resultTo, options, userId);
3500        return ret;
3501    }
3502
3503    final int startActivitiesInPackage(int uid, String callingPackage,
3504            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3505            Bundle options, int userId) {
3506
3507        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3508                false, true, "startActivityInPackage", null);
3509        // TODO: Switch to user app stacks here.
3510        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3511                resultTo, options, userId);
3512        return ret;
3513    }
3514
3515    final void addRecentTaskLocked(TaskRecord task) {
3516        int N = mRecentTasks.size();
3517        // Quick case: check if the top-most recent task is the same.
3518        if (N > 0 && mRecentTasks.get(0) == task) {
3519            return;
3520        }
3521        // Another quick case: never add voice sessions.
3522        if (task.voiceSession != null) {
3523            return;
3524        }
3525        // Remove any existing entries that are the same kind of task.
3526        final Intent intent = task.intent;
3527        final boolean document = intent != null && intent.isDocument();
3528        for (int i=0; i<N; i++) {
3529            TaskRecord tr = mRecentTasks.get(i);
3530            if (task != tr) {
3531                if (task.userId != tr.userId) {
3532                    continue;
3533                }
3534                final Intent trIntent = tr.intent;
3535                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3536                    (intent == null || !intent.filterEquals(trIntent))) {
3537                    continue;
3538                }
3539                if (document || trIntent != null && trIntent.isDocument()) {
3540                    // Document tasks do not match other tasks.
3541                    continue;
3542                }
3543            }
3544
3545            // Either task and tr are the same or, their affinities match or their intents match
3546            // and neither of them is a document.
3547            tr.disposeThumbnail();
3548            mRecentTasks.remove(i);
3549            i--;
3550            N--;
3551            if (task.intent == null) {
3552                // If the new recent task we are adding is not fully
3553                // specified, then replace it with the existing recent task.
3554                task = tr;
3555            }
3556        }
3557        if (N >= MAX_RECENT_TASKS) {
3558            mRecentTasks.remove(N-1).disposeThumbnail();
3559        }
3560        mRecentTasks.add(0, task);
3561    }
3562
3563    @Override
3564    public void reportActivityFullyDrawn(IBinder token) {
3565        synchronized (this) {
3566            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3567            if (r == null) {
3568                return;
3569            }
3570            r.reportFullyDrawnLocked();
3571        }
3572    }
3573
3574    @Override
3575    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3576        synchronized (this) {
3577            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3578            if (r == null) {
3579                return;
3580            }
3581            final long origId = Binder.clearCallingIdentity();
3582            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3583            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3584                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3585            if (config != null) {
3586                r.frozenBeforeDestroy = true;
3587                if (!updateConfigurationLocked(config, r, false, false)) {
3588                    mStackSupervisor.resumeTopActivitiesLocked();
3589                }
3590            }
3591            Binder.restoreCallingIdentity(origId);
3592        }
3593    }
3594
3595    @Override
3596    public int getRequestedOrientation(IBinder token) {
3597        synchronized (this) {
3598            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3599            if (r == null) {
3600                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3601            }
3602            return mWindowManager.getAppOrientation(r.appToken);
3603        }
3604    }
3605
3606    /**
3607     * This is the internal entry point for handling Activity.finish().
3608     *
3609     * @param token The Binder token referencing the Activity we want to finish.
3610     * @param resultCode Result code, if any, from this Activity.
3611     * @param resultData Result data (Intent), if any, from this Activity.
3612     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3613     *            the root Activity in the task.
3614     *
3615     * @return Returns true if the activity successfully finished, or false if it is still running.
3616     */
3617    @Override
3618    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3619            boolean finishTask) {
3620        // Refuse possible leaked file descriptors
3621        if (resultData != null && resultData.hasFileDescriptors() == true) {
3622            throw new IllegalArgumentException("File descriptors passed in Intent");
3623        }
3624
3625        synchronized(this) {
3626            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3627            if (r == null) {
3628                return true;
3629            }
3630            // Keep track of the root activity of the task before we finish it
3631            TaskRecord tr = r.task;
3632            ActivityRecord rootR = tr.getRootActivity();
3633            if (mController != null) {
3634                // Find the first activity that is not finishing.
3635                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3636                if (next != null) {
3637                    // ask watcher if this is allowed
3638                    boolean resumeOK = true;
3639                    try {
3640                        resumeOK = mController.activityResuming(next.packageName);
3641                    } catch (RemoteException e) {
3642                        mController = null;
3643                        Watchdog.getInstance().setActivityController(null);
3644                    }
3645
3646                    if (!resumeOK) {
3647                        return false;
3648                    }
3649                }
3650            }
3651            final long origId = Binder.clearCallingIdentity();
3652            try {
3653                boolean res;
3654                if (finishTask && r == rootR) {
3655                    // If requested, remove the task that is associated to this activity only if it
3656                    // was the root activity in the task.  The result code and data is ignored because
3657                    // we don't support returning them across task boundaries.
3658                    res = removeTaskByIdLocked(tr.taskId, 0);
3659                } else {
3660                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3661                            resultData, "app-request", true);
3662                }
3663                return res;
3664            } finally {
3665                Binder.restoreCallingIdentity(origId);
3666            }
3667        }
3668    }
3669
3670    @Override
3671    public final void finishHeavyWeightApp() {
3672        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3673                != PackageManager.PERMISSION_GRANTED) {
3674            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3675                    + Binder.getCallingPid()
3676                    + ", uid=" + Binder.getCallingUid()
3677                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3678            Slog.w(TAG, msg);
3679            throw new SecurityException(msg);
3680        }
3681
3682        synchronized(this) {
3683            if (mHeavyWeightProcess == null) {
3684                return;
3685            }
3686
3687            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3688                    mHeavyWeightProcess.activities);
3689            for (int i=0; i<activities.size(); i++) {
3690                ActivityRecord r = activities.get(i);
3691                if (!r.finishing) {
3692                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3693                            null, "finish-heavy", true);
3694                }
3695            }
3696
3697            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3698                    mHeavyWeightProcess.userId, 0));
3699            mHeavyWeightProcess = null;
3700        }
3701    }
3702
3703    @Override
3704    public void crashApplication(int uid, int initialPid, String packageName,
3705            String message) {
3706        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3707                != PackageManager.PERMISSION_GRANTED) {
3708            String msg = "Permission Denial: crashApplication() from pid="
3709                    + Binder.getCallingPid()
3710                    + ", uid=" + Binder.getCallingUid()
3711                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3712            Slog.w(TAG, msg);
3713            throw new SecurityException(msg);
3714        }
3715
3716        synchronized(this) {
3717            ProcessRecord proc = null;
3718
3719            // Figure out which process to kill.  We don't trust that initialPid
3720            // still has any relation to current pids, so must scan through the
3721            // list.
3722            synchronized (mPidsSelfLocked) {
3723                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3724                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3725                    if (p.uid != uid) {
3726                        continue;
3727                    }
3728                    if (p.pid == initialPid) {
3729                        proc = p;
3730                        break;
3731                    }
3732                    if (p.pkgList.containsKey(packageName)) {
3733                        proc = p;
3734                    }
3735                }
3736            }
3737
3738            if (proc == null) {
3739                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3740                        + " initialPid=" + initialPid
3741                        + " packageName=" + packageName);
3742                return;
3743            }
3744
3745            if (proc.thread != null) {
3746                if (proc.pid == Process.myPid()) {
3747                    Log.w(TAG, "crashApplication: trying to crash self!");
3748                    return;
3749                }
3750                long ident = Binder.clearCallingIdentity();
3751                try {
3752                    proc.thread.scheduleCrash(message);
3753                } catch (RemoteException e) {
3754                }
3755                Binder.restoreCallingIdentity(ident);
3756            }
3757        }
3758    }
3759
3760    @Override
3761    public final void finishSubActivity(IBinder token, String resultWho,
3762            int requestCode) {
3763        synchronized(this) {
3764            final long origId = Binder.clearCallingIdentity();
3765            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3766            if (r != null) {
3767                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3768            }
3769            Binder.restoreCallingIdentity(origId);
3770        }
3771    }
3772
3773    @Override
3774    public boolean finishActivityAffinity(IBinder token) {
3775        synchronized(this) {
3776            final long origId = Binder.clearCallingIdentity();
3777            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3778            boolean res = false;
3779            if (r != null) {
3780                res = r.task.stack.finishActivityAffinityLocked(r);
3781            }
3782            Binder.restoreCallingIdentity(origId);
3783            return res;
3784        }
3785    }
3786
3787    @Override
3788    public boolean willActivityBeVisible(IBinder token) {
3789        synchronized(this) {
3790            ActivityStack stack = ActivityRecord.getStackLocked(token);
3791            if (stack != null) {
3792                return stack.willActivityBeVisibleLocked(token);
3793            }
3794            return false;
3795        }
3796    }
3797
3798    @Override
3799    public void overridePendingTransition(IBinder token, String packageName,
3800            int enterAnim, int exitAnim) {
3801        synchronized(this) {
3802            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3803            if (self == null) {
3804                return;
3805            }
3806
3807            final long origId = Binder.clearCallingIdentity();
3808
3809            if (self.state == ActivityState.RESUMED
3810                    || self.state == ActivityState.PAUSING) {
3811                mWindowManager.overridePendingAppTransition(packageName,
3812                        enterAnim, exitAnim, null);
3813            }
3814
3815            Binder.restoreCallingIdentity(origId);
3816        }
3817    }
3818
3819    /**
3820     * Main function for removing an existing process from the activity manager
3821     * as a result of that process going away.  Clears out all connections
3822     * to the process.
3823     */
3824    private final void handleAppDiedLocked(ProcessRecord app,
3825            boolean restarting, boolean allowRestart) {
3826        int pid = app.pid;
3827        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3828        if (!restarting) {
3829            removeLruProcessLocked(app);
3830            if (pid > 0) {
3831                ProcessList.remove(pid);
3832            }
3833        }
3834
3835        if (mProfileProc == app) {
3836            clearProfilerLocked();
3837        }
3838
3839        // Remove this application's activities from active lists.
3840        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3841
3842        app.activities.clear();
3843
3844        if (app.instrumentationClass != null) {
3845            Slog.w(TAG, "Crash of app " + app.processName
3846                  + " running instrumentation " + app.instrumentationClass);
3847            Bundle info = new Bundle();
3848            info.putString("shortMsg", "Process crashed.");
3849            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3850        }
3851
3852        if (!restarting) {
3853            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3854                // If there was nothing to resume, and we are not already
3855                // restarting this process, but there is a visible activity that
3856                // is hosted by the process...  then make sure all visible
3857                // activities are running, taking care of restarting this
3858                // process.
3859                if (hasVisibleActivities) {
3860                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3861                }
3862            }
3863        }
3864    }
3865
3866    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3867        IBinder threadBinder = thread.asBinder();
3868        // Find the application record.
3869        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3870            ProcessRecord rec = mLruProcesses.get(i);
3871            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3872                return i;
3873            }
3874        }
3875        return -1;
3876    }
3877
3878    final ProcessRecord getRecordForAppLocked(
3879            IApplicationThread thread) {
3880        if (thread == null) {
3881            return null;
3882        }
3883
3884        int appIndex = getLRURecordIndexForAppLocked(thread);
3885        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3886    }
3887
3888    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3889        // If there are no longer any background processes running,
3890        // and the app that died was not running instrumentation,
3891        // then tell everyone we are now low on memory.
3892        boolean haveBg = false;
3893        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3894            ProcessRecord rec = mLruProcesses.get(i);
3895            if (rec.thread != null
3896                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3897                haveBg = true;
3898                break;
3899            }
3900        }
3901
3902        if (!haveBg) {
3903            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3904            if (doReport) {
3905                long now = SystemClock.uptimeMillis();
3906                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3907                    doReport = false;
3908                } else {
3909                    mLastMemUsageReportTime = now;
3910                }
3911            }
3912            final ArrayList<ProcessMemInfo> memInfos
3913                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3914            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3915            long now = SystemClock.uptimeMillis();
3916            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3917                ProcessRecord rec = mLruProcesses.get(i);
3918                if (rec == dyingProc || rec.thread == null) {
3919                    continue;
3920                }
3921                if (doReport) {
3922                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3923                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3924                }
3925                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3926                    // The low memory report is overriding any current
3927                    // state for a GC request.  Make sure to do
3928                    // heavy/important/visible/foreground processes first.
3929                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3930                        rec.lastRequestedGc = 0;
3931                    } else {
3932                        rec.lastRequestedGc = rec.lastLowMemory;
3933                    }
3934                    rec.reportLowMemory = true;
3935                    rec.lastLowMemory = now;
3936                    mProcessesToGc.remove(rec);
3937                    addProcessToGcListLocked(rec);
3938                }
3939            }
3940            if (doReport) {
3941                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3942                mHandler.sendMessage(msg);
3943            }
3944            scheduleAppGcsLocked();
3945        }
3946    }
3947
3948    final void appDiedLocked(ProcessRecord app, int pid,
3949            IApplicationThread thread) {
3950
3951        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3952        synchronized (stats) {
3953            stats.noteProcessDiedLocked(app.info.uid, pid);
3954        }
3955
3956        // Clean up already done if the process has been re-started.
3957        if (app.pid == pid && app.thread != null &&
3958                app.thread.asBinder() == thread.asBinder()) {
3959            boolean doLowMem = app.instrumentationClass == null;
3960            boolean doOomAdj = doLowMem;
3961            if (!app.killedByAm) {
3962                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3963                        + ") has died.");
3964                mAllowLowerMemLevel = true;
3965            } else {
3966                // Note that we always want to do oom adj to update our state with the
3967                // new number of procs.
3968                mAllowLowerMemLevel = false;
3969                doLowMem = false;
3970            }
3971            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3972            if (DEBUG_CLEANUP) Slog.v(
3973                TAG, "Dying app: " + app + ", pid: " + pid
3974                + ", thread: " + thread.asBinder());
3975            handleAppDiedLocked(app, false, true);
3976
3977            if (doOomAdj) {
3978                updateOomAdjLocked();
3979            }
3980            if (doLowMem) {
3981                doLowMemReportIfNeededLocked(app);
3982            }
3983        } else if (app.pid != pid) {
3984            // A new process has already been started.
3985            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3986                    + ") has died and restarted (pid " + app.pid + ").");
3987            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3988        } else if (DEBUG_PROCESSES) {
3989            Slog.d(TAG, "Received spurious death notification for thread "
3990                    + thread.asBinder());
3991        }
3992    }
3993
3994    /**
3995     * If a stack trace dump file is configured, dump process stack traces.
3996     * @param clearTraces causes the dump file to be erased prior to the new
3997     *    traces being written, if true; when false, the new traces will be
3998     *    appended to any existing file content.
3999     * @param firstPids of dalvik VM processes to dump stack traces for first
4000     * @param lastPids of dalvik VM processes to dump stack traces for last
4001     * @param nativeProcs optional list of native process names to dump stack crawls
4002     * @return file containing stack traces, or null if no dump file is configured
4003     */
4004    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4005            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4006        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4007        if (tracesPath == null || tracesPath.length() == 0) {
4008            return null;
4009        }
4010
4011        File tracesFile = new File(tracesPath);
4012        try {
4013            File tracesDir = tracesFile.getParentFile();
4014            if (!tracesDir.exists()) {
4015                tracesFile.mkdirs();
4016                if (!SELinux.restorecon(tracesDir)) {
4017                    return null;
4018                }
4019            }
4020            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4021
4022            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4023            tracesFile.createNewFile();
4024            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4025        } catch (IOException e) {
4026            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4027            return null;
4028        }
4029
4030        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4031        return tracesFile;
4032    }
4033
4034    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4035            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4036        // Use a FileObserver to detect when traces finish writing.
4037        // The order of traces is considered important to maintain for legibility.
4038        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4039            @Override
4040            public synchronized void onEvent(int event, String path) { notify(); }
4041        };
4042
4043        try {
4044            observer.startWatching();
4045
4046            // First collect all of the stacks of the most important pids.
4047            if (firstPids != null) {
4048                try {
4049                    int num = firstPids.size();
4050                    for (int i = 0; i < num; i++) {
4051                        synchronized (observer) {
4052                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4053                            observer.wait(200);  // Wait for write-close, give up after 200msec
4054                        }
4055                    }
4056                } catch (InterruptedException e) {
4057                    Log.wtf(TAG, e);
4058                }
4059            }
4060
4061            // Next collect the stacks of the native pids
4062            if (nativeProcs != null) {
4063                int[] pids = Process.getPidsForCommands(nativeProcs);
4064                if (pids != null) {
4065                    for (int pid : pids) {
4066                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4067                    }
4068                }
4069            }
4070
4071            // Lastly, measure CPU usage.
4072            if (processCpuTracker != null) {
4073                processCpuTracker.init();
4074                System.gc();
4075                processCpuTracker.update();
4076                try {
4077                    synchronized (processCpuTracker) {
4078                        processCpuTracker.wait(500); // measure over 1/2 second.
4079                    }
4080                } catch (InterruptedException e) {
4081                }
4082                processCpuTracker.update();
4083
4084                // We'll take the stack crawls of just the top apps using CPU.
4085                final int N = processCpuTracker.countWorkingStats();
4086                int numProcs = 0;
4087                for (int i=0; i<N && numProcs<5; i++) {
4088                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4089                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4090                        numProcs++;
4091                        try {
4092                            synchronized (observer) {
4093                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4094                                observer.wait(200);  // Wait for write-close, give up after 200msec
4095                            }
4096                        } catch (InterruptedException e) {
4097                            Log.wtf(TAG, e);
4098                        }
4099
4100                    }
4101                }
4102            }
4103        } finally {
4104            observer.stopWatching();
4105        }
4106    }
4107
4108    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4109        if (true || IS_USER_BUILD) {
4110            return;
4111        }
4112        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4113        if (tracesPath == null || tracesPath.length() == 0) {
4114            return;
4115        }
4116
4117        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4118        StrictMode.allowThreadDiskWrites();
4119        try {
4120            final File tracesFile = new File(tracesPath);
4121            final File tracesDir = tracesFile.getParentFile();
4122            final File tracesTmp = new File(tracesDir, "__tmp__");
4123            try {
4124                if (!tracesDir.exists()) {
4125                    tracesFile.mkdirs();
4126                    if (!SELinux.restorecon(tracesDir.getPath())) {
4127                        return;
4128                    }
4129                }
4130                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4131
4132                if (tracesFile.exists()) {
4133                    tracesTmp.delete();
4134                    tracesFile.renameTo(tracesTmp);
4135                }
4136                StringBuilder sb = new StringBuilder();
4137                Time tobj = new Time();
4138                tobj.set(System.currentTimeMillis());
4139                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4140                sb.append(": ");
4141                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4142                sb.append(" since ");
4143                sb.append(msg);
4144                FileOutputStream fos = new FileOutputStream(tracesFile);
4145                fos.write(sb.toString().getBytes());
4146                if (app == null) {
4147                    fos.write("\n*** No application process!".getBytes());
4148                }
4149                fos.close();
4150                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4151            } catch (IOException e) {
4152                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4153                return;
4154            }
4155
4156            if (app != null) {
4157                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4158                firstPids.add(app.pid);
4159                dumpStackTraces(tracesPath, firstPids, null, null, null);
4160            }
4161
4162            File lastTracesFile = null;
4163            File curTracesFile = null;
4164            for (int i=9; i>=0; i--) {
4165                String name = String.format(Locale.US, "slow%02d.txt", i);
4166                curTracesFile = new File(tracesDir, name);
4167                if (curTracesFile.exists()) {
4168                    if (lastTracesFile != null) {
4169                        curTracesFile.renameTo(lastTracesFile);
4170                    } else {
4171                        curTracesFile.delete();
4172                    }
4173                }
4174                lastTracesFile = curTracesFile;
4175            }
4176            tracesFile.renameTo(curTracesFile);
4177            if (tracesTmp.exists()) {
4178                tracesTmp.renameTo(tracesFile);
4179            }
4180        } finally {
4181            StrictMode.setThreadPolicy(oldPolicy);
4182        }
4183    }
4184
4185    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4186            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4187        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4188        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4189
4190        if (mController != null) {
4191            try {
4192                // 0 == continue, -1 = kill process immediately
4193                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4194                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
4195            } catch (RemoteException e) {
4196                mController = null;
4197                Watchdog.getInstance().setActivityController(null);
4198            }
4199        }
4200
4201        long anrTime = SystemClock.uptimeMillis();
4202        if (MONITOR_CPU_USAGE) {
4203            updateCpuStatsNow();
4204        }
4205
4206        synchronized (this) {
4207            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4208            if (mShuttingDown) {
4209                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4210                return;
4211            } else if (app.notResponding) {
4212                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4213                return;
4214            } else if (app.crashing) {
4215                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4216                return;
4217            }
4218
4219            // In case we come through here for the same app before completing
4220            // this one, mark as anring now so we will bail out.
4221            app.notResponding = true;
4222
4223            // Log the ANR to the event log.
4224            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4225                    app.processName, app.info.flags, annotation);
4226
4227            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4228            firstPids.add(app.pid);
4229
4230            int parentPid = app.pid;
4231            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4232            if (parentPid != app.pid) firstPids.add(parentPid);
4233
4234            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4235
4236            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4237                ProcessRecord r = mLruProcesses.get(i);
4238                if (r != null && r.thread != null) {
4239                    int pid = r.pid;
4240                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4241                        if (r.persistent) {
4242                            firstPids.add(pid);
4243                        } else {
4244                            lastPids.put(pid, Boolean.TRUE);
4245                        }
4246                    }
4247                }
4248            }
4249        }
4250
4251        // Log the ANR to the main log.
4252        StringBuilder info = new StringBuilder();
4253        info.setLength(0);
4254        info.append("ANR in ").append(app.processName);
4255        if (activity != null && activity.shortComponentName != null) {
4256            info.append(" (").append(activity.shortComponentName).append(")");
4257        }
4258        info.append("\n");
4259        info.append("PID: ").append(app.pid).append("\n");
4260        if (annotation != null) {
4261            info.append("Reason: ").append(annotation).append("\n");
4262        }
4263        if (parent != null && parent != activity) {
4264            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4265        }
4266
4267        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4268
4269        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4270                NATIVE_STACKS_OF_INTEREST);
4271
4272        String cpuInfo = null;
4273        if (MONITOR_CPU_USAGE) {
4274            updateCpuStatsNow();
4275            synchronized (mProcessCpuThread) {
4276                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4277            }
4278            info.append(processCpuTracker.printCurrentLoad());
4279            info.append(cpuInfo);
4280        }
4281
4282        info.append(processCpuTracker.printCurrentState(anrTime));
4283
4284        Slog.e(TAG, info.toString());
4285        if (tracesFile == null) {
4286            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4287            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4288        }
4289
4290        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4291                cpuInfo, tracesFile, null);
4292
4293        if (mController != null) {
4294            try {
4295                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4296                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4297                if (res != 0) {
4298                    if (res < 0 && app.pid != MY_PID) {
4299                        Process.killProcess(app.pid);
4300                    } else {
4301                        synchronized (this) {
4302                            mServices.scheduleServiceTimeoutLocked(app);
4303                        }
4304                    }
4305                    return;
4306                }
4307            } catch (RemoteException e) {
4308                mController = null;
4309                Watchdog.getInstance().setActivityController(null);
4310            }
4311        }
4312
4313        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4314        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4315                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4316
4317        synchronized (this) {
4318            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4319                killUnneededProcessLocked(app, "background ANR");
4320                return;
4321            }
4322
4323            // Set the app's notResponding state, and look up the errorReportReceiver
4324            makeAppNotRespondingLocked(app,
4325                    activity != null ? activity.shortComponentName : null,
4326                    annotation != null ? "ANR " + annotation : "ANR",
4327                    info.toString());
4328
4329            // Bring up the infamous App Not Responding dialog
4330            Message msg = Message.obtain();
4331            HashMap<String, Object> map = new HashMap<String, Object>();
4332            msg.what = SHOW_NOT_RESPONDING_MSG;
4333            msg.obj = map;
4334            msg.arg1 = aboveSystem ? 1 : 0;
4335            map.put("app", app);
4336            if (activity != null) {
4337                map.put("activity", activity);
4338            }
4339
4340            mHandler.sendMessage(msg);
4341        }
4342    }
4343
4344    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4345        if (!mLaunchWarningShown) {
4346            mLaunchWarningShown = true;
4347            mHandler.post(new Runnable() {
4348                @Override
4349                public void run() {
4350                    synchronized (ActivityManagerService.this) {
4351                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4352                        d.show();
4353                        mHandler.postDelayed(new Runnable() {
4354                            @Override
4355                            public void run() {
4356                                synchronized (ActivityManagerService.this) {
4357                                    d.dismiss();
4358                                    mLaunchWarningShown = false;
4359                                }
4360                            }
4361                        }, 4000);
4362                    }
4363                }
4364            });
4365        }
4366    }
4367
4368    @Override
4369    public boolean clearApplicationUserData(final String packageName,
4370            final IPackageDataObserver observer, int userId) {
4371        enforceNotIsolatedCaller("clearApplicationUserData");
4372        int uid = Binder.getCallingUid();
4373        int pid = Binder.getCallingPid();
4374        userId = handleIncomingUser(pid, uid,
4375                userId, false, true, "clearApplicationUserData", null);
4376        long callingId = Binder.clearCallingIdentity();
4377        try {
4378            IPackageManager pm = AppGlobals.getPackageManager();
4379            int pkgUid = -1;
4380            synchronized(this) {
4381                try {
4382                    pkgUid = pm.getPackageUid(packageName, userId);
4383                } catch (RemoteException e) {
4384                }
4385                if (pkgUid == -1) {
4386                    Slog.w(TAG, "Invalid packageName: " + packageName);
4387                    if (observer != null) {
4388                        try {
4389                            observer.onRemoveCompleted(packageName, false);
4390                        } catch (RemoteException e) {
4391                            Slog.i(TAG, "Observer no longer exists.");
4392                        }
4393                    }
4394                    return false;
4395                }
4396                if (uid == pkgUid || checkComponentPermission(
4397                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4398                        pid, uid, -1, true)
4399                        == PackageManager.PERMISSION_GRANTED) {
4400                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4401                } else {
4402                    throw new SecurityException("PID " + pid + " does not have permission "
4403                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4404                                    + " of package " + packageName);
4405                }
4406            }
4407
4408            try {
4409                // Clear application user data
4410                pm.clearApplicationUserData(packageName, observer, userId);
4411
4412                // Remove all permissions granted from/to this package
4413                removeUriPermissionsForPackageLocked(packageName, userId, true);
4414
4415                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4416                        Uri.fromParts("package", packageName, null));
4417                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4418                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4419                        null, null, 0, null, null, null, false, false, userId);
4420            } catch (RemoteException e) {
4421            }
4422        } finally {
4423            Binder.restoreCallingIdentity(callingId);
4424        }
4425        return true;
4426    }
4427
4428    @Override
4429    public void killBackgroundProcesses(final String packageName, int userId) {
4430        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4431                != PackageManager.PERMISSION_GRANTED &&
4432                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4433                        != PackageManager.PERMISSION_GRANTED) {
4434            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4435                    + Binder.getCallingPid()
4436                    + ", uid=" + Binder.getCallingUid()
4437                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4438            Slog.w(TAG, msg);
4439            throw new SecurityException(msg);
4440        }
4441
4442        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4443                userId, true, true, "killBackgroundProcesses", null);
4444        long callingId = Binder.clearCallingIdentity();
4445        try {
4446            IPackageManager pm = AppGlobals.getPackageManager();
4447            synchronized(this) {
4448                int appId = -1;
4449                try {
4450                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4451                } catch (RemoteException e) {
4452                }
4453                if (appId == -1) {
4454                    Slog.w(TAG, "Invalid packageName: " + packageName);
4455                    return;
4456                }
4457                killPackageProcessesLocked(packageName, appId, userId,
4458                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4459            }
4460        } finally {
4461            Binder.restoreCallingIdentity(callingId);
4462        }
4463    }
4464
4465    @Override
4466    public void killAllBackgroundProcesses() {
4467        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4468                != PackageManager.PERMISSION_GRANTED) {
4469            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4470                    + Binder.getCallingPid()
4471                    + ", uid=" + Binder.getCallingUid()
4472                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4473            Slog.w(TAG, msg);
4474            throw new SecurityException(msg);
4475        }
4476
4477        long callingId = Binder.clearCallingIdentity();
4478        try {
4479            synchronized(this) {
4480                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4481                final int NP = mProcessNames.getMap().size();
4482                for (int ip=0; ip<NP; ip++) {
4483                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4484                    final int NA = apps.size();
4485                    for (int ia=0; ia<NA; ia++) {
4486                        ProcessRecord app = apps.valueAt(ia);
4487                        if (app.persistent) {
4488                            // we don't kill persistent processes
4489                            continue;
4490                        }
4491                        if (app.removed) {
4492                            procs.add(app);
4493                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4494                            app.removed = true;
4495                            procs.add(app);
4496                        }
4497                    }
4498                }
4499
4500                int N = procs.size();
4501                for (int i=0; i<N; i++) {
4502                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4503                }
4504                mAllowLowerMemLevel = true;
4505                updateOomAdjLocked();
4506                doLowMemReportIfNeededLocked(null);
4507            }
4508        } finally {
4509            Binder.restoreCallingIdentity(callingId);
4510        }
4511    }
4512
4513    @Override
4514    public void forceStopPackage(final String packageName, int userId) {
4515        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4516                != PackageManager.PERMISSION_GRANTED) {
4517            String msg = "Permission Denial: forceStopPackage() from pid="
4518                    + Binder.getCallingPid()
4519                    + ", uid=" + Binder.getCallingUid()
4520                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4521            Slog.w(TAG, msg);
4522            throw new SecurityException(msg);
4523        }
4524        final int callingPid = Binder.getCallingPid();
4525        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4526                userId, true, true, "forceStopPackage", null);
4527        long callingId = Binder.clearCallingIdentity();
4528        try {
4529            IPackageManager pm = AppGlobals.getPackageManager();
4530            synchronized(this) {
4531                int[] users = userId == UserHandle.USER_ALL
4532                        ? getUsersLocked() : new int[] { userId };
4533                for (int user : users) {
4534                    int pkgUid = -1;
4535                    try {
4536                        pkgUid = pm.getPackageUid(packageName, user);
4537                    } catch (RemoteException e) {
4538                    }
4539                    if (pkgUid == -1) {
4540                        Slog.w(TAG, "Invalid packageName: " + packageName);
4541                        continue;
4542                    }
4543                    try {
4544                        pm.setPackageStoppedState(packageName, true, user);
4545                    } catch (RemoteException e) {
4546                    } catch (IllegalArgumentException e) {
4547                        Slog.w(TAG, "Failed trying to unstop package "
4548                                + packageName + ": " + e);
4549                    }
4550                    if (isUserRunningLocked(user, false)) {
4551                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4552                    }
4553                }
4554            }
4555        } finally {
4556            Binder.restoreCallingIdentity(callingId);
4557        }
4558    }
4559
4560    /*
4561     * The pkg name and app id have to be specified.
4562     */
4563    @Override
4564    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4565        if (pkg == null) {
4566            return;
4567        }
4568        // Make sure the uid is valid.
4569        if (appid < 0) {
4570            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4571            return;
4572        }
4573        int callerUid = Binder.getCallingUid();
4574        // Only the system server can kill an application
4575        if (callerUid == Process.SYSTEM_UID) {
4576            // Post an aysnc message to kill the application
4577            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4578            msg.arg1 = appid;
4579            msg.arg2 = 0;
4580            Bundle bundle = new Bundle();
4581            bundle.putString("pkg", pkg);
4582            bundle.putString("reason", reason);
4583            msg.obj = bundle;
4584            mHandler.sendMessage(msg);
4585        } else {
4586            throw new SecurityException(callerUid + " cannot kill pkg: " +
4587                    pkg);
4588        }
4589    }
4590
4591    @Override
4592    public void closeSystemDialogs(String reason) {
4593        enforceNotIsolatedCaller("closeSystemDialogs");
4594
4595        final int pid = Binder.getCallingPid();
4596        final int uid = Binder.getCallingUid();
4597        final long origId = Binder.clearCallingIdentity();
4598        try {
4599            synchronized (this) {
4600                // Only allow this from foreground processes, so that background
4601                // applications can't abuse it to prevent system UI from being shown.
4602                if (uid >= Process.FIRST_APPLICATION_UID) {
4603                    ProcessRecord proc;
4604                    synchronized (mPidsSelfLocked) {
4605                        proc = mPidsSelfLocked.get(pid);
4606                    }
4607                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4608                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4609                                + " from background process " + proc);
4610                        return;
4611                    }
4612                }
4613                closeSystemDialogsLocked(reason);
4614            }
4615        } finally {
4616            Binder.restoreCallingIdentity(origId);
4617        }
4618    }
4619
4620    void closeSystemDialogsLocked(String reason) {
4621        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4622        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4623                | Intent.FLAG_RECEIVER_FOREGROUND);
4624        if (reason != null) {
4625            intent.putExtra("reason", reason);
4626        }
4627        mWindowManager.closeSystemDialogs(reason);
4628
4629        mStackSupervisor.closeSystemDialogsLocked();
4630
4631        broadcastIntentLocked(null, null, intent, null,
4632                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4633                Process.SYSTEM_UID, UserHandle.USER_ALL);
4634    }
4635
4636    @Override
4637    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4638        enforceNotIsolatedCaller("getProcessMemoryInfo");
4639        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4640        for (int i=pids.length-1; i>=0; i--) {
4641            ProcessRecord proc;
4642            int oomAdj;
4643            synchronized (this) {
4644                synchronized (mPidsSelfLocked) {
4645                    proc = mPidsSelfLocked.get(pids[i]);
4646                    oomAdj = proc != null ? proc.setAdj : 0;
4647                }
4648            }
4649            infos[i] = new Debug.MemoryInfo();
4650            Debug.getMemoryInfo(pids[i], infos[i]);
4651            if (proc != null) {
4652                synchronized (this) {
4653                    if (proc.thread != null && proc.setAdj == oomAdj) {
4654                        // Record this for posterity if the process has been stable.
4655                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4656                                infos[i].getTotalUss(), false, proc.pkgList);
4657                    }
4658                }
4659            }
4660        }
4661        return infos;
4662    }
4663
4664    @Override
4665    public long[] getProcessPss(int[] pids) {
4666        enforceNotIsolatedCaller("getProcessPss");
4667        long[] pss = new long[pids.length];
4668        for (int i=pids.length-1; i>=0; i--) {
4669            ProcessRecord proc;
4670            int oomAdj;
4671            synchronized (this) {
4672                synchronized (mPidsSelfLocked) {
4673                    proc = mPidsSelfLocked.get(pids[i]);
4674                    oomAdj = proc != null ? proc.setAdj : 0;
4675                }
4676            }
4677            long[] tmpUss = new long[1];
4678            pss[i] = Debug.getPss(pids[i], tmpUss);
4679            if (proc != null) {
4680                synchronized (this) {
4681                    if (proc.thread != null && proc.setAdj == oomAdj) {
4682                        // Record this for posterity if the process has been stable.
4683                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4684                    }
4685                }
4686            }
4687        }
4688        return pss;
4689    }
4690
4691    @Override
4692    public void killApplicationProcess(String processName, int uid) {
4693        if (processName == null) {
4694            return;
4695        }
4696
4697        int callerUid = Binder.getCallingUid();
4698        // Only the system server can kill an application
4699        if (callerUid == Process.SYSTEM_UID) {
4700            synchronized (this) {
4701                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4702                if (app != null && app.thread != null) {
4703                    try {
4704                        app.thread.scheduleSuicide();
4705                    } catch (RemoteException e) {
4706                        // If the other end already died, then our work here is done.
4707                    }
4708                } else {
4709                    Slog.w(TAG, "Process/uid not found attempting kill of "
4710                            + processName + " / " + uid);
4711                }
4712            }
4713        } else {
4714            throw new SecurityException(callerUid + " cannot kill app process: " +
4715                    processName);
4716        }
4717    }
4718
4719    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4720        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4721                false, true, false, false, UserHandle.getUserId(uid), reason);
4722        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4723                Uri.fromParts("package", packageName, null));
4724        if (!mProcessesReady) {
4725            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4726                    | Intent.FLAG_RECEIVER_FOREGROUND);
4727        }
4728        intent.putExtra(Intent.EXTRA_UID, uid);
4729        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4730        broadcastIntentLocked(null, null, intent,
4731                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4732                false, false,
4733                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4734    }
4735
4736    private void forceStopUserLocked(int userId, String reason) {
4737        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4738        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4739        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4740                | Intent.FLAG_RECEIVER_FOREGROUND);
4741        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4742        broadcastIntentLocked(null, null, intent,
4743                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4744                false, false,
4745                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4746    }
4747
4748    private final boolean killPackageProcessesLocked(String packageName, int appId,
4749            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4750            boolean doit, boolean evenPersistent, String reason) {
4751        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4752
4753        // Remove all processes this package may have touched: all with the
4754        // same UID (except for the system or root user), and all whose name
4755        // matches the package name.
4756        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4757        final int NP = mProcessNames.getMap().size();
4758        for (int ip=0; ip<NP; ip++) {
4759            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4760            final int NA = apps.size();
4761            for (int ia=0; ia<NA; ia++) {
4762                ProcessRecord app = apps.valueAt(ia);
4763                if (app.persistent && !evenPersistent) {
4764                    // we don't kill persistent processes
4765                    continue;
4766                }
4767                if (app.removed) {
4768                    if (doit) {
4769                        procs.add(app);
4770                    }
4771                    continue;
4772                }
4773
4774                // Skip process if it doesn't meet our oom adj requirement.
4775                if (app.setAdj < minOomAdj) {
4776                    continue;
4777                }
4778
4779                // If no package is specified, we call all processes under the
4780                // give user id.
4781                if (packageName == null) {
4782                    if (app.userId != userId) {
4783                        continue;
4784                    }
4785                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4786                        continue;
4787                    }
4788                // Package has been specified, we want to hit all processes
4789                // that match it.  We need to qualify this by the processes
4790                // that are running under the specified app and user ID.
4791                } else {
4792                    if (UserHandle.getAppId(app.uid) != appId) {
4793                        continue;
4794                    }
4795                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4796                        continue;
4797                    }
4798                    if (!app.pkgList.containsKey(packageName)) {
4799                        continue;
4800                    }
4801                }
4802
4803                // Process has passed all conditions, kill it!
4804                if (!doit) {
4805                    return true;
4806                }
4807                app.removed = true;
4808                procs.add(app);
4809            }
4810        }
4811
4812        int N = procs.size();
4813        for (int i=0; i<N; i++) {
4814            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4815        }
4816        updateOomAdjLocked();
4817        return N > 0;
4818    }
4819
4820    private final boolean forceStopPackageLocked(String name, int appId,
4821            boolean callerWillRestart, boolean purgeCache, boolean doit,
4822            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4823        int i;
4824        int N;
4825
4826        if (userId == UserHandle.USER_ALL && name == null) {
4827            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4828        }
4829
4830        if (appId < 0 && name != null) {
4831            try {
4832                appId = UserHandle.getAppId(
4833                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4834            } catch (RemoteException e) {
4835            }
4836        }
4837
4838        if (doit) {
4839            if (name != null) {
4840                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4841                        + " user=" + userId + ": " + reason);
4842            } else {
4843                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4844            }
4845
4846            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4847            for (int ip=pmap.size()-1; ip>=0; ip--) {
4848                SparseArray<Long> ba = pmap.valueAt(ip);
4849                for (i=ba.size()-1; i>=0; i--) {
4850                    boolean remove = false;
4851                    final int entUid = ba.keyAt(i);
4852                    if (name != null) {
4853                        if (userId == UserHandle.USER_ALL) {
4854                            if (UserHandle.getAppId(entUid) == appId) {
4855                                remove = true;
4856                            }
4857                        } else {
4858                            if (entUid == UserHandle.getUid(userId, appId)) {
4859                                remove = true;
4860                            }
4861                        }
4862                    } else if (UserHandle.getUserId(entUid) == userId) {
4863                        remove = true;
4864                    }
4865                    if (remove) {
4866                        ba.removeAt(i);
4867                    }
4868                }
4869                if (ba.size() == 0) {
4870                    pmap.removeAt(ip);
4871                }
4872            }
4873        }
4874
4875        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4876                -100, callerWillRestart, true, doit, evenPersistent,
4877                name == null ? ("stop user " + userId) : ("stop " + name));
4878
4879        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4880            if (!doit) {
4881                return true;
4882            }
4883            didSomething = true;
4884        }
4885
4886        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4887            if (!doit) {
4888                return true;
4889            }
4890            didSomething = true;
4891        }
4892
4893        if (name == null) {
4894            // Remove all sticky broadcasts from this user.
4895            mStickyBroadcasts.remove(userId);
4896        }
4897
4898        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4899        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4900                userId, providers)) {
4901            if (!doit) {
4902                return true;
4903            }
4904            didSomething = true;
4905        }
4906        N = providers.size();
4907        for (i=0; i<N; i++) {
4908            removeDyingProviderLocked(null, providers.get(i), true);
4909        }
4910
4911        // Remove transient permissions granted from/to this package/user
4912        removeUriPermissionsForPackageLocked(name, userId, false);
4913
4914        if (name == null || uninstalling) {
4915            // Remove pending intents.  For now we only do this when force
4916            // stopping users, because we have some problems when doing this
4917            // for packages -- app widgets are not currently cleaned up for
4918            // such packages, so they can be left with bad pending intents.
4919            if (mIntentSenderRecords.size() > 0) {
4920                Iterator<WeakReference<PendingIntentRecord>> it
4921                        = mIntentSenderRecords.values().iterator();
4922                while (it.hasNext()) {
4923                    WeakReference<PendingIntentRecord> wpir = it.next();
4924                    if (wpir == null) {
4925                        it.remove();
4926                        continue;
4927                    }
4928                    PendingIntentRecord pir = wpir.get();
4929                    if (pir == null) {
4930                        it.remove();
4931                        continue;
4932                    }
4933                    if (name == null) {
4934                        // Stopping user, remove all objects for the user.
4935                        if (pir.key.userId != userId) {
4936                            // Not the same user, skip it.
4937                            continue;
4938                        }
4939                    } else {
4940                        if (UserHandle.getAppId(pir.uid) != appId) {
4941                            // Different app id, skip it.
4942                            continue;
4943                        }
4944                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4945                            // Different user, skip it.
4946                            continue;
4947                        }
4948                        if (!pir.key.packageName.equals(name)) {
4949                            // Different package, skip it.
4950                            continue;
4951                        }
4952                    }
4953                    if (!doit) {
4954                        return true;
4955                    }
4956                    didSomething = true;
4957                    it.remove();
4958                    pir.canceled = true;
4959                    if (pir.key.activity != null) {
4960                        pir.key.activity.pendingResults.remove(pir.ref);
4961                    }
4962                }
4963            }
4964        }
4965
4966        if (doit) {
4967            if (purgeCache && name != null) {
4968                AttributeCache ac = AttributeCache.instance();
4969                if (ac != null) {
4970                    ac.removePackage(name);
4971                }
4972            }
4973            if (mBooted) {
4974                mStackSupervisor.resumeTopActivitiesLocked();
4975                mStackSupervisor.scheduleIdleLocked();
4976            }
4977        }
4978
4979        return didSomething;
4980    }
4981
4982    private final boolean removeProcessLocked(ProcessRecord app,
4983            boolean callerWillRestart, boolean allowRestart, String reason) {
4984        final String name = app.processName;
4985        final int uid = app.uid;
4986        if (DEBUG_PROCESSES) Slog.d(
4987            TAG, "Force removing proc " + app.toShortString() + " (" + name
4988            + "/" + uid + ")");
4989
4990        mProcessNames.remove(name, uid);
4991        mIsolatedProcesses.remove(app.uid);
4992        if (mHeavyWeightProcess == app) {
4993            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4994                    mHeavyWeightProcess.userId, 0));
4995            mHeavyWeightProcess = null;
4996        }
4997        boolean needRestart = false;
4998        if (app.pid > 0 && app.pid != MY_PID) {
4999            int pid = app.pid;
5000            synchronized (mPidsSelfLocked) {
5001                mPidsSelfLocked.remove(pid);
5002                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5003            }
5004            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5005                    app.processName, app.info.uid);
5006            if (app.isolated) {
5007                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5008            }
5009            killUnneededProcessLocked(app, reason);
5010            handleAppDiedLocked(app, true, allowRestart);
5011            removeLruProcessLocked(app);
5012
5013            if (app.persistent && !app.isolated) {
5014                if (!callerWillRestart) {
5015                    addAppLocked(app.info, false);
5016                } else {
5017                    needRestart = true;
5018                }
5019            }
5020        } else {
5021            mRemovedProcesses.add(app);
5022        }
5023
5024        return needRestart;
5025    }
5026
5027    private final void processStartTimedOutLocked(ProcessRecord app) {
5028        final int pid = app.pid;
5029        boolean gone = false;
5030        synchronized (mPidsSelfLocked) {
5031            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5032            if (knownApp != null && knownApp.thread == null) {
5033                mPidsSelfLocked.remove(pid);
5034                gone = true;
5035            }
5036        }
5037
5038        if (gone) {
5039            Slog.w(TAG, "Process " + app + " failed to attach");
5040            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5041                    pid, app.uid, app.processName);
5042            mProcessNames.remove(app.processName, app.uid);
5043            mIsolatedProcesses.remove(app.uid);
5044            if (mHeavyWeightProcess == app) {
5045                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5046                        mHeavyWeightProcess.userId, 0));
5047                mHeavyWeightProcess = null;
5048            }
5049            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5050                    app.processName, app.info.uid);
5051            if (app.isolated) {
5052                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5053            }
5054            // Take care of any launching providers waiting for this process.
5055            checkAppInLaunchingProvidersLocked(app, true);
5056            // Take care of any services that are waiting for the process.
5057            mServices.processStartTimedOutLocked(app);
5058            killUnneededProcessLocked(app, "start timeout");
5059            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5060                Slog.w(TAG, "Unattached app died before backup, skipping");
5061                try {
5062                    IBackupManager bm = IBackupManager.Stub.asInterface(
5063                            ServiceManager.getService(Context.BACKUP_SERVICE));
5064                    bm.agentDisconnected(app.info.packageName);
5065                } catch (RemoteException e) {
5066                    // Can't happen; the backup manager is local
5067                }
5068            }
5069            if (isPendingBroadcastProcessLocked(pid)) {
5070                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5071                skipPendingBroadcastLocked(pid);
5072            }
5073        } else {
5074            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5075        }
5076    }
5077
5078    private final boolean attachApplicationLocked(IApplicationThread thread,
5079            int pid) {
5080
5081        // Find the application record that is being attached...  either via
5082        // the pid if we are running in multiple processes, or just pull the
5083        // next app record if we are emulating process with anonymous threads.
5084        ProcessRecord app;
5085        if (pid != MY_PID && pid >= 0) {
5086            synchronized (mPidsSelfLocked) {
5087                app = mPidsSelfLocked.get(pid);
5088            }
5089        } else {
5090            app = null;
5091        }
5092
5093        if (app == null) {
5094            Slog.w(TAG, "No pending application record for pid " + pid
5095                    + " (IApplicationThread " + thread + "); dropping process");
5096            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5097            if (pid > 0 && pid != MY_PID) {
5098                Process.killProcessQuiet(pid);
5099            } else {
5100                try {
5101                    thread.scheduleExit();
5102                } catch (Exception e) {
5103                    // Ignore exceptions.
5104                }
5105            }
5106            return false;
5107        }
5108
5109        // If this application record is still attached to a previous
5110        // process, clean it up now.
5111        if (app.thread != null) {
5112            handleAppDiedLocked(app, true, true);
5113        }
5114
5115        // Tell the process all about itself.
5116
5117        if (localLOGV) Slog.v(
5118                TAG, "Binding process pid " + pid + " to record " + app);
5119
5120        final String processName = app.processName;
5121        try {
5122            AppDeathRecipient adr = new AppDeathRecipient(
5123                    app, pid, thread);
5124            thread.asBinder().linkToDeath(adr, 0);
5125            app.deathRecipient = adr;
5126        } catch (RemoteException e) {
5127            app.resetPackageList(mProcessStats);
5128            startProcessLocked(app, "link fail", processName);
5129            return false;
5130        }
5131
5132        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5133
5134        app.makeActive(thread, mProcessStats);
5135        app.curAdj = app.setAdj = -100;
5136        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5137        app.forcingToForeground = null;
5138        updateProcessForegroundLocked(app, false, false);
5139        app.hasShownUi = false;
5140        app.debugging = false;
5141        app.cached = false;
5142
5143        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5144
5145        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5146        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5147
5148        if (!normalMode) {
5149            Slog.i(TAG, "Launching preboot mode app: " + app);
5150        }
5151
5152        if (localLOGV) Slog.v(
5153            TAG, "New app record " + app
5154            + " thread=" + thread.asBinder() + " pid=" + pid);
5155        try {
5156            int testMode = IApplicationThread.DEBUG_OFF;
5157            if (mDebugApp != null && mDebugApp.equals(processName)) {
5158                testMode = mWaitForDebugger
5159                    ? IApplicationThread.DEBUG_WAIT
5160                    : IApplicationThread.DEBUG_ON;
5161                app.debugging = true;
5162                if (mDebugTransient) {
5163                    mDebugApp = mOrigDebugApp;
5164                    mWaitForDebugger = mOrigWaitForDebugger;
5165                }
5166            }
5167            String profileFile = app.instrumentationProfileFile;
5168            ParcelFileDescriptor profileFd = null;
5169            boolean profileAutoStop = false;
5170            if (mProfileApp != null && mProfileApp.equals(processName)) {
5171                mProfileProc = app;
5172                profileFile = mProfileFile;
5173                profileFd = mProfileFd;
5174                profileAutoStop = mAutoStopProfiler;
5175            }
5176            boolean enableOpenGlTrace = false;
5177            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5178                enableOpenGlTrace = true;
5179                mOpenGlTraceApp = null;
5180            }
5181
5182            // If the app is being launched for restore or full backup, set it up specially
5183            boolean isRestrictedBackupMode = false;
5184            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5185                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5186                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5187                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5188            }
5189
5190            ensurePackageDexOpt(app.instrumentationInfo != null
5191                    ? app.instrumentationInfo.packageName
5192                    : app.info.packageName);
5193            if (app.instrumentationClass != null) {
5194                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5195            }
5196            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5197                    + processName + " with config " + mConfiguration);
5198            ApplicationInfo appInfo = app.instrumentationInfo != null
5199                    ? app.instrumentationInfo : app.info;
5200            app.compat = compatibilityInfoForPackageLocked(appInfo);
5201            if (profileFd != null) {
5202                profileFd = profileFd.dup();
5203            }
5204            thread.bindApplication(processName, appInfo, providers,
5205                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5206                    app.instrumentationArguments, app.instrumentationWatcher,
5207                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5208                    isRestrictedBackupMode || !normalMode, app.persistent,
5209                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5210                    mCoreSettingsObserver.getCoreSettingsLocked());
5211            updateLruProcessLocked(app, false, null);
5212            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5213        } catch (Exception e) {
5214            // todo: Yikes!  What should we do?  For now we will try to
5215            // start another process, but that could easily get us in
5216            // an infinite loop of restarting processes...
5217            Slog.w(TAG, "Exception thrown during bind!", e);
5218
5219            app.resetPackageList(mProcessStats);
5220            app.unlinkDeathRecipient();
5221            startProcessLocked(app, "bind fail", processName);
5222            return false;
5223        }
5224
5225        // Remove this record from the list of starting applications.
5226        mPersistentStartingProcesses.remove(app);
5227        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5228                "Attach application locked removing on hold: " + app);
5229        mProcessesOnHold.remove(app);
5230
5231        boolean badApp = false;
5232        boolean didSomething = false;
5233
5234        // See if the top visible activity is waiting to run in this process...
5235        if (normalMode) {
5236            try {
5237                if (mStackSupervisor.attachApplicationLocked(app)) {
5238                    didSomething = true;
5239                }
5240            } catch (Exception e) {
5241                badApp = true;
5242            }
5243        }
5244
5245        // Find any services that should be running in this process...
5246        if (!badApp) {
5247            try {
5248                didSomething |= mServices.attachApplicationLocked(app, processName);
5249            } catch (Exception e) {
5250                badApp = true;
5251            }
5252        }
5253
5254        // Check if a next-broadcast receiver is in this process...
5255        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5256            try {
5257                didSomething |= sendPendingBroadcastsLocked(app);
5258            } catch (Exception e) {
5259                // If the app died trying to launch the receiver we declare it 'bad'
5260                badApp = true;
5261            }
5262        }
5263
5264        // Check whether the next backup agent is in this process...
5265        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5266            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5267            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5268            try {
5269                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5270                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5271                        mBackupTarget.backupMode);
5272            } catch (Exception e) {
5273                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5274                e.printStackTrace();
5275            }
5276        }
5277
5278        if (badApp) {
5279            // todo: Also need to kill application to deal with all
5280            // kinds of exceptions.
5281            handleAppDiedLocked(app, false, true);
5282            return false;
5283        }
5284
5285        if (!didSomething) {
5286            updateOomAdjLocked();
5287        }
5288
5289        return true;
5290    }
5291
5292    @Override
5293    public final void attachApplication(IApplicationThread thread) {
5294        synchronized (this) {
5295            int callingPid = Binder.getCallingPid();
5296            final long origId = Binder.clearCallingIdentity();
5297            attachApplicationLocked(thread, callingPid);
5298            Binder.restoreCallingIdentity(origId);
5299        }
5300    }
5301
5302    @Override
5303    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5304        final long origId = Binder.clearCallingIdentity();
5305        synchronized (this) {
5306            ActivityStack stack = ActivityRecord.getStackLocked(token);
5307            if (stack != null) {
5308                ActivityRecord r =
5309                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5310                if (stopProfiling) {
5311                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5312                        try {
5313                            mProfileFd.close();
5314                        } catch (IOException e) {
5315                        }
5316                        clearProfilerLocked();
5317                    }
5318                }
5319            }
5320        }
5321        Binder.restoreCallingIdentity(origId);
5322    }
5323
5324    void enableScreenAfterBoot() {
5325        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5326                SystemClock.uptimeMillis());
5327        mWindowManager.enableScreenAfterBoot();
5328
5329        synchronized (this) {
5330            updateEventDispatchingLocked();
5331        }
5332    }
5333
5334    @Override
5335    public void showBootMessage(final CharSequence msg, final boolean always) {
5336        enforceNotIsolatedCaller("showBootMessage");
5337        mWindowManager.showBootMessage(msg, always);
5338    }
5339
5340    @Override
5341    public void dismissKeyguardOnNextActivity() {
5342        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5343        final long token = Binder.clearCallingIdentity();
5344        try {
5345            synchronized (this) {
5346                if (DEBUG_LOCKSCREEN) logLockScreen("");
5347                if (mLockScreenShown) {
5348                    mLockScreenShown = false;
5349                    comeOutOfSleepIfNeededLocked();
5350                }
5351                mStackSupervisor.setDismissKeyguard(true);
5352            }
5353        } finally {
5354            Binder.restoreCallingIdentity(token);
5355        }
5356    }
5357
5358    final void finishBooting() {
5359        // Register receivers to handle package update events
5360        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5361
5362        synchronized (this) {
5363            // Ensure that any processes we had put on hold are now started
5364            // up.
5365            final int NP = mProcessesOnHold.size();
5366            if (NP > 0) {
5367                ArrayList<ProcessRecord> procs =
5368                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5369                for (int ip=0; ip<NP; ip++) {
5370                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5371                            + procs.get(ip));
5372                    startProcessLocked(procs.get(ip), "on-hold", null);
5373                }
5374            }
5375
5376            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5377                // Start looking for apps that are abusing wake locks.
5378                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5379                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5380                // Tell anyone interested that we are done booting!
5381                SystemProperties.set("sys.boot_completed", "1");
5382                SystemProperties.set("dev.bootcomplete", "1");
5383                for (int i=0; i<mStartedUsers.size(); i++) {
5384                    UserStartedState uss = mStartedUsers.valueAt(i);
5385                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5386                        uss.mState = UserStartedState.STATE_RUNNING;
5387                        final int userId = mStartedUsers.keyAt(i);
5388                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5389                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5390                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5391                        broadcastIntentLocked(null, null, intent, null,
5392                                new IIntentReceiver.Stub() {
5393                                    @Override
5394                                    public void performReceive(Intent intent, int resultCode,
5395                                            String data, Bundle extras, boolean ordered,
5396                                            boolean sticky, int sendingUser) {
5397                                        synchronized (ActivityManagerService.this) {
5398                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5399                                                    true, false);
5400                                        }
5401                                    }
5402                                },
5403                                0, null, null,
5404                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5405                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5406                                userId);
5407                    }
5408                }
5409                scheduleStartProfilesLocked();
5410            }
5411        }
5412    }
5413
5414    final void ensureBootCompleted() {
5415        boolean booting;
5416        boolean enableScreen;
5417        synchronized (this) {
5418            booting = mBooting;
5419            mBooting = false;
5420            enableScreen = !mBooted;
5421            mBooted = true;
5422        }
5423
5424        if (booting) {
5425            finishBooting();
5426        }
5427
5428        if (enableScreen) {
5429            enableScreenAfterBoot();
5430        }
5431    }
5432
5433    @Override
5434    public final void activityResumed(IBinder token) {
5435        final long origId = Binder.clearCallingIdentity();
5436        synchronized(this) {
5437            ActivityStack stack = ActivityRecord.getStackLocked(token);
5438            if (stack != null) {
5439                ActivityRecord.activityResumedLocked(token);
5440            }
5441        }
5442        Binder.restoreCallingIdentity(origId);
5443    }
5444
5445    @Override
5446    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5447        final long origId = Binder.clearCallingIdentity();
5448        synchronized(this) {
5449            ActivityStack stack = ActivityRecord.getStackLocked(token);
5450            if (stack != null) {
5451                stack.activityPausedLocked(token, false, persistentState);
5452            }
5453        }
5454        Binder.restoreCallingIdentity(origId);
5455    }
5456
5457    @Override
5458    public final void activityStopped(IBinder token, Bundle icicle,
5459            PersistableBundle persistentState, CharSequence description) {
5460        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5461
5462        // Refuse possible leaked file descriptors
5463        if (icicle != null && icicle.hasFileDescriptors()) {
5464            throw new IllegalArgumentException("File descriptors passed in Bundle");
5465        }
5466
5467        final long origId = Binder.clearCallingIdentity();
5468
5469        synchronized (this) {
5470            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5471            if (r != null) {
5472                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5473            }
5474        }
5475
5476        trimApplications();
5477
5478        Binder.restoreCallingIdentity(origId);
5479    }
5480
5481    @Override
5482    public final void activityDestroyed(IBinder token) {
5483        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5484        synchronized (this) {
5485            ActivityStack stack = ActivityRecord.getStackLocked(token);
5486            if (stack != null) {
5487                stack.activityDestroyedLocked(token);
5488            }
5489        }
5490    }
5491
5492    @Override
5493    public String getCallingPackage(IBinder token) {
5494        synchronized (this) {
5495            ActivityRecord r = getCallingRecordLocked(token);
5496            return r != null ? r.info.packageName : null;
5497        }
5498    }
5499
5500    @Override
5501    public ComponentName getCallingActivity(IBinder token) {
5502        synchronized (this) {
5503            ActivityRecord r = getCallingRecordLocked(token);
5504            return r != null ? r.intent.getComponent() : null;
5505        }
5506    }
5507
5508    private ActivityRecord getCallingRecordLocked(IBinder token) {
5509        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5510        if (r == null) {
5511            return null;
5512        }
5513        return r.resultTo;
5514    }
5515
5516    @Override
5517    public ComponentName getActivityClassForToken(IBinder token) {
5518        synchronized(this) {
5519            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5520            if (r == null) {
5521                return null;
5522            }
5523            return r.intent.getComponent();
5524        }
5525    }
5526
5527    @Override
5528    public String getPackageForToken(IBinder token) {
5529        synchronized(this) {
5530            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5531            if (r == null) {
5532                return null;
5533            }
5534            return r.packageName;
5535        }
5536    }
5537
5538    @Override
5539    public IIntentSender getIntentSender(int type,
5540            String packageName, IBinder token, String resultWho,
5541            int requestCode, Intent[] intents, String[] resolvedTypes,
5542            int flags, Bundle options, int userId) {
5543        enforceNotIsolatedCaller("getIntentSender");
5544        // Refuse possible leaked file descriptors
5545        if (intents != null) {
5546            if (intents.length < 1) {
5547                throw new IllegalArgumentException("Intents array length must be >= 1");
5548            }
5549            for (int i=0; i<intents.length; i++) {
5550                Intent intent = intents[i];
5551                if (intent != null) {
5552                    if (intent.hasFileDescriptors()) {
5553                        throw new IllegalArgumentException("File descriptors passed in Intent");
5554                    }
5555                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5556                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5557                        throw new IllegalArgumentException(
5558                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5559                    }
5560                    intents[i] = new Intent(intent);
5561                }
5562            }
5563            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5564                throw new IllegalArgumentException(
5565                        "Intent array length does not match resolvedTypes length");
5566            }
5567        }
5568        if (options != null) {
5569            if (options.hasFileDescriptors()) {
5570                throw new IllegalArgumentException("File descriptors passed in options");
5571            }
5572        }
5573
5574        synchronized(this) {
5575            int callingUid = Binder.getCallingUid();
5576            int origUserId = userId;
5577            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5578                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5579                    "getIntentSender", null);
5580            if (origUserId == UserHandle.USER_CURRENT) {
5581                // We don't want to evaluate this until the pending intent is
5582                // actually executed.  However, we do want to always do the
5583                // security checking for it above.
5584                userId = UserHandle.USER_CURRENT;
5585            }
5586            try {
5587                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5588                    int uid = AppGlobals.getPackageManager()
5589                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5590                    if (!UserHandle.isSameApp(callingUid, uid)) {
5591                        String msg = "Permission Denial: getIntentSender() from pid="
5592                            + Binder.getCallingPid()
5593                            + ", uid=" + Binder.getCallingUid()
5594                            + ", (need uid=" + uid + ")"
5595                            + " is not allowed to send as package " + packageName;
5596                        Slog.w(TAG, msg);
5597                        throw new SecurityException(msg);
5598                    }
5599                }
5600
5601                return getIntentSenderLocked(type, packageName, callingUid, userId,
5602                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5603
5604            } catch (RemoteException e) {
5605                throw new SecurityException(e);
5606            }
5607        }
5608    }
5609
5610    IIntentSender getIntentSenderLocked(int type, String packageName,
5611            int callingUid, int userId, IBinder token, String resultWho,
5612            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5613            Bundle options) {
5614        if (DEBUG_MU)
5615            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5616        ActivityRecord activity = null;
5617        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5618            activity = ActivityRecord.isInStackLocked(token);
5619            if (activity == null) {
5620                return null;
5621            }
5622            if (activity.finishing) {
5623                return null;
5624            }
5625        }
5626
5627        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5628        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5629        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5630        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5631                |PendingIntent.FLAG_UPDATE_CURRENT);
5632
5633        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5634                type, packageName, activity, resultWho,
5635                requestCode, intents, resolvedTypes, flags, options, userId);
5636        WeakReference<PendingIntentRecord> ref;
5637        ref = mIntentSenderRecords.get(key);
5638        PendingIntentRecord rec = ref != null ? ref.get() : null;
5639        if (rec != null) {
5640            if (!cancelCurrent) {
5641                if (updateCurrent) {
5642                    if (rec.key.requestIntent != null) {
5643                        rec.key.requestIntent.replaceExtras(intents != null ?
5644                                intents[intents.length - 1] : null);
5645                    }
5646                    if (intents != null) {
5647                        intents[intents.length-1] = rec.key.requestIntent;
5648                        rec.key.allIntents = intents;
5649                        rec.key.allResolvedTypes = resolvedTypes;
5650                    } else {
5651                        rec.key.allIntents = null;
5652                        rec.key.allResolvedTypes = null;
5653                    }
5654                }
5655                return rec;
5656            }
5657            rec.canceled = true;
5658            mIntentSenderRecords.remove(key);
5659        }
5660        if (noCreate) {
5661            return rec;
5662        }
5663        rec = new PendingIntentRecord(this, key, callingUid);
5664        mIntentSenderRecords.put(key, rec.ref);
5665        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5666            if (activity.pendingResults == null) {
5667                activity.pendingResults
5668                        = new HashSet<WeakReference<PendingIntentRecord>>();
5669            }
5670            activity.pendingResults.add(rec.ref);
5671        }
5672        return rec;
5673    }
5674
5675    @Override
5676    public void cancelIntentSender(IIntentSender sender) {
5677        if (!(sender instanceof PendingIntentRecord)) {
5678            return;
5679        }
5680        synchronized(this) {
5681            PendingIntentRecord rec = (PendingIntentRecord)sender;
5682            try {
5683                int uid = AppGlobals.getPackageManager()
5684                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5685                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5686                    String msg = "Permission Denial: cancelIntentSender() from pid="
5687                        + Binder.getCallingPid()
5688                        + ", uid=" + Binder.getCallingUid()
5689                        + " is not allowed to cancel packges "
5690                        + rec.key.packageName;
5691                    Slog.w(TAG, msg);
5692                    throw new SecurityException(msg);
5693                }
5694            } catch (RemoteException e) {
5695                throw new SecurityException(e);
5696            }
5697            cancelIntentSenderLocked(rec, true);
5698        }
5699    }
5700
5701    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5702        rec.canceled = true;
5703        mIntentSenderRecords.remove(rec.key);
5704        if (cleanActivity && rec.key.activity != null) {
5705            rec.key.activity.pendingResults.remove(rec.ref);
5706        }
5707    }
5708
5709    @Override
5710    public String getPackageForIntentSender(IIntentSender pendingResult) {
5711        if (!(pendingResult instanceof PendingIntentRecord)) {
5712            return null;
5713        }
5714        try {
5715            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5716            return res.key.packageName;
5717        } catch (ClassCastException e) {
5718        }
5719        return null;
5720    }
5721
5722    @Override
5723    public int getUidForIntentSender(IIntentSender sender) {
5724        if (sender instanceof PendingIntentRecord) {
5725            try {
5726                PendingIntentRecord res = (PendingIntentRecord)sender;
5727                return res.uid;
5728            } catch (ClassCastException e) {
5729            }
5730        }
5731        return -1;
5732    }
5733
5734    @Override
5735    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5736        if (!(pendingResult instanceof PendingIntentRecord)) {
5737            return false;
5738        }
5739        try {
5740            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5741            if (res.key.allIntents == null) {
5742                return false;
5743            }
5744            for (int i=0; i<res.key.allIntents.length; i++) {
5745                Intent intent = res.key.allIntents[i];
5746                if (intent.getPackage() != null && intent.getComponent() != null) {
5747                    return false;
5748                }
5749            }
5750            return true;
5751        } catch (ClassCastException e) {
5752        }
5753        return false;
5754    }
5755
5756    @Override
5757    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5758        if (!(pendingResult instanceof PendingIntentRecord)) {
5759            return false;
5760        }
5761        try {
5762            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5763            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5764                return true;
5765            }
5766            return false;
5767        } catch (ClassCastException e) {
5768        }
5769        return false;
5770    }
5771
5772    @Override
5773    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5774        if (!(pendingResult instanceof PendingIntentRecord)) {
5775            return null;
5776        }
5777        try {
5778            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5779            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5780        } catch (ClassCastException e) {
5781        }
5782        return null;
5783    }
5784
5785    @Override
5786    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5787        if (!(pendingResult instanceof PendingIntentRecord)) {
5788            return null;
5789        }
5790        try {
5791            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5792            Intent intent = res.key.requestIntent;
5793            if (intent != null) {
5794                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5795                        || res.lastTagPrefix.equals(prefix))) {
5796                    return res.lastTag;
5797                }
5798                res.lastTagPrefix = prefix;
5799                StringBuilder sb = new StringBuilder(128);
5800                if (prefix != null) {
5801                    sb.append(prefix);
5802                }
5803                if (intent.getAction() != null) {
5804                    sb.append(intent.getAction());
5805                } else if (intent.getComponent() != null) {
5806                    intent.getComponent().appendShortString(sb);
5807                } else {
5808                    sb.append("?");
5809                }
5810                return res.lastTag = sb.toString();
5811            }
5812        } catch (ClassCastException e) {
5813        }
5814        return null;
5815    }
5816
5817    @Override
5818    public void setProcessLimit(int max) {
5819        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5820                "setProcessLimit()");
5821        synchronized (this) {
5822            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5823            mProcessLimitOverride = max;
5824        }
5825        trimApplications();
5826    }
5827
5828    @Override
5829    public int getProcessLimit() {
5830        synchronized (this) {
5831            return mProcessLimitOverride;
5832        }
5833    }
5834
5835    void foregroundTokenDied(ForegroundToken token) {
5836        synchronized (ActivityManagerService.this) {
5837            synchronized (mPidsSelfLocked) {
5838                ForegroundToken cur
5839                    = mForegroundProcesses.get(token.pid);
5840                if (cur != token) {
5841                    return;
5842                }
5843                mForegroundProcesses.remove(token.pid);
5844                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5845                if (pr == null) {
5846                    return;
5847                }
5848                pr.forcingToForeground = null;
5849                updateProcessForegroundLocked(pr, false, false);
5850            }
5851            updateOomAdjLocked();
5852        }
5853    }
5854
5855    @Override
5856    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5857        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5858                "setProcessForeground()");
5859        synchronized(this) {
5860            boolean changed = false;
5861
5862            synchronized (mPidsSelfLocked) {
5863                ProcessRecord pr = mPidsSelfLocked.get(pid);
5864                if (pr == null && isForeground) {
5865                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5866                    return;
5867                }
5868                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5869                if (oldToken != null) {
5870                    oldToken.token.unlinkToDeath(oldToken, 0);
5871                    mForegroundProcesses.remove(pid);
5872                    if (pr != null) {
5873                        pr.forcingToForeground = null;
5874                    }
5875                    changed = true;
5876                }
5877                if (isForeground && token != null) {
5878                    ForegroundToken newToken = new ForegroundToken() {
5879                        @Override
5880                        public void binderDied() {
5881                            foregroundTokenDied(this);
5882                        }
5883                    };
5884                    newToken.pid = pid;
5885                    newToken.token = token;
5886                    try {
5887                        token.linkToDeath(newToken, 0);
5888                        mForegroundProcesses.put(pid, newToken);
5889                        pr.forcingToForeground = token;
5890                        changed = true;
5891                    } catch (RemoteException e) {
5892                        // If the process died while doing this, we will later
5893                        // do the cleanup with the process death link.
5894                    }
5895                }
5896            }
5897
5898            if (changed) {
5899                updateOomAdjLocked();
5900            }
5901        }
5902    }
5903
5904    // =========================================================
5905    // PERMISSIONS
5906    // =========================================================
5907
5908    static class PermissionController extends IPermissionController.Stub {
5909        ActivityManagerService mActivityManagerService;
5910        PermissionController(ActivityManagerService activityManagerService) {
5911            mActivityManagerService = activityManagerService;
5912        }
5913
5914        @Override
5915        public boolean checkPermission(String permission, int pid, int uid) {
5916            return mActivityManagerService.checkPermission(permission, pid,
5917                    uid) == PackageManager.PERMISSION_GRANTED;
5918        }
5919    }
5920
5921    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5922        @Override
5923        public int checkComponentPermission(String permission, int pid, int uid,
5924                int owningUid, boolean exported) {
5925            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5926                    owningUid, exported);
5927        }
5928
5929        @Override
5930        public Object getAMSLock() {
5931            return ActivityManagerService.this;
5932        }
5933    }
5934
5935    /**
5936     * This can be called with or without the global lock held.
5937     */
5938    int checkComponentPermission(String permission, int pid, int uid,
5939            int owningUid, boolean exported) {
5940        // We might be performing an operation on behalf of an indirect binder
5941        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5942        // client identity accordingly before proceeding.
5943        Identity tlsIdentity = sCallerIdentity.get();
5944        if (tlsIdentity != null) {
5945            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5946                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5947            uid = tlsIdentity.uid;
5948            pid = tlsIdentity.pid;
5949        }
5950
5951        if (pid == MY_PID) {
5952            return PackageManager.PERMISSION_GRANTED;
5953        }
5954
5955        return ActivityManager.checkComponentPermission(permission, uid,
5956                owningUid, exported);
5957    }
5958
5959    /**
5960     * As the only public entry point for permissions checking, this method
5961     * can enforce the semantic that requesting a check on a null global
5962     * permission is automatically denied.  (Internally a null permission
5963     * string is used when calling {@link #checkComponentPermission} in cases
5964     * when only uid-based security is needed.)
5965     *
5966     * This can be called with or without the global lock held.
5967     */
5968    @Override
5969    public int checkPermission(String permission, int pid, int uid) {
5970        if (permission == null) {
5971            return PackageManager.PERMISSION_DENIED;
5972        }
5973        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5974    }
5975
5976    /**
5977     * Binder IPC calls go through the public entry point.
5978     * This can be called with or without the global lock held.
5979     */
5980    int checkCallingPermission(String permission) {
5981        return checkPermission(permission,
5982                Binder.getCallingPid(),
5983                UserHandle.getAppId(Binder.getCallingUid()));
5984    }
5985
5986    /**
5987     * This can be called with or without the global lock held.
5988     */
5989    void enforceCallingPermission(String permission, String func) {
5990        if (checkCallingPermission(permission)
5991                == PackageManager.PERMISSION_GRANTED) {
5992            return;
5993        }
5994
5995        String msg = "Permission Denial: " + func + " from pid="
5996                + Binder.getCallingPid()
5997                + ", uid=" + Binder.getCallingUid()
5998                + " requires " + permission;
5999        Slog.w(TAG, msg);
6000        throw new SecurityException(msg);
6001    }
6002
6003    /**
6004     * Determine if UID is holding permissions required to access {@link Uri} in
6005     * the given {@link ProviderInfo}. Final permission checking is always done
6006     * in {@link ContentProvider}.
6007     */
6008    private final boolean checkHoldingPermissionsLocked(
6009            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6010        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6011                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6012
6013        if (pi.applicationInfo.uid == uid) {
6014            return true;
6015        } else if (!pi.exported) {
6016            return false;
6017        }
6018
6019        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6020        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6021        try {
6022            // check if target holds top-level <provider> permissions
6023            if (!readMet && pi.readPermission != null
6024                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6025                readMet = true;
6026            }
6027            if (!writeMet && pi.writePermission != null
6028                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6029                writeMet = true;
6030            }
6031
6032            // track if unprotected read/write is allowed; any denied
6033            // <path-permission> below removes this ability
6034            boolean allowDefaultRead = pi.readPermission == null;
6035            boolean allowDefaultWrite = pi.writePermission == null;
6036
6037            // check if target holds any <path-permission> that match uri
6038            final PathPermission[] pps = pi.pathPermissions;
6039            if (pps != null) {
6040                final String path = grantUri.uri.getPath();
6041                int i = pps.length;
6042                while (i > 0 && (!readMet || !writeMet)) {
6043                    i--;
6044                    PathPermission pp = pps[i];
6045                    if (pp.match(path)) {
6046                        if (!readMet) {
6047                            final String pprperm = pp.getReadPermission();
6048                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6049                                    + pprperm + " for " + pp.getPath()
6050                                    + ": match=" + pp.match(path)
6051                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6052                            if (pprperm != null) {
6053                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
6054                                    readMet = true;
6055                                } else {
6056                                    allowDefaultRead = false;
6057                                }
6058                            }
6059                        }
6060                        if (!writeMet) {
6061                            final String ppwperm = pp.getWritePermission();
6062                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6063                                    + ppwperm + " for " + pp.getPath()
6064                                    + ": match=" + pp.match(path)
6065                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6066                            if (ppwperm != null) {
6067                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
6068                                    writeMet = true;
6069                                } else {
6070                                    allowDefaultWrite = false;
6071                                }
6072                            }
6073                        }
6074                    }
6075                }
6076            }
6077
6078            // grant unprotected <provider> read/write, if not blocked by
6079            // <path-permission> above
6080            if (allowDefaultRead) readMet = true;
6081            if (allowDefaultWrite) writeMet = true;
6082
6083        } catch (RemoteException e) {
6084            return false;
6085        }
6086
6087        return readMet && writeMet;
6088    }
6089
6090    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6091        ProviderInfo pi = null;
6092        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6093        if (cpr != null) {
6094            pi = cpr.info;
6095        } else {
6096            try {
6097                pi = AppGlobals.getPackageManager().resolveContentProvider(
6098                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6099            } catch (RemoteException ex) {
6100            }
6101        }
6102        return pi;
6103    }
6104
6105    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6106        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6107        if (targetUris != null) {
6108            return targetUris.get(grantUri);
6109        }
6110        return null;
6111    }
6112
6113    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6114            String targetPkg, int targetUid, GrantUri grantUri) {
6115        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6116        if (targetUris == null) {
6117            targetUris = Maps.newArrayMap();
6118            mGrantedUriPermissions.put(targetUid, targetUris);
6119        }
6120
6121        UriPermission perm = targetUris.get(grantUri);
6122        if (perm == null) {
6123            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6124            targetUris.put(grantUri, perm);
6125        }
6126
6127        return perm;
6128    }
6129
6130    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6131            final int modeFlags) {
6132        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6133        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6134                : UriPermission.STRENGTH_OWNED;
6135
6136        // Root gets to do everything.
6137        if (uid == 0) {
6138            return true;
6139        }
6140
6141        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6142        if (perms == null) return false;
6143
6144        // First look for exact match
6145        final UriPermission exactPerm = perms.get(grantUri);
6146        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6147            return true;
6148        }
6149
6150        // No exact match, look for prefixes
6151        final int N = perms.size();
6152        for (int i = 0; i < N; i++) {
6153            final UriPermission perm = perms.valueAt(i);
6154            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6155                    && perm.getStrength(modeFlags) >= minStrength) {
6156                return true;
6157            }
6158        }
6159
6160        return false;
6161    }
6162
6163    @Override
6164    public int checkUriPermission(Uri uri, int pid, int uid,
6165            final int modeFlags, int userId) {
6166        enforceNotIsolatedCaller("checkUriPermission");
6167
6168        // Another redirected-binder-call permissions check as in
6169        // {@link checkComponentPermission}.
6170        Identity tlsIdentity = sCallerIdentity.get();
6171        if (tlsIdentity != null) {
6172            uid = tlsIdentity.uid;
6173            pid = tlsIdentity.pid;
6174        }
6175
6176        // Our own process gets to do everything.
6177        if (pid == MY_PID) {
6178            return PackageManager.PERMISSION_GRANTED;
6179        }
6180        synchronized (this) {
6181            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6182                    ? PackageManager.PERMISSION_GRANTED
6183                    : PackageManager.PERMISSION_DENIED;
6184        }
6185    }
6186
6187    /**
6188     * Check if the targetPkg can be granted permission to access uri by
6189     * the callingUid using the given modeFlags.  Throws a security exception
6190     * if callingUid is not allowed to do this.  Returns the uid of the target
6191     * if the URI permission grant should be performed; returns -1 if it is not
6192     * needed (for example targetPkg already has permission to access the URI).
6193     * If you already know the uid of the target, you can supply it in
6194     * lastTargetUid else set that to -1.
6195     */
6196    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6197            final int modeFlags, int lastTargetUid) {
6198        if (!Intent.isAccessUriMode(modeFlags)) {
6199            return -1;
6200        }
6201
6202        if (targetPkg != null) {
6203            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6204                    "Checking grant " + targetPkg + " permission to " + grantUri);
6205        }
6206
6207        final IPackageManager pm = AppGlobals.getPackageManager();
6208
6209        // If this is not a content: uri, we can't do anything with it.
6210        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6211            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6212                    "Can't grant URI permission for non-content URI: " + grantUri);
6213            return -1;
6214        }
6215
6216        final String authority = grantUri.uri.getAuthority();
6217        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6218        if (pi == null) {
6219            Slog.w(TAG, "No content provider found for permission check: " +
6220                    grantUri.uri.toSafeString());
6221            return -1;
6222        }
6223
6224        int targetUid = lastTargetUid;
6225        if (targetUid < 0 && targetPkg != null) {
6226            try {
6227                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6228                if (targetUid < 0) {
6229                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6230                            "Can't grant URI permission no uid for: " + targetPkg);
6231                    return -1;
6232                }
6233            } catch (RemoteException ex) {
6234                return -1;
6235            }
6236        }
6237
6238        if (targetUid >= 0) {
6239            // First...  does the target actually need this permission?
6240            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6241                // No need to grant the target this permission.
6242                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6243                        "Target " + targetPkg + " already has full permission to " + grantUri);
6244                return -1;
6245            }
6246        } else {
6247            // First...  there is no target package, so can anyone access it?
6248            boolean allowed = pi.exported;
6249            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6250                if (pi.readPermission != null) {
6251                    allowed = false;
6252                }
6253            }
6254            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6255                if (pi.writePermission != null) {
6256                    allowed = false;
6257                }
6258            }
6259            if (allowed) {
6260                return -1;
6261            }
6262        }
6263
6264        // Second...  is the provider allowing granting of URI permissions?
6265        if (!pi.grantUriPermissions) {
6266            throw new SecurityException("Provider " + pi.packageName
6267                    + "/" + pi.name
6268                    + " does not allow granting of Uri permissions (uri "
6269                    + grantUri + ")");
6270        }
6271        if (pi.uriPermissionPatterns != null) {
6272            final int N = pi.uriPermissionPatterns.length;
6273            boolean allowed = false;
6274            for (int i=0; i<N; i++) {
6275                if (pi.uriPermissionPatterns[i] != null
6276                        && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6277                    allowed = true;
6278                    break;
6279                }
6280            }
6281            if (!allowed) {
6282                throw new SecurityException("Provider " + pi.packageName
6283                        + "/" + pi.name
6284                        + " does not allow granting of permission to path of Uri "
6285                        + grantUri);
6286            }
6287        }
6288
6289        // Third...  does the caller itself have permission to access
6290        // this uri?
6291        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6292            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6293                // Require they hold a strong enough Uri permission
6294                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6295                    throw new SecurityException("Uid " + callingUid
6296                            + " does not have permission to uri " + grantUri);
6297                }
6298            }
6299        }
6300        return targetUid;
6301    }
6302
6303    @Override
6304    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6305            final int modeFlags, int userId) {
6306        enforceNotIsolatedCaller("checkGrantUriPermission");
6307        synchronized(this) {
6308            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6309                    new GrantUri(userId, uri, false), modeFlags, -1);
6310        }
6311    }
6312
6313    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6314            final int modeFlags, UriPermissionOwner owner) {
6315        if (!Intent.isAccessUriMode(modeFlags)) {
6316            return;
6317        }
6318
6319        // So here we are: the caller has the assumed permission
6320        // to the uri, and the target doesn't.  Let's now give this to
6321        // the target.
6322
6323        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6324                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6325
6326        final String authority = grantUri.uri.getAuthority();
6327        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6328        if (pi == null) {
6329            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6330            return;
6331        }
6332
6333        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6334            grantUri.prefix = true;
6335        }
6336        final UriPermission perm = findOrCreateUriPermissionLocked(
6337                pi.packageName, targetPkg, targetUid, grantUri);
6338        perm.grantModes(modeFlags, owner);
6339    }
6340
6341    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6342            final int modeFlags, UriPermissionOwner owner) {
6343        if (targetPkg == null) {
6344            throw new NullPointerException("targetPkg");
6345        }
6346
6347        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6348                -1);
6349        if (targetUid < 0) {
6350            return;
6351        }
6352
6353        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6354                owner);
6355    }
6356
6357    static class NeededUriGrants extends ArrayList<GrantUri> {
6358        final String targetPkg;
6359        final int targetUid;
6360        final int flags;
6361
6362        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6363            this.targetPkg = targetPkg;
6364            this.targetUid = targetUid;
6365            this.flags = flags;
6366        }
6367    }
6368
6369    /**
6370     * Like checkGrantUriPermissionLocked, but takes an Intent.
6371     */
6372    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6373            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6374        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6375                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6376                + " clip=" + (intent != null ? intent.getClipData() : null)
6377                + " from " + intent + "; flags=0x"
6378                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6379
6380        if (targetPkg == null) {
6381            throw new NullPointerException("targetPkg");
6382        }
6383
6384        if (intent == null) {
6385            return null;
6386        }
6387        Uri data = intent.getData();
6388        ClipData clip = intent.getClipData();
6389        if (data == null && clip == null) {
6390            return null;
6391        }
6392
6393        if (data != null) {
6394            GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data);
6395            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6396                    needed != null ? needed.targetUid : -1);
6397            if (targetUid > 0) {
6398                if (needed == null) {
6399                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6400                }
6401                needed.add(grantUri);
6402            }
6403        }
6404        if (clip != null) {
6405            for (int i=0; i<clip.getItemCount(); i++) {
6406                Uri uri = clip.getItemAt(i).getUri();
6407                if (uri != null) {
6408                    int targetUid = -1;
6409                    GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri);
6410                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6411                            needed != null ? needed.targetUid : -1);
6412                    if (targetUid > 0) {
6413                        if (needed == null) {
6414                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6415                        }
6416                        needed.add(grantUri);
6417                    }
6418                } else {
6419                    Intent clipIntent = clip.getItemAt(i).getIntent();
6420                    if (clipIntent != null) {
6421                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6422                                callingUid, targetPkg, clipIntent, mode, needed);
6423                        if (newNeeded != null) {
6424                            needed = newNeeded;
6425                        }
6426                    }
6427                }
6428            }
6429        }
6430
6431        return needed;
6432    }
6433
6434    /**
6435     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6436     */
6437    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6438            UriPermissionOwner owner) {
6439        if (needed != null) {
6440            for (int i=0; i<needed.size(); i++) {
6441                GrantUri grantUri = needed.get(i);
6442                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6443                        grantUri, needed.flags, owner);
6444            }
6445        }
6446    }
6447
6448    void grantUriPermissionFromIntentLocked(int callingUid,
6449            String targetPkg, Intent intent, UriPermissionOwner owner) {
6450        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6451                intent, intent != null ? intent.getFlags() : 0, null);
6452        if (needed == null) {
6453            return;
6454        }
6455
6456        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6457    }
6458
6459    @Override
6460    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6461            final int modeFlags, int userId) {
6462        enforceNotIsolatedCaller("grantUriPermission");
6463        GrantUri grantUri = new GrantUri(userId, uri, false);
6464        synchronized(this) {
6465            final ProcessRecord r = getRecordForAppLocked(caller);
6466            if (r == null) {
6467                throw new SecurityException("Unable to find app for caller "
6468                        + caller
6469                        + " when granting permission to uri " + grantUri);
6470            }
6471            if (targetPkg == null) {
6472                throw new IllegalArgumentException("null target");
6473            }
6474            if (grantUri == null) {
6475                throw new IllegalArgumentException("null uri");
6476            }
6477
6478            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6479                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6480                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6481                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6482
6483            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null);
6484        }
6485    }
6486
6487    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6488        if (perm.modeFlags == 0) {
6489            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6490                    perm.targetUid);
6491            if (perms != null) {
6492                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6493                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6494
6495                perms.remove(perm.uri);
6496                if (perms.isEmpty()) {
6497                    mGrantedUriPermissions.remove(perm.targetUid);
6498                }
6499            }
6500        }
6501    }
6502
6503    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6504        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6505
6506        final IPackageManager pm = AppGlobals.getPackageManager();
6507        final String authority = grantUri.uri.getAuthority();
6508        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6509        if (pi == null) {
6510            Slog.w(TAG, "No content provider found for permission revoke: "
6511                    + grantUri.toSafeString());
6512            return;
6513        }
6514
6515        // Does the caller have this permission on the URI?
6516        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6517            // Right now, if you are not the original owner of the permission,
6518            // you are not allowed to revoke it.
6519            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6520                throw new SecurityException("Uid " + callingUid
6521                        + " does not have permission to uri " + grantUri);
6522            //}
6523        }
6524
6525        boolean persistChanged = false;
6526
6527        // Go through all of the permissions and remove any that match.
6528        int N = mGrantedUriPermissions.size();
6529        for (int i = 0; i < N; i++) {
6530            final int targetUid = mGrantedUriPermissions.keyAt(i);
6531            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6532
6533            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6534                final UriPermission perm = it.next();
6535                if (perm.uri.sourceUserId == grantUri.sourceUserId
6536                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6537                    if (DEBUG_URI_PERMISSION)
6538                        Slog.v(TAG,
6539                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6540                    persistChanged |= perm.revokeModes(
6541                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6542                    if (perm.modeFlags == 0) {
6543                        it.remove();
6544                    }
6545                }
6546            }
6547
6548            if (perms.isEmpty()) {
6549                mGrantedUriPermissions.remove(targetUid);
6550                N--;
6551                i--;
6552            }
6553        }
6554
6555        if (persistChanged) {
6556            schedulePersistUriGrants();
6557        }
6558    }
6559
6560    @Override
6561    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6562            int userId) {
6563        enforceNotIsolatedCaller("revokeUriPermission");
6564        synchronized(this) {
6565            final ProcessRecord r = getRecordForAppLocked(caller);
6566            if (r == null) {
6567                throw new SecurityException("Unable to find app for caller "
6568                        + caller
6569                        + " when revoking permission to uri " + uri);
6570            }
6571            if (uri == null) {
6572                Slog.w(TAG, "revokeUriPermission: null uri");
6573                return;
6574            }
6575
6576            if (!Intent.isAccessUriMode(modeFlags)) {
6577                return;
6578            }
6579
6580            final IPackageManager pm = AppGlobals.getPackageManager();
6581            final String authority = uri.getAuthority();
6582            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6583            if (pi == null) {
6584                Slog.w(TAG, "No content provider found for permission revoke: "
6585                        + uri.toSafeString());
6586                return;
6587            }
6588
6589            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6590        }
6591    }
6592
6593    /**
6594     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6595     * given package.
6596     *
6597     * @param packageName Package name to match, or {@code null} to apply to all
6598     *            packages.
6599     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6600     *            to all users.
6601     * @param persistable If persistable grants should be removed.
6602     */
6603    private void removeUriPermissionsForPackageLocked(
6604            String packageName, int userHandle, boolean persistable) {
6605        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6606            throw new IllegalArgumentException("Must narrow by either package or user");
6607        }
6608
6609        boolean persistChanged = false;
6610
6611        int N = mGrantedUriPermissions.size();
6612        for (int i = 0; i < N; i++) {
6613            final int targetUid = mGrantedUriPermissions.keyAt(i);
6614            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6615
6616            // Only inspect grants matching user
6617            if (userHandle == UserHandle.USER_ALL
6618                    || userHandle == UserHandle.getUserId(targetUid)) {
6619                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6620                    final UriPermission perm = it.next();
6621
6622                    // Only inspect grants matching package
6623                    if (packageName == null || perm.sourcePkg.equals(packageName)
6624                            || perm.targetPkg.equals(packageName)) {
6625                        persistChanged |= perm.revokeModes(
6626                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6627
6628                        // Only remove when no modes remain; any persisted grants
6629                        // will keep this alive.
6630                        if (perm.modeFlags == 0) {
6631                            it.remove();
6632                        }
6633                    }
6634                }
6635
6636                if (perms.isEmpty()) {
6637                    mGrantedUriPermissions.remove(targetUid);
6638                    N--;
6639                    i--;
6640                }
6641            }
6642        }
6643
6644        if (persistChanged) {
6645            schedulePersistUriGrants();
6646        }
6647    }
6648
6649    @Override
6650    public IBinder newUriPermissionOwner(String name) {
6651        enforceNotIsolatedCaller("newUriPermissionOwner");
6652        synchronized(this) {
6653            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6654            return owner.getExternalTokenLocked();
6655        }
6656    }
6657
6658    @Override
6659    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6660            final int modeFlags, int userId) {
6661        synchronized(this) {
6662            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6663            if (owner == null) {
6664                throw new IllegalArgumentException("Unknown owner: " + token);
6665            }
6666            if (fromUid != Binder.getCallingUid()) {
6667                if (Binder.getCallingUid() != Process.myUid()) {
6668                    // Only system code can grant URI permissions on behalf
6669                    // of other users.
6670                    throw new SecurityException("nice try");
6671                }
6672            }
6673            if (targetPkg == null) {
6674                throw new IllegalArgumentException("null target");
6675            }
6676            if (uri == null) {
6677                throw new IllegalArgumentException("null uri");
6678            }
6679
6680            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false),
6681                    modeFlags, owner);
6682        }
6683    }
6684
6685    @Override
6686    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6687        synchronized(this) {
6688            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6689            if (owner == null) {
6690                throw new IllegalArgumentException("Unknown owner: " + token);
6691            }
6692
6693            if (uri == null) {
6694                owner.removeUriPermissionsLocked(mode);
6695            } else {
6696                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
6697            }
6698        }
6699    }
6700
6701    private void schedulePersistUriGrants() {
6702        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6703            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6704                    10 * DateUtils.SECOND_IN_MILLIS);
6705        }
6706    }
6707
6708    private void writeGrantedUriPermissions() {
6709        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6710
6711        // Snapshot permissions so we can persist without lock
6712        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6713        synchronized (this) {
6714            final int size = mGrantedUriPermissions.size();
6715            for (int i = 0; i < size; i++) {
6716                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6717                for (UriPermission perm : perms.values()) {
6718                    if (perm.persistedModeFlags != 0) {
6719                        persist.add(perm.snapshot());
6720                    }
6721                }
6722            }
6723        }
6724
6725        FileOutputStream fos = null;
6726        try {
6727            fos = mGrantFile.startWrite();
6728
6729            XmlSerializer out = new FastXmlSerializer();
6730            out.setOutput(fos, "utf-8");
6731            out.startDocument(null, true);
6732            out.startTag(null, TAG_URI_GRANTS);
6733            for (UriPermission.Snapshot perm : persist) {
6734                out.startTag(null, TAG_URI_GRANT);
6735                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
6736                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
6737                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6738                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6739                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6740                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6741                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6742                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6743                out.endTag(null, TAG_URI_GRANT);
6744            }
6745            out.endTag(null, TAG_URI_GRANTS);
6746            out.endDocument();
6747
6748            mGrantFile.finishWrite(fos);
6749        } catch (IOException e) {
6750            if (fos != null) {
6751                mGrantFile.failWrite(fos);
6752            }
6753        }
6754    }
6755
6756    private void readGrantedUriPermissionsLocked() {
6757        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6758
6759        final long now = System.currentTimeMillis();
6760
6761        FileInputStream fis = null;
6762        try {
6763            fis = mGrantFile.openRead();
6764            final XmlPullParser in = Xml.newPullParser();
6765            in.setInput(fis, null);
6766
6767            int type;
6768            while ((type = in.next()) != END_DOCUMENT) {
6769                final String tag = in.getName();
6770                if (type == START_TAG) {
6771                    if (TAG_URI_GRANT.equals(tag)) {
6772                        final int sourceUserId;
6773                        final int targetUserId;
6774                        final int userHandle = readIntAttribute(in,
6775                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
6776                        if (userHandle != UserHandle.USER_NULL) {
6777                            // For backwards compatibility.
6778                            sourceUserId = userHandle;
6779                            targetUserId = userHandle;
6780                        } else {
6781                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
6782                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
6783                        }
6784                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6785                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6786                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6787                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
6788                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6789                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6790
6791                        // Sanity check that provider still belongs to source package
6792                        final ProviderInfo pi = getProviderInfoLocked(
6793                                uri.getAuthority(), sourceUserId);
6794                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6795                            int targetUid = -1;
6796                            try {
6797                                targetUid = AppGlobals.getPackageManager()
6798                                        .getPackageUid(targetPkg, targetUserId);
6799                            } catch (RemoteException e) {
6800                            }
6801                            if (targetUid != -1) {
6802                                final UriPermission perm = findOrCreateUriPermissionLocked(
6803                                        sourcePkg, targetPkg, targetUid,
6804                                        new GrantUri(sourceUserId, uri, prefix));
6805                                perm.initPersistedModes(modeFlags, createdTime);
6806                            }
6807                        } else {
6808                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6809                                    + " but instead found " + pi);
6810                        }
6811                    }
6812                }
6813            }
6814        } catch (FileNotFoundException e) {
6815            // Missing grants is okay
6816        } catch (IOException e) {
6817            Log.wtf(TAG, "Failed reading Uri grants", e);
6818        } catch (XmlPullParserException e) {
6819            Log.wtf(TAG, "Failed reading Uri grants", e);
6820        } finally {
6821            IoUtils.closeQuietly(fis);
6822        }
6823    }
6824
6825    @Override
6826    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6827        enforceNotIsolatedCaller("takePersistableUriPermission");
6828
6829        Preconditions.checkFlagsArgument(modeFlags,
6830                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6831
6832        synchronized (this) {
6833            final int callingUid = Binder.getCallingUid();
6834            boolean persistChanged = false;
6835            GrantUri grantUri = new GrantUri(userId, uri, false);
6836
6837            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6838                    new GrantUri(userId, uri, false));
6839            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6840                    new GrantUri(userId, uri, true));
6841
6842            final boolean exactValid = (exactPerm != null)
6843                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
6844            final boolean prefixValid = (prefixPerm != null)
6845                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
6846
6847            if (!(exactValid || prefixValid)) {
6848                throw new SecurityException("No persistable permission grants found for UID "
6849                        + callingUid + " and Uri " + grantUri.toSafeString());
6850            }
6851
6852            if (exactValid) {
6853                persistChanged |= exactPerm.takePersistableModes(modeFlags);
6854            }
6855            if (prefixValid) {
6856                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
6857            }
6858
6859            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6860
6861            if (persistChanged) {
6862                schedulePersistUriGrants();
6863            }
6864        }
6865    }
6866
6867    @Override
6868    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6869        enforceNotIsolatedCaller("releasePersistableUriPermission");
6870
6871        Preconditions.checkFlagsArgument(modeFlags,
6872                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6873
6874        synchronized (this) {
6875            final int callingUid = Binder.getCallingUid();
6876            boolean persistChanged = false;
6877
6878            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6879                    new GrantUri(userId, uri, false));
6880            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6881                    new GrantUri(userId, uri, true));
6882            if (exactPerm == null && prefixPerm == null) {
6883                throw new SecurityException("No permission grants found for UID " + callingUid
6884                        + " and Uri " + uri.toSafeString());
6885            }
6886
6887            if (exactPerm != null) {
6888                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
6889                removeUriPermissionIfNeededLocked(exactPerm);
6890            }
6891            if (prefixPerm != null) {
6892                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
6893                removeUriPermissionIfNeededLocked(prefixPerm);
6894            }
6895
6896            if (persistChanged) {
6897                schedulePersistUriGrants();
6898            }
6899        }
6900    }
6901
6902    /**
6903     * Prune any older {@link UriPermission} for the given UID until outstanding
6904     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6905     *
6906     * @return if any mutations occured that require persisting.
6907     */
6908    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6909        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6910        if (perms == null) return false;
6911        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6912
6913        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6914        for (UriPermission perm : perms.values()) {
6915            if (perm.persistedModeFlags != 0) {
6916                persisted.add(perm);
6917            }
6918        }
6919
6920        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6921        if (trimCount <= 0) return false;
6922
6923        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6924        for (int i = 0; i < trimCount; i++) {
6925            final UriPermission perm = persisted.get(i);
6926
6927            if (DEBUG_URI_PERMISSION) {
6928                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6929            }
6930
6931            perm.releasePersistableModes(~0);
6932            removeUriPermissionIfNeededLocked(perm);
6933        }
6934
6935        return true;
6936    }
6937
6938    @Override
6939    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6940            String packageName, boolean incoming) {
6941        enforceNotIsolatedCaller("getPersistedUriPermissions");
6942        Preconditions.checkNotNull(packageName, "packageName");
6943
6944        final int callingUid = Binder.getCallingUid();
6945        final IPackageManager pm = AppGlobals.getPackageManager();
6946        try {
6947            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6948            if (packageUid != callingUid) {
6949                throw new SecurityException(
6950                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6951            }
6952        } catch (RemoteException e) {
6953            throw new SecurityException("Failed to verify package name ownership");
6954        }
6955
6956        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6957        synchronized (this) {
6958            if (incoming) {
6959                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6960                        callingUid);
6961                if (perms == null) {
6962                    Slog.w(TAG, "No permission grants found for " + packageName);
6963                } else {
6964                    for (UriPermission perm : perms.values()) {
6965                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6966                            result.add(perm.buildPersistedPublicApiObject());
6967                        }
6968                    }
6969                }
6970            } else {
6971                final int size = mGrantedUriPermissions.size();
6972                for (int i = 0; i < size; i++) {
6973                    final ArrayMap<GrantUri, UriPermission> perms =
6974                            mGrantedUriPermissions.valueAt(i);
6975                    for (UriPermission perm : perms.values()) {
6976                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6977                            result.add(perm.buildPersistedPublicApiObject());
6978                        }
6979                    }
6980                }
6981            }
6982        }
6983        return new ParceledListSlice<android.content.UriPermission>(result);
6984    }
6985
6986    @Override
6987    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6988        synchronized (this) {
6989            ProcessRecord app =
6990                who != null ? getRecordForAppLocked(who) : null;
6991            if (app == null) return;
6992
6993            Message msg = Message.obtain();
6994            msg.what = WAIT_FOR_DEBUGGER_MSG;
6995            msg.obj = app;
6996            msg.arg1 = waiting ? 1 : 0;
6997            mHandler.sendMessage(msg);
6998        }
6999    }
7000
7001    @Override
7002    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7003        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7004        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7005        outInfo.availMem = Process.getFreeMemory();
7006        outInfo.totalMem = Process.getTotalMemory();
7007        outInfo.threshold = homeAppMem;
7008        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7009        outInfo.hiddenAppThreshold = cachedAppMem;
7010        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7011                ProcessList.SERVICE_ADJ);
7012        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7013                ProcessList.VISIBLE_APP_ADJ);
7014        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7015                ProcessList.FOREGROUND_APP_ADJ);
7016    }
7017
7018    // =========================================================
7019    // TASK MANAGEMENT
7020    // =========================================================
7021
7022    @Override
7023    public List<IAppTask> getAppTasks() {
7024        int callingUid = Binder.getCallingUid();
7025        long ident = Binder.clearCallingIdentity();
7026        synchronized(this) {
7027            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7028            try {
7029                if (localLOGV) Slog.v(TAG, "getAppTasks");
7030
7031                final int N = mRecentTasks.size();
7032                for (int i = 0; i < N; i++) {
7033                    TaskRecord tr = mRecentTasks.get(i);
7034                    // Skip tasks that are not created by the caller
7035                    if (tr.creatorUid == callingUid) {
7036                        ActivityManager.RecentTaskInfo taskInfo =
7037                                createRecentTaskInfoFromTaskRecord(tr);
7038                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7039                        list.add(taskImpl);
7040                    }
7041                }
7042            } finally {
7043                Binder.restoreCallingIdentity(ident);
7044            }
7045            return list;
7046        }
7047    }
7048
7049    @Override
7050    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7051        final int callingUid = Binder.getCallingUid();
7052        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7053
7054        synchronized(this) {
7055            if (localLOGV) Slog.v(
7056                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7057
7058            final boolean allowed = checkCallingPermission(
7059                    android.Manifest.permission.GET_TASKS)
7060                    == PackageManager.PERMISSION_GRANTED;
7061            if (!allowed) {
7062                Slog.w(TAG, "getTasks: caller " + callingUid
7063                        + " does not hold GET_TASKS; limiting output");
7064            }
7065
7066            // TODO: Improve with MRU list from all ActivityStacks.
7067            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7068        }
7069
7070        return list;
7071    }
7072
7073    TaskRecord getMostRecentTask() {
7074        return mRecentTasks.get(0);
7075    }
7076
7077    /**
7078     * Creates a new RecentTaskInfo from a TaskRecord.
7079     */
7080    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7081        ActivityManager.RecentTaskInfo rti
7082                = new ActivityManager.RecentTaskInfo();
7083        rti.id = tr.numActivities > 0 ? tr.taskId : -1;
7084        rti.persistentId = tr.taskId;
7085        rti.baseIntent = new Intent(tr.getBaseIntent());
7086        rti.origActivity = tr.origActivity;
7087        rti.description = tr.lastDescription;
7088        rti.stackId = tr.stack.mStackId;
7089        rti.userId = tr.userId;
7090        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7091        return rti;
7092    }
7093
7094    @Override
7095    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
7096            int flags, int userId) {
7097        final int callingUid = Binder.getCallingUid();
7098        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7099                false, true, "getRecentTasks", null);
7100
7101        synchronized (this) {
7102            final boolean allowed = checkCallingPermission(
7103                    android.Manifest.permission.GET_TASKS)
7104                    == PackageManager.PERMISSION_GRANTED;
7105            if (!allowed) {
7106                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7107                        + " does not hold GET_TASKS; limiting output");
7108            }
7109            final boolean detailed = checkCallingPermission(
7110                    android.Manifest.permission.GET_DETAILED_TASKS)
7111                    == PackageManager.PERMISSION_GRANTED;
7112
7113            IPackageManager pm = AppGlobals.getPackageManager();
7114
7115            final int N = mRecentTasks.size();
7116            ArrayList<ActivityManager.RecentTaskInfo> res
7117                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7118                            maxNum < N ? maxNum : N);
7119
7120            final Set<Integer> includedUsers;
7121            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
7122                includedUsers = getProfileIdsLocked(userId);
7123            } else {
7124                includedUsers = new HashSet<Integer>();
7125            }
7126            includedUsers.add(Integer.valueOf(userId));
7127            for (int i=0; i<N && maxNum > 0; i++) {
7128                TaskRecord tr = mRecentTasks.get(i);
7129                // Only add calling user or related users recent tasks
7130                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7131
7132                // Return the entry if desired by the caller.  We always return
7133                // the first entry, because callers always expect this to be the
7134                // foreground app.  We may filter others if the caller has
7135                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7136                // we should exclude the entry.
7137
7138                if (i == 0
7139                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
7140                        || (tr.intent == null)
7141                        || ((tr.intent.getFlags()
7142                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
7143                    if (!allowed) {
7144                        // If the caller doesn't have the GET_TASKS permission, then only
7145                        // allow them to see a small subset of tasks -- their own and home.
7146                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7147                            continue;
7148                        }
7149                    }
7150
7151                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7152                    if (!detailed) {
7153                        rti.baseIntent.replaceExtras((Bundle)null);
7154                    }
7155
7156                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7157                        // Check whether this activity is currently available.
7158                        try {
7159                            if (rti.origActivity != null) {
7160                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7161                                        == null) {
7162                                    continue;
7163                                }
7164                            } else if (rti.baseIntent != null) {
7165                                if (pm.queryIntentActivities(rti.baseIntent,
7166                                        null, 0, userId) == null) {
7167                                    continue;
7168                                }
7169                            }
7170                        } catch (RemoteException e) {
7171                            // Will never happen.
7172                        }
7173                    }
7174
7175                    res.add(rti);
7176                    maxNum--;
7177                }
7178            }
7179            return res;
7180        }
7181    }
7182
7183    private TaskRecord recentTaskForIdLocked(int id) {
7184        final int N = mRecentTasks.size();
7185            for (int i=0; i<N; i++) {
7186                TaskRecord tr = mRecentTasks.get(i);
7187                if (tr.taskId == id) {
7188                    return tr;
7189                }
7190            }
7191            return null;
7192    }
7193
7194    @Override
7195    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
7196        synchronized (this) {
7197            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7198                    "getTaskThumbnails()");
7199            TaskRecord tr = recentTaskForIdLocked(id);
7200            if (tr != null) {
7201                return tr.getTaskThumbnailsLocked();
7202            }
7203        }
7204        return null;
7205    }
7206
7207    @Override
7208    public Bitmap getTaskTopThumbnail(int id) {
7209        synchronized (this) {
7210            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7211                    "getTaskTopThumbnail()");
7212            TaskRecord tr = recentTaskForIdLocked(id);
7213            if (tr != null) {
7214                return tr.getTaskTopThumbnailLocked();
7215            }
7216        }
7217        return null;
7218    }
7219
7220    @Override
7221    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7222        synchronized (this) {
7223            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7224            if (r != null) {
7225                r.taskDescription = td;
7226                r.task.updateTaskDescription();
7227            }
7228        }
7229    }
7230
7231    @Override
7232    public boolean removeSubTask(int taskId, int subTaskIndex) {
7233        synchronized (this) {
7234            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7235                    "removeSubTask()");
7236            long ident = Binder.clearCallingIdentity();
7237            try {
7238                TaskRecord tr = recentTaskForIdLocked(taskId);
7239                if (tr != null) {
7240                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
7241                }
7242                return false;
7243            } finally {
7244                Binder.restoreCallingIdentity(ident);
7245            }
7246        }
7247    }
7248
7249    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7250        if (!pr.killedByAm) {
7251            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7252            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7253                    pr.processName, pr.setAdj, reason);
7254            pr.killedByAm = true;
7255            Process.killProcessQuiet(pr.pid);
7256        }
7257    }
7258
7259    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7260        tr.disposeThumbnail();
7261        mRecentTasks.remove(tr);
7262        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7263        Intent baseIntent = new Intent(
7264                tr.intent != null ? tr.intent : tr.affinityIntent);
7265        ComponentName component = baseIntent.getComponent();
7266        if (component == null) {
7267            Slog.w(TAG, "Now component for base intent of task: " + tr);
7268            return;
7269        }
7270
7271        // Find any running services associated with this app.
7272        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7273
7274        if (killProcesses) {
7275            // Find any running processes associated with this app.
7276            final String pkg = component.getPackageName();
7277            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7278            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7279            for (int i=0; i<pmap.size(); i++) {
7280                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7281                for (int j=0; j<uids.size(); j++) {
7282                    ProcessRecord proc = uids.valueAt(j);
7283                    if (proc.userId != tr.userId) {
7284                        continue;
7285                    }
7286                    if (!proc.pkgList.containsKey(pkg)) {
7287                        continue;
7288                    }
7289                    procs.add(proc);
7290                }
7291            }
7292
7293            // Kill the running processes.
7294            for (int i=0; i<procs.size(); i++) {
7295                ProcessRecord pr = procs.get(i);
7296                if (pr == mHomeProcess) {
7297                    // Don't kill the home process along with tasks from the same package.
7298                    continue;
7299                }
7300                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7301                    killUnneededProcessLocked(pr, "remove task");
7302                } else {
7303                    pr.waitingToKill = "remove task";
7304                }
7305            }
7306        }
7307    }
7308
7309    /**
7310     * Removes the task with the specified task id.
7311     *
7312     * @param taskId Identifier of the task to be removed.
7313     * @param flags Additional operational flags.  May be 0 or
7314     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7315     * @return Returns true if the given task was found and removed.
7316     */
7317    private boolean removeTaskByIdLocked(int taskId, int flags) {
7318        TaskRecord tr = recentTaskForIdLocked(taskId);
7319        if (tr != null) {
7320            tr.removeTaskActivitiesLocked(-1, false);
7321            cleanUpRemovedTaskLocked(tr, flags);
7322            return true;
7323        }
7324        return false;
7325    }
7326
7327    @Override
7328    public boolean removeTask(int taskId, int flags) {
7329        synchronized (this) {
7330            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7331                    "removeTask()");
7332            long ident = Binder.clearCallingIdentity();
7333            try {
7334                return removeTaskByIdLocked(taskId, flags);
7335            } finally {
7336                Binder.restoreCallingIdentity(ident);
7337            }
7338        }
7339    }
7340
7341    /**
7342     * TODO: Add mController hook
7343     */
7344    @Override
7345    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7346        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7347                "moveTaskToFront()");
7348
7349        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7350        synchronized(this) {
7351            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7352                    Binder.getCallingUid(), "Task to front")) {
7353                ActivityOptions.abort(options);
7354                return;
7355            }
7356            final long origId = Binder.clearCallingIdentity();
7357            try {
7358                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7359                if (task == null) {
7360                    return;
7361                }
7362                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7363                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7364                    return;
7365                }
7366                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7367            } finally {
7368                Binder.restoreCallingIdentity(origId);
7369            }
7370            ActivityOptions.abort(options);
7371        }
7372    }
7373
7374    @Override
7375    public void moveTaskToBack(int taskId) {
7376        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7377                "moveTaskToBack()");
7378
7379        synchronized(this) {
7380            TaskRecord tr = recentTaskForIdLocked(taskId);
7381            if (tr != null) {
7382                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7383                ActivityStack stack = tr.stack;
7384                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7385                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7386                            Binder.getCallingUid(), "Task to back")) {
7387                        return;
7388                    }
7389                }
7390                final long origId = Binder.clearCallingIdentity();
7391                try {
7392                    stack.moveTaskToBackLocked(taskId, null);
7393                } finally {
7394                    Binder.restoreCallingIdentity(origId);
7395                }
7396            }
7397        }
7398    }
7399
7400    /**
7401     * Moves an activity, and all of the other activities within the same task, to the bottom
7402     * of the history stack.  The activity's order within the task is unchanged.
7403     *
7404     * @param token A reference to the activity we wish to move
7405     * @param nonRoot If false then this only works if the activity is the root
7406     *                of a task; if true it will work for any activity in a task.
7407     * @return Returns true if the move completed, false if not.
7408     */
7409    @Override
7410    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7411        enforceNotIsolatedCaller("moveActivityTaskToBack");
7412        synchronized(this) {
7413            final long origId = Binder.clearCallingIdentity();
7414            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7415            if (taskId >= 0) {
7416                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7417            }
7418            Binder.restoreCallingIdentity(origId);
7419        }
7420        return false;
7421    }
7422
7423    @Override
7424    public void moveTaskBackwards(int task) {
7425        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7426                "moveTaskBackwards()");
7427
7428        synchronized(this) {
7429            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7430                    Binder.getCallingUid(), "Task backwards")) {
7431                return;
7432            }
7433            final long origId = Binder.clearCallingIdentity();
7434            moveTaskBackwardsLocked(task);
7435            Binder.restoreCallingIdentity(origId);
7436        }
7437    }
7438
7439    private final void moveTaskBackwardsLocked(int task) {
7440        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7441    }
7442
7443    @Override
7444    public IBinder getHomeActivityToken() throws RemoteException {
7445        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7446                "getHomeActivityToken()");
7447        synchronized (this) {
7448            return mStackSupervisor.getHomeActivityToken();
7449        }
7450    }
7451
7452    @Override
7453    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7454            IActivityContainerCallback callback) throws RemoteException {
7455        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7456                "createActivityContainer()");
7457        synchronized (this) {
7458            if (parentActivityToken == null) {
7459                throw new IllegalArgumentException("parent token must not be null");
7460            }
7461            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7462            if (r == null) {
7463                return null;
7464            }
7465            if (callback == null) {
7466                throw new IllegalArgumentException("callback must not be null");
7467            }
7468            return mStackSupervisor.createActivityContainer(r, callback);
7469        }
7470    }
7471
7472    @Override
7473    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7474        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7475                "deleteActivityContainer()");
7476        synchronized (this) {
7477            mStackSupervisor.deleteActivityContainer(container);
7478        }
7479    }
7480
7481    @Override
7482    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7483            throws RemoteException {
7484        synchronized (this) {
7485            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7486            if (stack != null) {
7487                return stack.mActivityContainer;
7488            }
7489            return null;
7490        }
7491    }
7492
7493    @Override
7494    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7495        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7496                "moveTaskToStack()");
7497        if (stackId == HOME_STACK_ID) {
7498            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7499                    new RuntimeException("here").fillInStackTrace());
7500        }
7501        synchronized (this) {
7502            long ident = Binder.clearCallingIdentity();
7503            try {
7504                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7505                        + stackId + " toTop=" + toTop);
7506                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7507            } finally {
7508                Binder.restoreCallingIdentity(ident);
7509            }
7510        }
7511    }
7512
7513    @Override
7514    public void resizeStack(int stackBoxId, Rect bounds) {
7515        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7516                "resizeStackBox()");
7517        long ident = Binder.clearCallingIdentity();
7518        try {
7519            mWindowManager.resizeStack(stackBoxId, bounds);
7520        } finally {
7521            Binder.restoreCallingIdentity(ident);
7522        }
7523    }
7524
7525    @Override
7526    public List<StackInfo> getAllStackInfos() {
7527        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7528                "getAllStackInfos()");
7529        long ident = Binder.clearCallingIdentity();
7530        try {
7531            synchronized (this) {
7532                return mStackSupervisor.getAllStackInfosLocked();
7533            }
7534        } finally {
7535            Binder.restoreCallingIdentity(ident);
7536        }
7537    }
7538
7539    @Override
7540    public StackInfo getStackInfo(int stackId) {
7541        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7542                "getStackInfo()");
7543        long ident = Binder.clearCallingIdentity();
7544        try {
7545            synchronized (this) {
7546                return mStackSupervisor.getStackInfoLocked(stackId);
7547            }
7548        } finally {
7549            Binder.restoreCallingIdentity(ident);
7550        }
7551    }
7552
7553    @Override
7554    public boolean isInHomeStack(int taskId) {
7555        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7556                "getStackInfo()");
7557        long ident = Binder.clearCallingIdentity();
7558        try {
7559            synchronized (this) {
7560                TaskRecord tr = recentTaskForIdLocked(taskId);
7561                if (tr != null) {
7562                    return tr.stack.isHomeStack();
7563                }
7564            }
7565        } finally {
7566            Binder.restoreCallingIdentity(ident);
7567        }
7568        return false;
7569    }
7570
7571    @Override
7572    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7573        synchronized(this) {
7574            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7575        }
7576    }
7577
7578    private boolean isLockTaskAuthorized(ComponentName name) {
7579//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7580//                "startLockTaskMode()");
7581//        DevicePolicyManager dpm = (DevicePolicyManager)
7582//                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7583//        return dpm != null && dpm.isLockTaskPermitted(name);
7584        return true;
7585    }
7586
7587    private void startLockTaskMode(TaskRecord task) {
7588        if (!isLockTaskAuthorized(task.intent.getComponent())) {
7589            return;
7590        }
7591        long ident = Binder.clearCallingIdentity();
7592        try {
7593            synchronized (this) {
7594                // Since we lost lock on task, make sure it is still there.
7595                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7596                if (task != null) {
7597                    mStackSupervisor.setLockTaskModeLocked(task);
7598                }
7599            }
7600        } finally {
7601            Binder.restoreCallingIdentity(ident);
7602        }
7603    }
7604
7605    @Override
7606    public void startLockTaskMode(int taskId) {
7607        long ident = Binder.clearCallingIdentity();
7608        try {
7609            final TaskRecord task;
7610            synchronized (this) {
7611                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7612            }
7613            if (task != null) {
7614                startLockTaskMode(task);
7615            }
7616        } finally {
7617            Binder.restoreCallingIdentity(ident);
7618        }
7619    }
7620
7621    @Override
7622    public void startLockTaskMode(IBinder token) {
7623        long ident = Binder.clearCallingIdentity();
7624        try {
7625            final TaskRecord task;
7626            synchronized (this) {
7627                final ActivityRecord r = ActivityRecord.forToken(token);
7628                if (r == null) {
7629                    return;
7630                }
7631                task = r.task;
7632            }
7633            if (task != null) {
7634                startLockTaskMode(task);
7635            }
7636        } finally {
7637            Binder.restoreCallingIdentity(ident);
7638        }
7639    }
7640
7641    @Override
7642    public void stopLockTaskMode() {
7643//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7644//                "stopLockTaskMode()");
7645        synchronized (this) {
7646            mStackSupervisor.setLockTaskModeLocked(null);
7647        }
7648    }
7649
7650    @Override
7651    public boolean isInLockTaskMode() {
7652        synchronized (this) {
7653            return mStackSupervisor.isInLockTaskMode();
7654        }
7655    }
7656
7657    // =========================================================
7658    // CONTENT PROVIDERS
7659    // =========================================================
7660
7661    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7662        List<ProviderInfo> providers = null;
7663        try {
7664            providers = AppGlobals.getPackageManager().
7665                queryContentProviders(app.processName, app.uid,
7666                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7667        } catch (RemoteException ex) {
7668        }
7669        if (DEBUG_MU)
7670            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7671        int userId = app.userId;
7672        if (providers != null) {
7673            int N = providers.size();
7674            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7675            for (int i=0; i<N; i++) {
7676                ProviderInfo cpi =
7677                    (ProviderInfo)providers.get(i);
7678                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7679                        cpi.name, cpi.flags);
7680                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7681                    // This is a singleton provider, but a user besides the
7682                    // default user is asking to initialize a process it runs
7683                    // in...  well, no, it doesn't actually run in this process,
7684                    // it runs in the process of the default user.  Get rid of it.
7685                    providers.remove(i);
7686                    N--;
7687                    i--;
7688                    continue;
7689                }
7690
7691                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7692                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7693                if (cpr == null) {
7694                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7695                    mProviderMap.putProviderByClass(comp, cpr);
7696                }
7697                if (DEBUG_MU)
7698                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7699                app.pubProviders.put(cpi.name, cpr);
7700                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7701                    // Don't add this if it is a platform component that is marked
7702                    // to run in multiple processes, because this is actually
7703                    // part of the framework so doesn't make sense to track as a
7704                    // separate apk in the process.
7705                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7706                }
7707                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7708            }
7709        }
7710        return providers;
7711    }
7712
7713    /**
7714     * Check if {@link ProcessRecord} has a possible chance at accessing the
7715     * given {@link ProviderInfo}. Final permission checking is always done
7716     * in {@link ContentProvider}.
7717     */
7718    private final String checkContentProviderPermissionLocked(
7719            ProviderInfo cpi, ProcessRecord r, int userId) {
7720        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7721        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7722        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7723        // Looking for cross-user grants before to enforce the typical cross-users permissions
7724        if (userId != UserHandle.getUserId(callingUid)) {
7725            if (perms != null) {
7726                for (GrantUri grantUri : perms.keySet()) {
7727                    if (grantUri.sourceUserId == userId) {
7728                        String authority = grantUri.uri.getAuthority();
7729                        if (authority.equals(cpi.authority)) {
7730                            return null;
7731                        }
7732                    }
7733                }
7734            }
7735        }
7736        userId = handleIncomingUser(callingPid, callingUid, userId,
7737                false, true, "checkContentProviderPermissionLocked", null);
7738        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7739                cpi.applicationInfo.uid, cpi.exported)
7740                == PackageManager.PERMISSION_GRANTED) {
7741            return null;
7742        }
7743        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7744                cpi.applicationInfo.uid, cpi.exported)
7745                == PackageManager.PERMISSION_GRANTED) {
7746            return null;
7747        }
7748
7749        PathPermission[] pps = cpi.pathPermissions;
7750        if (pps != null) {
7751            int i = pps.length;
7752            while (i > 0) {
7753                i--;
7754                PathPermission pp = pps[i];
7755                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7756                        cpi.applicationInfo.uid, cpi.exported)
7757                        == PackageManager.PERMISSION_GRANTED) {
7758                    return null;
7759                }
7760                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7761                        cpi.applicationInfo.uid, cpi.exported)
7762                        == PackageManager.PERMISSION_GRANTED) {
7763                    return null;
7764                }
7765            }
7766        }
7767
7768        if (perms != null) {
7769            for (GrantUri grantUri : perms.keySet()) {
7770                if (grantUri.uri.getAuthority().equals(cpi.authority)) {
7771                    return null;
7772                }
7773            }
7774        }
7775
7776        String msg;
7777        if (!cpi.exported) {
7778            msg = "Permission Denial: opening provider " + cpi.name
7779                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7780                    + ", uid=" + callingUid + ") that is not exported from uid "
7781                    + cpi.applicationInfo.uid;
7782        } else {
7783            msg = "Permission Denial: opening provider " + cpi.name
7784                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7785                    + ", uid=" + callingUid + ") requires "
7786                    + cpi.readPermission + " or " + cpi.writePermission;
7787        }
7788        Slog.w(TAG, msg);
7789        return msg;
7790    }
7791
7792    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7793            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7794        if (r != null) {
7795            for (int i=0; i<r.conProviders.size(); i++) {
7796                ContentProviderConnection conn = r.conProviders.get(i);
7797                if (conn.provider == cpr) {
7798                    if (DEBUG_PROVIDER) Slog.v(TAG,
7799                            "Adding provider requested by "
7800                            + r.processName + " from process "
7801                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7802                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7803                    if (stable) {
7804                        conn.stableCount++;
7805                        conn.numStableIncs++;
7806                    } else {
7807                        conn.unstableCount++;
7808                        conn.numUnstableIncs++;
7809                    }
7810                    return conn;
7811                }
7812            }
7813            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7814            if (stable) {
7815                conn.stableCount = 1;
7816                conn.numStableIncs = 1;
7817            } else {
7818                conn.unstableCount = 1;
7819                conn.numUnstableIncs = 1;
7820            }
7821            cpr.connections.add(conn);
7822            r.conProviders.add(conn);
7823            return conn;
7824        }
7825        cpr.addExternalProcessHandleLocked(externalProcessToken);
7826        return null;
7827    }
7828
7829    boolean decProviderCountLocked(ContentProviderConnection conn,
7830            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7831        if (conn != null) {
7832            cpr = conn.provider;
7833            if (DEBUG_PROVIDER) Slog.v(TAG,
7834                    "Removing provider requested by "
7835                    + conn.client.processName + " from process "
7836                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7837                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7838            if (stable) {
7839                conn.stableCount--;
7840            } else {
7841                conn.unstableCount--;
7842            }
7843            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7844                cpr.connections.remove(conn);
7845                conn.client.conProviders.remove(conn);
7846                return true;
7847            }
7848            return false;
7849        }
7850        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7851        return false;
7852    }
7853
7854    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7855            String name, IBinder token, boolean stable, int userId) {
7856        ContentProviderRecord cpr;
7857        ContentProviderConnection conn = null;
7858        ProviderInfo cpi = null;
7859
7860        synchronized(this) {
7861            ProcessRecord r = null;
7862            if (caller != null) {
7863                r = getRecordForAppLocked(caller);
7864                if (r == null) {
7865                    throw new SecurityException(
7866                            "Unable to find app for caller " + caller
7867                          + " (pid=" + Binder.getCallingPid()
7868                          + ") when getting content provider " + name);
7869                }
7870            }
7871
7872            // First check if this content provider has been published...
7873            cpr = mProviderMap.getProviderByName(name, userId);
7874            boolean providerRunning = cpr != null;
7875            if (providerRunning) {
7876                cpi = cpr.info;
7877                String msg;
7878                if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) {
7879                    throw new SecurityException(msg);
7880                }
7881
7882                if (r != null && cpr.canRunHere(r)) {
7883                    // This provider has been published or is in the process
7884                    // of being published...  but it is also allowed to run
7885                    // in the caller's process, so don't make a connection
7886                    // and just let the caller instantiate its own instance.
7887                    ContentProviderHolder holder = cpr.newHolder(null);
7888                    // don't give caller the provider object, it needs
7889                    // to make its own.
7890                    holder.provider = null;
7891                    return holder;
7892                }
7893
7894                final long origId = Binder.clearCallingIdentity();
7895
7896                // In this case the provider instance already exists, so we can
7897                // return it right away.
7898                conn = incProviderCountLocked(r, cpr, token, stable);
7899                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7900                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7901                        // If this is a perceptible app accessing the provider,
7902                        // make sure to count it as being accessed and thus
7903                        // back up on the LRU list.  This is good because
7904                        // content providers are often expensive to start.
7905                        updateLruProcessLocked(cpr.proc, false, null);
7906                    }
7907                }
7908
7909                if (cpr.proc != null) {
7910                    if (false) {
7911                        if (cpr.name.flattenToShortString().equals(
7912                                "com.android.providers.calendar/.CalendarProvider2")) {
7913                            Slog.v(TAG, "****************** KILLING "
7914                                + cpr.name.flattenToShortString());
7915                            Process.killProcess(cpr.proc.pid);
7916                        }
7917                    }
7918                    boolean success = updateOomAdjLocked(cpr.proc);
7919                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7920                    // NOTE: there is still a race here where a signal could be
7921                    // pending on the process even though we managed to update its
7922                    // adj level.  Not sure what to do about this, but at least
7923                    // the race is now smaller.
7924                    if (!success) {
7925                        // Uh oh...  it looks like the provider's process
7926                        // has been killed on us.  We need to wait for a new
7927                        // process to be started, and make sure its death
7928                        // doesn't kill our process.
7929                        Slog.i(TAG,
7930                                "Existing provider " + cpr.name.flattenToShortString()
7931                                + " is crashing; detaching " + r);
7932                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7933                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7934                        if (!lastRef) {
7935                            // This wasn't the last ref our process had on
7936                            // the provider...  we have now been killed, bail.
7937                            return null;
7938                        }
7939                        providerRunning = false;
7940                        conn = null;
7941                    }
7942                }
7943
7944                Binder.restoreCallingIdentity(origId);
7945            }
7946
7947            boolean singleton;
7948            if (!providerRunning) {
7949                try {
7950                    cpi = AppGlobals.getPackageManager().
7951                        resolveContentProvider(name,
7952                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7953                } catch (RemoteException ex) {
7954                }
7955                if (cpi == null) {
7956                    return null;
7957                }
7958                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7959                        cpi.name, cpi.flags);
7960                if (singleton) {
7961                    userId = 0;
7962                }
7963                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7964
7965                String msg;
7966                if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) {
7967                    throw new SecurityException(msg);
7968                }
7969
7970                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
7971                        && !cpi.processName.equals("system")) {
7972                    // If this content provider does not run in the system
7973                    // process, and the system is not yet ready to run other
7974                    // processes, then fail fast instead of hanging.
7975                    throw new IllegalArgumentException(
7976                            "Attempt to launch content provider before system ready");
7977                }
7978
7979                // Make sure that the user who owns this provider is started.  If not,
7980                // we don't want to allow it to run.
7981                if (mStartedUsers.get(userId) == null) {
7982                    Slog.w(TAG, "Unable to launch app "
7983                            + cpi.applicationInfo.packageName + "/"
7984                            + cpi.applicationInfo.uid + " for provider "
7985                            + name + ": user " + userId + " is stopped");
7986                    return null;
7987                }
7988
7989                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7990                cpr = mProviderMap.getProviderByClass(comp, userId);
7991                final boolean firstClass = cpr == null;
7992                if (firstClass) {
7993                    try {
7994                        ApplicationInfo ai =
7995                            AppGlobals.getPackageManager().
7996                                getApplicationInfo(
7997                                        cpi.applicationInfo.packageName,
7998                                        STOCK_PM_FLAGS, userId);
7999                        if (ai == null) {
8000                            Slog.w(TAG, "No package info for content provider "
8001                                    + cpi.name);
8002                            return null;
8003                        }
8004                        ai = getAppInfoForUser(ai, userId);
8005                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8006                    } catch (RemoteException ex) {
8007                        // pm is in same process, this will never happen.
8008                    }
8009                }
8010
8011                if (r != null && cpr.canRunHere(r)) {
8012                    // If this is a multiprocess provider, then just return its
8013                    // info and allow the caller to instantiate it.  Only do
8014                    // this if the provider is the same user as the caller's
8015                    // process, or can run as root (so can be in any process).
8016                    return cpr.newHolder(null);
8017                }
8018
8019                if (DEBUG_PROVIDER) {
8020                    RuntimeException e = new RuntimeException("here");
8021                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8022                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8023                }
8024
8025                // This is single process, and our app is now connecting to it.
8026                // See if we are already in the process of launching this
8027                // provider.
8028                final int N = mLaunchingProviders.size();
8029                int i;
8030                for (i=0; i<N; i++) {
8031                    if (mLaunchingProviders.get(i) == cpr) {
8032                        break;
8033                    }
8034                }
8035
8036                // If the provider is not already being launched, then get it
8037                // started.
8038                if (i >= N) {
8039                    final long origId = Binder.clearCallingIdentity();
8040
8041                    try {
8042                        // Content provider is now in use, its package can't be stopped.
8043                        try {
8044                            AppGlobals.getPackageManager().setPackageStoppedState(
8045                                    cpr.appInfo.packageName, false, userId);
8046                        } catch (RemoteException e) {
8047                        } catch (IllegalArgumentException e) {
8048                            Slog.w(TAG, "Failed trying to unstop package "
8049                                    + cpr.appInfo.packageName + ": " + e);
8050                        }
8051
8052                        // Use existing process if already started
8053                        ProcessRecord proc = getProcessRecordLocked(
8054                                cpi.processName, cpr.appInfo.uid, false);
8055                        if (proc != null && proc.thread != null) {
8056                            if (DEBUG_PROVIDER) {
8057                                Slog.d(TAG, "Installing in existing process " + proc);
8058                            }
8059                            proc.pubProviders.put(cpi.name, cpr);
8060                            try {
8061                                proc.thread.scheduleInstallProvider(cpi);
8062                            } catch (RemoteException e) {
8063                            }
8064                        } else {
8065                            proc = startProcessLocked(cpi.processName,
8066                                    cpr.appInfo, false, 0, "content provider",
8067                                    new ComponentName(cpi.applicationInfo.packageName,
8068                                            cpi.name), false, false, false);
8069                            if (proc == null) {
8070                                Slog.w(TAG, "Unable to launch app "
8071                                        + cpi.applicationInfo.packageName + "/"
8072                                        + cpi.applicationInfo.uid + " for provider "
8073                                        + name + ": process is bad");
8074                                return null;
8075                            }
8076                        }
8077                        cpr.launchingApp = proc;
8078                        mLaunchingProviders.add(cpr);
8079                    } finally {
8080                        Binder.restoreCallingIdentity(origId);
8081                    }
8082                }
8083
8084                // Make sure the provider is published (the same provider class
8085                // may be published under multiple names).
8086                if (firstClass) {
8087                    mProviderMap.putProviderByClass(comp, cpr);
8088                }
8089
8090                mProviderMap.putProviderByName(name, cpr);
8091                conn = incProviderCountLocked(r, cpr, token, stable);
8092                if (conn != null) {
8093                    conn.waiting = true;
8094                }
8095            }
8096        }
8097
8098        // Wait for the provider to be published...
8099        synchronized (cpr) {
8100            while (cpr.provider == null) {
8101                if (cpr.launchingApp == null) {
8102                    Slog.w(TAG, "Unable to launch app "
8103                            + cpi.applicationInfo.packageName + "/"
8104                            + cpi.applicationInfo.uid + " for provider "
8105                            + name + ": launching app became null");
8106                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8107                            UserHandle.getUserId(cpi.applicationInfo.uid),
8108                            cpi.applicationInfo.packageName,
8109                            cpi.applicationInfo.uid, name);
8110                    return null;
8111                }
8112                try {
8113                    if (DEBUG_MU) {
8114                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8115                                + cpr.launchingApp);
8116                    }
8117                    if (conn != null) {
8118                        conn.waiting = true;
8119                    }
8120                    cpr.wait();
8121                } catch (InterruptedException ex) {
8122                } finally {
8123                    if (conn != null) {
8124                        conn.waiting = false;
8125                    }
8126                }
8127            }
8128        }
8129        return cpr != null ? cpr.newHolder(conn) : null;
8130    }
8131
8132    @Override
8133    public final ContentProviderHolder getContentProvider(
8134            IApplicationThread caller, String name, int userId, boolean stable) {
8135        enforceNotIsolatedCaller("getContentProvider");
8136        if (caller == null) {
8137            String msg = "null IApplicationThread when getting content provider "
8138                    + name;
8139            Slog.w(TAG, msg);
8140            throw new SecurityException(msg);
8141        }
8142        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8143        // with cross-user grant.
8144        return getContentProviderImpl(caller, name, null, stable, userId);
8145    }
8146
8147    public ContentProviderHolder getContentProviderExternal(
8148            String name, int userId, IBinder token) {
8149        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8150            "Do not have permission in call getContentProviderExternal()");
8151        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8152                false, true, "getContentProvider", null);
8153        return getContentProviderExternalUnchecked(name, token, userId);
8154    }
8155
8156    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8157            IBinder token, int userId) {
8158        return getContentProviderImpl(null, name, token, true, userId);
8159    }
8160
8161    /**
8162     * Drop a content provider from a ProcessRecord's bookkeeping
8163     */
8164    public void removeContentProvider(IBinder connection, boolean stable) {
8165        enforceNotIsolatedCaller("removeContentProvider");
8166        long ident = Binder.clearCallingIdentity();
8167        try {
8168            synchronized (this) {
8169                ContentProviderConnection conn;
8170                try {
8171                    conn = (ContentProviderConnection)connection;
8172                } catch (ClassCastException e) {
8173                    String msg ="removeContentProvider: " + connection
8174                            + " not a ContentProviderConnection";
8175                    Slog.w(TAG, msg);
8176                    throw new IllegalArgumentException(msg);
8177                }
8178                if (conn == null) {
8179                    throw new NullPointerException("connection is null");
8180                }
8181                if (decProviderCountLocked(conn, null, null, stable)) {
8182                    updateOomAdjLocked();
8183                }
8184            }
8185        } finally {
8186            Binder.restoreCallingIdentity(ident);
8187        }
8188    }
8189
8190    public void removeContentProviderExternal(String name, IBinder token) {
8191        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8192            "Do not have permission in call removeContentProviderExternal()");
8193        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8194    }
8195
8196    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8197        synchronized (this) {
8198            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8199            if(cpr == null) {
8200                //remove from mProvidersByClass
8201                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8202                return;
8203            }
8204
8205            //update content provider record entry info
8206            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8207            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8208            if (localCpr.hasExternalProcessHandles()) {
8209                if (localCpr.removeExternalProcessHandleLocked(token)) {
8210                    updateOomAdjLocked();
8211                } else {
8212                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8213                            + " with no external reference for token: "
8214                            + token + ".");
8215                }
8216            } else {
8217                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8218                        + " with no external references.");
8219            }
8220        }
8221    }
8222
8223    public final void publishContentProviders(IApplicationThread caller,
8224            List<ContentProviderHolder> providers) {
8225        if (providers == null) {
8226            return;
8227        }
8228
8229        enforceNotIsolatedCaller("publishContentProviders");
8230        synchronized (this) {
8231            final ProcessRecord r = getRecordForAppLocked(caller);
8232            if (DEBUG_MU)
8233                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8234            if (r == null) {
8235                throw new SecurityException(
8236                        "Unable to find app for caller " + caller
8237                      + " (pid=" + Binder.getCallingPid()
8238                      + ") when publishing content providers");
8239            }
8240
8241            final long origId = Binder.clearCallingIdentity();
8242
8243            final int N = providers.size();
8244            for (int i=0; i<N; i++) {
8245                ContentProviderHolder src = providers.get(i);
8246                if (src == null || src.info == null || src.provider == null) {
8247                    continue;
8248                }
8249                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8250                if (DEBUG_MU)
8251                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8252                if (dst != null) {
8253                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8254                    mProviderMap.putProviderByClass(comp, dst);
8255                    String names[] = dst.info.authority.split(";");
8256                    for (int j = 0; j < names.length; j++) {
8257                        mProviderMap.putProviderByName(names[j], dst);
8258                    }
8259
8260                    int NL = mLaunchingProviders.size();
8261                    int j;
8262                    for (j=0; j<NL; j++) {
8263                        if (mLaunchingProviders.get(j) == dst) {
8264                            mLaunchingProviders.remove(j);
8265                            j--;
8266                            NL--;
8267                        }
8268                    }
8269                    synchronized (dst) {
8270                        dst.provider = src.provider;
8271                        dst.proc = r;
8272                        dst.notifyAll();
8273                    }
8274                    updateOomAdjLocked(r);
8275                }
8276            }
8277
8278            Binder.restoreCallingIdentity(origId);
8279        }
8280    }
8281
8282    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8283        ContentProviderConnection conn;
8284        try {
8285            conn = (ContentProviderConnection)connection;
8286        } catch (ClassCastException e) {
8287            String msg ="refContentProvider: " + connection
8288                    + " not a ContentProviderConnection";
8289            Slog.w(TAG, msg);
8290            throw new IllegalArgumentException(msg);
8291        }
8292        if (conn == null) {
8293            throw new NullPointerException("connection is null");
8294        }
8295
8296        synchronized (this) {
8297            if (stable > 0) {
8298                conn.numStableIncs += stable;
8299            }
8300            stable = conn.stableCount + stable;
8301            if (stable < 0) {
8302                throw new IllegalStateException("stableCount < 0: " + stable);
8303            }
8304
8305            if (unstable > 0) {
8306                conn.numUnstableIncs += unstable;
8307            }
8308            unstable = conn.unstableCount + unstable;
8309            if (unstable < 0) {
8310                throw new IllegalStateException("unstableCount < 0: " + unstable);
8311            }
8312
8313            if ((stable+unstable) <= 0) {
8314                throw new IllegalStateException("ref counts can't go to zero here: stable="
8315                        + stable + " unstable=" + unstable);
8316            }
8317            conn.stableCount = stable;
8318            conn.unstableCount = unstable;
8319            return !conn.dead;
8320        }
8321    }
8322
8323    public void unstableProviderDied(IBinder connection) {
8324        ContentProviderConnection conn;
8325        try {
8326            conn = (ContentProviderConnection)connection;
8327        } catch (ClassCastException e) {
8328            String msg ="refContentProvider: " + connection
8329                    + " not a ContentProviderConnection";
8330            Slog.w(TAG, msg);
8331            throw new IllegalArgumentException(msg);
8332        }
8333        if (conn == null) {
8334            throw new NullPointerException("connection is null");
8335        }
8336
8337        // Safely retrieve the content provider associated with the connection.
8338        IContentProvider provider;
8339        synchronized (this) {
8340            provider = conn.provider.provider;
8341        }
8342
8343        if (provider == null) {
8344            // Um, yeah, we're way ahead of you.
8345            return;
8346        }
8347
8348        // Make sure the caller is being honest with us.
8349        if (provider.asBinder().pingBinder()) {
8350            // Er, no, still looks good to us.
8351            synchronized (this) {
8352                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8353                        + " says " + conn + " died, but we don't agree");
8354                return;
8355            }
8356        }
8357
8358        // Well look at that!  It's dead!
8359        synchronized (this) {
8360            if (conn.provider.provider != provider) {
8361                // But something changed...  good enough.
8362                return;
8363            }
8364
8365            ProcessRecord proc = conn.provider.proc;
8366            if (proc == null || proc.thread == null) {
8367                // Seems like the process is already cleaned up.
8368                return;
8369            }
8370
8371            // As far as we're concerned, this is just like receiving a
8372            // death notification...  just a bit prematurely.
8373            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8374                    + ") early provider death");
8375            final long ident = Binder.clearCallingIdentity();
8376            try {
8377                appDiedLocked(proc, proc.pid, proc.thread);
8378            } finally {
8379                Binder.restoreCallingIdentity(ident);
8380            }
8381        }
8382    }
8383
8384    @Override
8385    public void appNotRespondingViaProvider(IBinder connection) {
8386        enforceCallingPermission(
8387                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8388
8389        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8390        if (conn == null) {
8391            Slog.w(TAG, "ContentProviderConnection is null");
8392            return;
8393        }
8394
8395        final ProcessRecord host = conn.provider.proc;
8396        if (host == null) {
8397            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8398            return;
8399        }
8400
8401        final long token = Binder.clearCallingIdentity();
8402        try {
8403            appNotResponding(host, null, null, false, "ContentProvider not responding");
8404        } finally {
8405            Binder.restoreCallingIdentity(token);
8406        }
8407    }
8408
8409    public final void installSystemProviders() {
8410        List<ProviderInfo> providers;
8411        synchronized (this) {
8412            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8413            providers = generateApplicationProvidersLocked(app);
8414            if (providers != null) {
8415                for (int i=providers.size()-1; i>=0; i--) {
8416                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8417                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8418                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8419                                + ": not system .apk");
8420                        providers.remove(i);
8421                    }
8422                }
8423            }
8424        }
8425        if (providers != null) {
8426            mSystemThread.installSystemProviders(providers);
8427        }
8428
8429        mCoreSettingsObserver = new CoreSettingsObserver(this);
8430
8431        mUsageStatsService.monitorPackages();
8432    }
8433
8434    /**
8435     * Allows app to retrieve the MIME type of a URI without having permission
8436     * to access its content provider.
8437     *
8438     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8439     *
8440     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8441     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8442     */
8443    public String getProviderMimeType(Uri uri, int userId) {
8444        enforceNotIsolatedCaller("getProviderMimeType");
8445        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8446                userId, false, true, "getProviderMimeType", null);
8447        final String name = uri.getAuthority();
8448        final long ident = Binder.clearCallingIdentity();
8449        ContentProviderHolder holder = null;
8450
8451        try {
8452            holder = getContentProviderExternalUnchecked(name, null, userId);
8453            if (holder != null) {
8454                return holder.provider.getType(uri);
8455            }
8456        } catch (RemoteException e) {
8457            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8458            return null;
8459        } finally {
8460            if (holder != null) {
8461                removeContentProviderExternalUnchecked(name, null, userId);
8462            }
8463            Binder.restoreCallingIdentity(ident);
8464        }
8465
8466        return null;
8467    }
8468
8469    // =========================================================
8470    // GLOBAL MANAGEMENT
8471    // =========================================================
8472
8473    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8474            boolean isolated) {
8475        String proc = customProcess != null ? customProcess : info.processName;
8476        BatteryStatsImpl.Uid.Proc ps = null;
8477        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8478        int uid = info.uid;
8479        if (isolated) {
8480            int userId = UserHandle.getUserId(uid);
8481            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8482            while (true) {
8483                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8484                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8485                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8486                }
8487                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8488                mNextIsolatedProcessUid++;
8489                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8490                    // No process for this uid, use it.
8491                    break;
8492                }
8493                stepsLeft--;
8494                if (stepsLeft <= 0) {
8495                    return null;
8496                }
8497            }
8498        }
8499        return new ProcessRecord(stats, info, proc, uid);
8500    }
8501
8502    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8503        ProcessRecord app;
8504        if (!isolated) {
8505            app = getProcessRecordLocked(info.processName, info.uid, true);
8506        } else {
8507            app = null;
8508        }
8509
8510        if (app == null) {
8511            app = newProcessRecordLocked(info, null, isolated);
8512            mProcessNames.put(info.processName, app.uid, app);
8513            if (isolated) {
8514                mIsolatedProcesses.put(app.uid, app);
8515            }
8516            updateLruProcessLocked(app, false, null);
8517            updateOomAdjLocked();
8518        }
8519
8520        // This package really, really can not be stopped.
8521        try {
8522            AppGlobals.getPackageManager().setPackageStoppedState(
8523                    info.packageName, false, UserHandle.getUserId(app.uid));
8524        } catch (RemoteException e) {
8525        } catch (IllegalArgumentException e) {
8526            Slog.w(TAG, "Failed trying to unstop package "
8527                    + info.packageName + ": " + e);
8528        }
8529
8530        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8531                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8532            app.persistent = true;
8533            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8534        }
8535        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8536            mPersistentStartingProcesses.add(app);
8537            startProcessLocked(app, "added application", app.processName);
8538        }
8539
8540        return app;
8541    }
8542
8543    public void unhandledBack() {
8544        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8545                "unhandledBack()");
8546
8547        synchronized(this) {
8548            final long origId = Binder.clearCallingIdentity();
8549            try {
8550                getFocusedStack().unhandledBackLocked();
8551            } finally {
8552                Binder.restoreCallingIdentity(origId);
8553            }
8554        }
8555    }
8556
8557    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8558        enforceNotIsolatedCaller("openContentUri");
8559        final int userId = UserHandle.getCallingUserId();
8560        String name = uri.getAuthority();
8561        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8562        ParcelFileDescriptor pfd = null;
8563        if (cph != null) {
8564            // We record the binder invoker's uid in thread-local storage before
8565            // going to the content provider to open the file.  Later, in the code
8566            // that handles all permissions checks, we look for this uid and use
8567            // that rather than the Activity Manager's own uid.  The effect is that
8568            // we do the check against the caller's permissions even though it looks
8569            // to the content provider like the Activity Manager itself is making
8570            // the request.
8571            sCallerIdentity.set(new Identity(
8572                    Binder.getCallingPid(), Binder.getCallingUid()));
8573            try {
8574                pfd = cph.provider.openFile(null, uri, "r", null);
8575            } catch (FileNotFoundException e) {
8576                // do nothing; pfd will be returned null
8577            } finally {
8578                // Ensure that whatever happens, we clean up the identity state
8579                sCallerIdentity.remove();
8580            }
8581
8582            // We've got the fd now, so we're done with the provider.
8583            removeContentProviderExternalUnchecked(name, null, userId);
8584        } else {
8585            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8586        }
8587        return pfd;
8588    }
8589
8590    // Actually is sleeping or shutting down or whatever else in the future
8591    // is an inactive state.
8592    public boolean isSleepingOrShuttingDown() {
8593        return mSleeping || mShuttingDown;
8594    }
8595
8596    public boolean isSleeping() {
8597        return mSleeping;
8598    }
8599
8600    void goingToSleep() {
8601        synchronized(this) {
8602            mWentToSleep = true;
8603            updateEventDispatchingLocked();
8604            goToSleepIfNeededLocked();
8605        }
8606    }
8607
8608    void finishRunningVoiceLocked() {
8609        if (mRunningVoice) {
8610            mRunningVoice = false;
8611            goToSleepIfNeededLocked();
8612        }
8613    }
8614
8615    void goToSleepIfNeededLocked() {
8616        if (mWentToSleep && !mRunningVoice) {
8617            if (!mSleeping) {
8618                mSleeping = true;
8619                mStackSupervisor.goingToSleepLocked();
8620
8621                // Initialize the wake times of all processes.
8622                checkExcessivePowerUsageLocked(false);
8623                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8624                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8625                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8626            }
8627        }
8628    }
8629
8630    @Override
8631    public boolean shutdown(int timeout) {
8632        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8633                != PackageManager.PERMISSION_GRANTED) {
8634            throw new SecurityException("Requires permission "
8635                    + android.Manifest.permission.SHUTDOWN);
8636        }
8637
8638        boolean timedout = false;
8639
8640        synchronized(this) {
8641            mShuttingDown = true;
8642            updateEventDispatchingLocked();
8643            timedout = mStackSupervisor.shutdownLocked(timeout);
8644        }
8645
8646        mAppOpsService.shutdown();
8647        mUsageStatsService.shutdown();
8648        mBatteryStatsService.shutdown();
8649        synchronized (this) {
8650            mProcessStats.shutdownLocked();
8651        }
8652
8653        return timedout;
8654    }
8655
8656    public final void activitySlept(IBinder token) {
8657        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8658
8659        final long origId = Binder.clearCallingIdentity();
8660
8661        synchronized (this) {
8662            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8663            if (r != null) {
8664                mStackSupervisor.activitySleptLocked(r);
8665            }
8666        }
8667
8668        Binder.restoreCallingIdentity(origId);
8669    }
8670
8671    void logLockScreen(String msg) {
8672        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8673                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8674                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8675                mStackSupervisor.mDismissKeyguardOnNextActivity);
8676    }
8677
8678    private void comeOutOfSleepIfNeededLocked() {
8679        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
8680            if (mSleeping) {
8681                mSleeping = false;
8682                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8683            }
8684        }
8685    }
8686
8687    void wakingUp() {
8688        synchronized(this) {
8689            mWentToSleep = false;
8690            updateEventDispatchingLocked();
8691            comeOutOfSleepIfNeededLocked();
8692        }
8693    }
8694
8695    void startRunningVoiceLocked() {
8696        if (!mRunningVoice) {
8697            mRunningVoice = true;
8698            comeOutOfSleepIfNeededLocked();
8699        }
8700    }
8701
8702    private void updateEventDispatchingLocked() {
8703        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8704    }
8705
8706    public void setLockScreenShown(boolean shown) {
8707        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8708                != PackageManager.PERMISSION_GRANTED) {
8709            throw new SecurityException("Requires permission "
8710                    + android.Manifest.permission.DEVICE_POWER);
8711        }
8712
8713        synchronized(this) {
8714            long ident = Binder.clearCallingIdentity();
8715            try {
8716                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8717                mLockScreenShown = shown;
8718                comeOutOfSleepIfNeededLocked();
8719            } finally {
8720                Binder.restoreCallingIdentity(ident);
8721            }
8722        }
8723    }
8724
8725    public void stopAppSwitches() {
8726        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8727                != PackageManager.PERMISSION_GRANTED) {
8728            throw new SecurityException("Requires permission "
8729                    + android.Manifest.permission.STOP_APP_SWITCHES);
8730        }
8731
8732        synchronized(this) {
8733            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8734                    + APP_SWITCH_DELAY_TIME;
8735            mDidAppSwitch = false;
8736            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8737            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8738            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8739        }
8740    }
8741
8742    public void resumeAppSwitches() {
8743        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8744                != PackageManager.PERMISSION_GRANTED) {
8745            throw new SecurityException("Requires permission "
8746                    + android.Manifest.permission.STOP_APP_SWITCHES);
8747        }
8748
8749        synchronized(this) {
8750            // Note that we don't execute any pending app switches... we will
8751            // let those wait until either the timeout, or the next start
8752            // activity request.
8753            mAppSwitchesAllowedTime = 0;
8754        }
8755    }
8756
8757    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8758            String name) {
8759        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8760            return true;
8761        }
8762
8763        final int perm = checkComponentPermission(
8764                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8765                callingUid, -1, true);
8766        if (perm == PackageManager.PERMISSION_GRANTED) {
8767            return true;
8768        }
8769
8770        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8771        return false;
8772    }
8773
8774    public void setDebugApp(String packageName, boolean waitForDebugger,
8775            boolean persistent) {
8776        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8777                "setDebugApp()");
8778
8779        long ident = Binder.clearCallingIdentity();
8780        try {
8781            // Note that this is not really thread safe if there are multiple
8782            // callers into it at the same time, but that's not a situation we
8783            // care about.
8784            if (persistent) {
8785                final ContentResolver resolver = mContext.getContentResolver();
8786                Settings.Global.putString(
8787                    resolver, Settings.Global.DEBUG_APP,
8788                    packageName);
8789                Settings.Global.putInt(
8790                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8791                    waitForDebugger ? 1 : 0);
8792            }
8793
8794            synchronized (this) {
8795                if (!persistent) {
8796                    mOrigDebugApp = mDebugApp;
8797                    mOrigWaitForDebugger = mWaitForDebugger;
8798                }
8799                mDebugApp = packageName;
8800                mWaitForDebugger = waitForDebugger;
8801                mDebugTransient = !persistent;
8802                if (packageName != null) {
8803                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8804                            false, UserHandle.USER_ALL, "set debug app");
8805                }
8806            }
8807        } finally {
8808            Binder.restoreCallingIdentity(ident);
8809        }
8810    }
8811
8812    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8813        synchronized (this) {
8814            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8815            if (!isDebuggable) {
8816                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8817                    throw new SecurityException("Process not debuggable: " + app.packageName);
8818                }
8819            }
8820
8821            mOpenGlTraceApp = processName;
8822        }
8823    }
8824
8825    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8826            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8827        synchronized (this) {
8828            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8829            if (!isDebuggable) {
8830                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8831                    throw new SecurityException("Process not debuggable: " + app.packageName);
8832                }
8833            }
8834            mProfileApp = processName;
8835            mProfileFile = profileFile;
8836            if (mProfileFd != null) {
8837                try {
8838                    mProfileFd.close();
8839                } catch (IOException e) {
8840                }
8841                mProfileFd = null;
8842            }
8843            mProfileFd = profileFd;
8844            mProfileType = 0;
8845            mAutoStopProfiler = autoStopProfiler;
8846        }
8847    }
8848
8849    @Override
8850    public void setAlwaysFinish(boolean enabled) {
8851        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8852                "setAlwaysFinish()");
8853
8854        Settings.Global.putInt(
8855                mContext.getContentResolver(),
8856                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8857
8858        synchronized (this) {
8859            mAlwaysFinishActivities = enabled;
8860        }
8861    }
8862
8863    @Override
8864    public void setActivityController(IActivityController controller) {
8865        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8866                "setActivityController()");
8867        synchronized (this) {
8868            mController = controller;
8869            Watchdog.getInstance().setActivityController(controller);
8870        }
8871    }
8872
8873    @Override
8874    public void setUserIsMonkey(boolean userIsMonkey) {
8875        synchronized (this) {
8876            synchronized (mPidsSelfLocked) {
8877                final int callingPid = Binder.getCallingPid();
8878                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8879                if (precessRecord == null) {
8880                    throw new SecurityException("Unknown process: " + callingPid);
8881                }
8882                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8883                    throw new SecurityException("Only an instrumentation process "
8884                            + "with a UiAutomation can call setUserIsMonkey");
8885                }
8886            }
8887            mUserIsMonkey = userIsMonkey;
8888        }
8889    }
8890
8891    @Override
8892    public boolean isUserAMonkey() {
8893        synchronized (this) {
8894            // If there is a controller also implies the user is a monkey.
8895            return (mUserIsMonkey || mController != null);
8896        }
8897    }
8898
8899    public void requestBugReport() {
8900        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8901        SystemProperties.set("ctl.start", "bugreport");
8902    }
8903
8904    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8905        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8906    }
8907
8908    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8909        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8910            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8911        }
8912        return KEY_DISPATCHING_TIMEOUT;
8913    }
8914
8915    @Override
8916    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8917        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8918                != PackageManager.PERMISSION_GRANTED) {
8919            throw new SecurityException("Requires permission "
8920                    + android.Manifest.permission.FILTER_EVENTS);
8921        }
8922        ProcessRecord proc;
8923        long timeout;
8924        synchronized (this) {
8925            synchronized (mPidsSelfLocked) {
8926                proc = mPidsSelfLocked.get(pid);
8927            }
8928            timeout = getInputDispatchingTimeoutLocked(proc);
8929        }
8930
8931        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8932            return -1;
8933        }
8934
8935        return timeout;
8936    }
8937
8938    /**
8939     * Handle input dispatching timeouts.
8940     * Returns whether input dispatching should be aborted or not.
8941     */
8942    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8943            final ActivityRecord activity, final ActivityRecord parent,
8944            final boolean aboveSystem, String reason) {
8945        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8946                != PackageManager.PERMISSION_GRANTED) {
8947            throw new SecurityException("Requires permission "
8948                    + android.Manifest.permission.FILTER_EVENTS);
8949        }
8950
8951        final String annotation;
8952        if (reason == null) {
8953            annotation = "Input dispatching timed out";
8954        } else {
8955            annotation = "Input dispatching timed out (" + reason + ")";
8956        }
8957
8958        if (proc != null) {
8959            synchronized (this) {
8960                if (proc.debugging) {
8961                    return false;
8962                }
8963
8964                if (mDidDexOpt) {
8965                    // Give more time since we were dexopting.
8966                    mDidDexOpt = false;
8967                    return false;
8968                }
8969
8970                if (proc.instrumentationClass != null) {
8971                    Bundle info = new Bundle();
8972                    info.putString("shortMsg", "keyDispatchingTimedOut");
8973                    info.putString("longMsg", annotation);
8974                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8975                    return true;
8976                }
8977            }
8978            mHandler.post(new Runnable() {
8979                @Override
8980                public void run() {
8981                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
8982                }
8983            });
8984        }
8985
8986        return true;
8987    }
8988
8989    public Bundle getAssistContextExtras(int requestType) {
8990        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
8991                "getAssistContextExtras()");
8992        PendingAssistExtras pae;
8993        Bundle extras = new Bundle();
8994        synchronized (this) {
8995            ActivityRecord activity = getFocusedStack().mResumedActivity;
8996            if (activity == null) {
8997                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
8998                return null;
8999            }
9000            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9001            if (activity.app == null || activity.app.thread == null) {
9002                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9003                return extras;
9004            }
9005            if (activity.app.pid == Binder.getCallingPid()) {
9006                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9007                return extras;
9008            }
9009            pae = new PendingAssistExtras(activity);
9010            try {
9011                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9012                        requestType);
9013                mPendingAssistExtras.add(pae);
9014                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9015            } catch (RemoteException e) {
9016                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9017                return extras;
9018            }
9019        }
9020        synchronized (pae) {
9021            while (!pae.haveResult) {
9022                try {
9023                    pae.wait();
9024                } catch (InterruptedException e) {
9025                }
9026            }
9027            if (pae.result != null) {
9028                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9029            }
9030        }
9031        synchronized (this) {
9032            mPendingAssistExtras.remove(pae);
9033            mHandler.removeCallbacks(pae);
9034        }
9035        return extras;
9036    }
9037
9038    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9039        PendingAssistExtras pae = (PendingAssistExtras)token;
9040        synchronized (pae) {
9041            pae.result = extras;
9042            pae.haveResult = true;
9043            pae.notifyAll();
9044        }
9045    }
9046
9047    public void registerProcessObserver(IProcessObserver observer) {
9048        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9049                "registerProcessObserver()");
9050        synchronized (this) {
9051            mProcessObservers.register(observer);
9052        }
9053    }
9054
9055    @Override
9056    public void unregisterProcessObserver(IProcessObserver observer) {
9057        synchronized (this) {
9058            mProcessObservers.unregister(observer);
9059        }
9060    }
9061
9062    @Override
9063    public boolean convertFromTranslucent(IBinder token) {
9064        final long origId = Binder.clearCallingIdentity();
9065        try {
9066            synchronized (this) {
9067                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9068                if (r == null) {
9069                    return false;
9070                }
9071                if (r.changeWindowTranslucency(true)) {
9072                    mWindowManager.setAppFullscreen(token, true);
9073                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9074                    return true;
9075                }
9076                return false;
9077            }
9078        } finally {
9079            Binder.restoreCallingIdentity(origId);
9080        }
9081    }
9082
9083    @Override
9084    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9085        final long origId = Binder.clearCallingIdentity();
9086        try {
9087            synchronized (this) {
9088                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9089                if (r == null) {
9090                    return false;
9091                }
9092                if (r.changeWindowTranslucency(false)) {
9093                    r.task.stack.convertToTranslucent(r, options);
9094                    mWindowManager.setAppFullscreen(token, false);
9095                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9096                    return true;
9097                }
9098                return false;
9099            }
9100        } finally {
9101            Binder.restoreCallingIdentity(origId);
9102        }
9103    }
9104
9105    @Override
9106    public ActivityOptions getActivityOptions(IBinder token) {
9107        final long origId = Binder.clearCallingIdentity();
9108        try {
9109            synchronized (this) {
9110                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9111                if (r != null) {
9112                    final ActivityOptions activityOptions = r.pendingOptions;
9113                    r.pendingOptions = null;
9114                    return activityOptions;
9115                }
9116                return null;
9117            }
9118        } finally {
9119            Binder.restoreCallingIdentity(origId);
9120        }
9121    }
9122
9123    @Override
9124    public void setImmersive(IBinder token, boolean immersive) {
9125        synchronized(this) {
9126            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9127            if (r == null) {
9128                throw new IllegalArgumentException();
9129            }
9130            r.immersive = immersive;
9131
9132            // update associated state if we're frontmost
9133            if (r == mFocusedActivity) {
9134                if (DEBUG_IMMERSIVE) {
9135                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9136                }
9137                applyUpdateLockStateLocked(r);
9138            }
9139        }
9140    }
9141
9142    @Override
9143    public boolean isImmersive(IBinder token) {
9144        synchronized (this) {
9145            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9146            if (r == null) {
9147                throw new IllegalArgumentException();
9148            }
9149            return r.immersive;
9150        }
9151    }
9152
9153    public boolean isTopActivityImmersive() {
9154        enforceNotIsolatedCaller("startActivity");
9155        synchronized (this) {
9156            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9157            return (r != null) ? r.immersive : false;
9158        }
9159    }
9160
9161    public final void enterSafeMode() {
9162        synchronized(this) {
9163            // It only makes sense to do this before the system is ready
9164            // and started launching other packages.
9165            if (!mSystemReady) {
9166                try {
9167                    AppGlobals.getPackageManager().enterSafeMode();
9168                } catch (RemoteException e) {
9169                }
9170            }
9171
9172            mSafeMode = true;
9173        }
9174    }
9175
9176    public final void showSafeModeOverlay() {
9177        View v = LayoutInflater.from(mContext).inflate(
9178                com.android.internal.R.layout.safe_mode, null);
9179        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9180        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9181        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9182        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9183        lp.gravity = Gravity.BOTTOM | Gravity.START;
9184        lp.format = v.getBackground().getOpacity();
9185        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9186                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9187        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9188        ((WindowManager)mContext.getSystemService(
9189                Context.WINDOW_SERVICE)).addView(v, lp);
9190    }
9191
9192    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9193        if (!(sender instanceof PendingIntentRecord)) {
9194            return;
9195        }
9196        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9197        synchronized (stats) {
9198            if (mBatteryStatsService.isOnBattery()) {
9199                mBatteryStatsService.enforceCallingPermission();
9200                PendingIntentRecord rec = (PendingIntentRecord)sender;
9201                int MY_UID = Binder.getCallingUid();
9202                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9203                BatteryStatsImpl.Uid.Pkg pkg =
9204                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9205                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9206                pkg.incWakeupsLocked();
9207            }
9208        }
9209    }
9210
9211    public boolean killPids(int[] pids, String pReason, boolean secure) {
9212        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9213            throw new SecurityException("killPids only available to the system");
9214        }
9215        String reason = (pReason == null) ? "Unknown" : pReason;
9216        // XXX Note: don't acquire main activity lock here, because the window
9217        // manager calls in with its locks held.
9218
9219        boolean killed = false;
9220        synchronized (mPidsSelfLocked) {
9221            int[] types = new int[pids.length];
9222            int worstType = 0;
9223            for (int i=0; i<pids.length; i++) {
9224                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9225                if (proc != null) {
9226                    int type = proc.setAdj;
9227                    types[i] = type;
9228                    if (type > worstType) {
9229                        worstType = type;
9230                    }
9231                }
9232            }
9233
9234            // If the worst oom_adj is somewhere in the cached proc LRU range,
9235            // then constrain it so we will kill all cached procs.
9236            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9237                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9238                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9239            }
9240
9241            // If this is not a secure call, don't let it kill processes that
9242            // are important.
9243            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9244                worstType = ProcessList.SERVICE_ADJ;
9245            }
9246
9247            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9248            for (int i=0; i<pids.length; i++) {
9249                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9250                if (proc == null) {
9251                    continue;
9252                }
9253                int adj = proc.setAdj;
9254                if (adj >= worstType && !proc.killedByAm) {
9255                    killUnneededProcessLocked(proc, reason);
9256                    killed = true;
9257                }
9258            }
9259        }
9260        return killed;
9261    }
9262
9263    @Override
9264    public void killUid(int uid, String reason) {
9265        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9266            throw new SecurityException("killUid only available to the system");
9267        }
9268        synchronized (this) {
9269            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9270                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9271                    reason != null ? reason : "kill uid");
9272        }
9273    }
9274
9275    @Override
9276    public boolean killProcessesBelowForeground(String reason) {
9277        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9278            throw new SecurityException("killProcessesBelowForeground() only available to system");
9279        }
9280
9281        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9282    }
9283
9284    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9285        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9286            throw new SecurityException("killProcessesBelowAdj() only available to system");
9287        }
9288
9289        boolean killed = false;
9290        synchronized (mPidsSelfLocked) {
9291            final int size = mPidsSelfLocked.size();
9292            for (int i = 0; i < size; i++) {
9293                final int pid = mPidsSelfLocked.keyAt(i);
9294                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9295                if (proc == null) continue;
9296
9297                final int adj = proc.setAdj;
9298                if (adj > belowAdj && !proc.killedByAm) {
9299                    killUnneededProcessLocked(proc, reason);
9300                    killed = true;
9301                }
9302            }
9303        }
9304        return killed;
9305    }
9306
9307    @Override
9308    public void hang(final IBinder who, boolean allowRestart) {
9309        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9310                != PackageManager.PERMISSION_GRANTED) {
9311            throw new SecurityException("Requires permission "
9312                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9313        }
9314
9315        final IBinder.DeathRecipient death = new DeathRecipient() {
9316            @Override
9317            public void binderDied() {
9318                synchronized (this) {
9319                    notifyAll();
9320                }
9321            }
9322        };
9323
9324        try {
9325            who.linkToDeath(death, 0);
9326        } catch (RemoteException e) {
9327            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9328            return;
9329        }
9330
9331        synchronized (this) {
9332            Watchdog.getInstance().setAllowRestart(allowRestart);
9333            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9334            synchronized (death) {
9335                while (who.isBinderAlive()) {
9336                    try {
9337                        death.wait();
9338                    } catch (InterruptedException e) {
9339                    }
9340                }
9341            }
9342            Watchdog.getInstance().setAllowRestart(true);
9343        }
9344    }
9345
9346    @Override
9347    public void restart() {
9348        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9349                != PackageManager.PERMISSION_GRANTED) {
9350            throw new SecurityException("Requires permission "
9351                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9352        }
9353
9354        Log.i(TAG, "Sending shutdown broadcast...");
9355
9356        BroadcastReceiver br = new BroadcastReceiver() {
9357            @Override public void onReceive(Context context, Intent intent) {
9358                // Now the broadcast is done, finish up the low-level shutdown.
9359                Log.i(TAG, "Shutting down activity manager...");
9360                shutdown(10000);
9361                Log.i(TAG, "Shutdown complete, restarting!");
9362                Process.killProcess(Process.myPid());
9363                System.exit(10);
9364            }
9365        };
9366
9367        // First send the high-level shut down broadcast.
9368        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9369        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9370        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9371        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9372        mContext.sendOrderedBroadcastAsUser(intent,
9373                UserHandle.ALL, null, br, mHandler, 0, null, null);
9374        */
9375        br.onReceive(mContext, intent);
9376    }
9377
9378    private long getLowRamTimeSinceIdle(long now) {
9379        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9380    }
9381
9382    @Override
9383    public void performIdleMaintenance() {
9384        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9385                != PackageManager.PERMISSION_GRANTED) {
9386            throw new SecurityException("Requires permission "
9387                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9388        }
9389
9390        synchronized (this) {
9391            final long now = SystemClock.uptimeMillis();
9392            final long timeSinceLastIdle = now - mLastIdleTime;
9393            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9394            mLastIdleTime = now;
9395            mLowRamTimeSinceLastIdle = 0;
9396            if (mLowRamStartTime != 0) {
9397                mLowRamStartTime = now;
9398            }
9399
9400            StringBuilder sb = new StringBuilder(128);
9401            sb.append("Idle maintenance over ");
9402            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9403            sb.append(" low RAM for ");
9404            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9405            Slog.i(TAG, sb.toString());
9406
9407            // If at least 1/3 of our time since the last idle period has been spent
9408            // with RAM low, then we want to kill processes.
9409            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9410
9411            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9412                ProcessRecord proc = mLruProcesses.get(i);
9413                if (proc.notCachedSinceIdle) {
9414                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9415                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9416                        if (doKilling && proc.initialIdlePss != 0
9417                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9418                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9419                                    + " from " + proc.initialIdlePss + ")");
9420                        }
9421                    }
9422                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9423                    proc.notCachedSinceIdle = true;
9424                    proc.initialIdlePss = 0;
9425                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9426                            isSleeping(), now);
9427                }
9428            }
9429
9430            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9431            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9432        }
9433    }
9434
9435    private void retrieveSettings() {
9436        final ContentResolver resolver = mContext.getContentResolver();
9437        String debugApp = Settings.Global.getString(
9438            resolver, Settings.Global.DEBUG_APP);
9439        boolean waitForDebugger = Settings.Global.getInt(
9440            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9441        boolean alwaysFinishActivities = Settings.Global.getInt(
9442            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9443        boolean forceRtl = Settings.Global.getInt(
9444                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9445        // Transfer any global setting for forcing RTL layout, into a System Property
9446        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9447
9448        Configuration configuration = new Configuration();
9449        Settings.System.getConfiguration(resolver, configuration);
9450        if (forceRtl) {
9451            // This will take care of setting the correct layout direction flags
9452            configuration.setLayoutDirection(configuration.locale);
9453        }
9454
9455        synchronized (this) {
9456            mDebugApp = mOrigDebugApp = debugApp;
9457            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9458            mAlwaysFinishActivities = alwaysFinishActivities;
9459            // This happens before any activities are started, so we can
9460            // change mConfiguration in-place.
9461            updateConfigurationLocked(configuration, null, false, true);
9462            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9463        }
9464    }
9465
9466    public boolean testIsSystemReady() {
9467        // no need to synchronize(this) just to read & return the value
9468        return mSystemReady;
9469    }
9470
9471    private static File getCalledPreBootReceiversFile() {
9472        File dataDir = Environment.getDataDirectory();
9473        File systemDir = new File(dataDir, "system");
9474        File fname = new File(systemDir, "called_pre_boots.dat");
9475        return fname;
9476    }
9477
9478    static final int LAST_DONE_VERSION = 10000;
9479
9480    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9481        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9482        File file = getCalledPreBootReceiversFile();
9483        FileInputStream fis = null;
9484        try {
9485            fis = new FileInputStream(file);
9486            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9487            int fvers = dis.readInt();
9488            if (fvers == LAST_DONE_VERSION) {
9489                String vers = dis.readUTF();
9490                String codename = dis.readUTF();
9491                String build = dis.readUTF();
9492                if (android.os.Build.VERSION.RELEASE.equals(vers)
9493                        && android.os.Build.VERSION.CODENAME.equals(codename)
9494                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9495                    int num = dis.readInt();
9496                    while (num > 0) {
9497                        num--;
9498                        String pkg = dis.readUTF();
9499                        String cls = dis.readUTF();
9500                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9501                    }
9502                }
9503            }
9504        } catch (FileNotFoundException e) {
9505        } catch (IOException e) {
9506            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9507        } finally {
9508            if (fis != null) {
9509                try {
9510                    fis.close();
9511                } catch (IOException e) {
9512                }
9513            }
9514        }
9515        return lastDoneReceivers;
9516    }
9517
9518    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9519        File file = getCalledPreBootReceiversFile();
9520        FileOutputStream fos = null;
9521        DataOutputStream dos = null;
9522        try {
9523            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9524            fos = new FileOutputStream(file);
9525            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9526            dos.writeInt(LAST_DONE_VERSION);
9527            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9528            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9529            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9530            dos.writeInt(list.size());
9531            for (int i=0; i<list.size(); i++) {
9532                dos.writeUTF(list.get(i).getPackageName());
9533                dos.writeUTF(list.get(i).getClassName());
9534            }
9535        } catch (IOException e) {
9536            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9537            file.delete();
9538        } finally {
9539            FileUtils.sync(fos);
9540            if (dos != null) {
9541                try {
9542                    dos.close();
9543                } catch (IOException e) {
9544                    // TODO Auto-generated catch block
9545                    e.printStackTrace();
9546                }
9547            }
9548        }
9549    }
9550
9551    public void systemReady(final Runnable goingCallback) {
9552        synchronized(this) {
9553            if (mSystemReady) {
9554                if (goingCallback != null) goingCallback.run();
9555                return;
9556            }
9557
9558            // Check to see if there are any update receivers to run.
9559            if (!mDidUpdate) {
9560                if (mWaitingUpdate) {
9561                    return;
9562                }
9563                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9564                List<ResolveInfo> ris = null;
9565                try {
9566                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9567                            intent, null, 0, 0);
9568                } catch (RemoteException e) {
9569                }
9570                if (ris != null) {
9571                    for (int i=ris.size()-1; i>=0; i--) {
9572                        if ((ris.get(i).activityInfo.applicationInfo.flags
9573                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9574                            ris.remove(i);
9575                        }
9576                    }
9577                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9578
9579                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9580
9581                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9582                    for (int i=0; i<ris.size(); i++) {
9583                        ActivityInfo ai = ris.get(i).activityInfo;
9584                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9585                        if (lastDoneReceivers.contains(comp)) {
9586                            // We already did the pre boot receiver for this app with the current
9587                            // platform version, so don't do it again...
9588                            ris.remove(i);
9589                            i--;
9590                            // ...however, do keep it as one that has been done, so we don't
9591                            // forget about it when rewriting the file of last done receivers.
9592                            doneReceivers.add(comp);
9593                        }
9594                    }
9595
9596                    final int[] users = getUsersLocked();
9597                    for (int i=0; i<ris.size(); i++) {
9598                        ActivityInfo ai = ris.get(i).activityInfo;
9599                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9600                        doneReceivers.add(comp);
9601                        intent.setComponent(comp);
9602                        for (int j=0; j<users.length; j++) {
9603                            IIntentReceiver finisher = null;
9604                            if (i == ris.size()-1 && j == users.length-1) {
9605                                finisher = new IIntentReceiver.Stub() {
9606                                    public void performReceive(Intent intent, int resultCode,
9607                                            String data, Bundle extras, boolean ordered,
9608                                            boolean sticky, int sendingUser) {
9609                                        // The raw IIntentReceiver interface is called
9610                                        // with the AM lock held, so redispatch to
9611                                        // execute our code without the lock.
9612                                        mHandler.post(new Runnable() {
9613                                            public void run() {
9614                                                synchronized (ActivityManagerService.this) {
9615                                                    mDidUpdate = true;
9616                                                }
9617                                                writeLastDonePreBootReceivers(doneReceivers);
9618                                                showBootMessage(mContext.getText(
9619                                                        R.string.android_upgrading_complete),
9620                                                        false);
9621                                                systemReady(goingCallback);
9622                                            }
9623                                        });
9624                                    }
9625                                };
9626                            }
9627                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9628                                    + " for user " + users[j]);
9629                            broadcastIntentLocked(null, null, intent, null, finisher,
9630                                    0, null, null, null, AppOpsManager.OP_NONE,
9631                                    true, false, MY_PID, Process.SYSTEM_UID,
9632                                    users[j]);
9633                            if (finisher != null) {
9634                                mWaitingUpdate = true;
9635                            }
9636                        }
9637                    }
9638                }
9639                if (mWaitingUpdate) {
9640                    return;
9641                }
9642                mDidUpdate = true;
9643            }
9644
9645            mAppOpsService.systemReady();
9646            mUsageStatsService.systemReady();
9647            mSystemReady = true;
9648        }
9649
9650        ArrayList<ProcessRecord> procsToKill = null;
9651        synchronized(mPidsSelfLocked) {
9652            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9653                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9654                if (!isAllowedWhileBooting(proc.info)){
9655                    if (procsToKill == null) {
9656                        procsToKill = new ArrayList<ProcessRecord>();
9657                    }
9658                    procsToKill.add(proc);
9659                }
9660            }
9661        }
9662
9663        synchronized(this) {
9664            if (procsToKill != null) {
9665                for (int i=procsToKill.size()-1; i>=0; i--) {
9666                    ProcessRecord proc = procsToKill.get(i);
9667                    Slog.i(TAG, "Removing system update proc: " + proc);
9668                    removeProcessLocked(proc, true, false, "system update done");
9669                }
9670            }
9671
9672            // Now that we have cleaned up any update processes, we
9673            // are ready to start launching real processes and know that
9674            // we won't trample on them any more.
9675            mProcessesReady = true;
9676        }
9677
9678        Slog.i(TAG, "System now ready");
9679        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9680            SystemClock.uptimeMillis());
9681
9682        synchronized(this) {
9683            // Make sure we have no pre-ready processes sitting around.
9684
9685            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9686                ResolveInfo ri = mContext.getPackageManager()
9687                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9688                                STOCK_PM_FLAGS);
9689                CharSequence errorMsg = null;
9690                if (ri != null) {
9691                    ActivityInfo ai = ri.activityInfo;
9692                    ApplicationInfo app = ai.applicationInfo;
9693                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9694                        mTopAction = Intent.ACTION_FACTORY_TEST;
9695                        mTopData = null;
9696                        mTopComponent = new ComponentName(app.packageName,
9697                                ai.name);
9698                    } else {
9699                        errorMsg = mContext.getResources().getText(
9700                                com.android.internal.R.string.factorytest_not_system);
9701                    }
9702                } else {
9703                    errorMsg = mContext.getResources().getText(
9704                            com.android.internal.R.string.factorytest_no_action);
9705                }
9706                if (errorMsg != null) {
9707                    mTopAction = null;
9708                    mTopData = null;
9709                    mTopComponent = null;
9710                    Message msg = Message.obtain();
9711                    msg.what = SHOW_FACTORY_ERROR_MSG;
9712                    msg.getData().putCharSequence("msg", errorMsg);
9713                    mHandler.sendMessage(msg);
9714                }
9715            }
9716        }
9717
9718        retrieveSettings();
9719
9720        synchronized (this) {
9721            readGrantedUriPermissionsLocked();
9722        }
9723
9724        if (goingCallback != null) goingCallback.run();
9725
9726        mSystemServiceManager.startUser(mCurrentUserId);
9727
9728        synchronized (this) {
9729            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9730                try {
9731                    List apps = AppGlobals.getPackageManager().
9732                        getPersistentApplications(STOCK_PM_FLAGS);
9733                    if (apps != null) {
9734                        int N = apps.size();
9735                        int i;
9736                        for (i=0; i<N; i++) {
9737                            ApplicationInfo info
9738                                = (ApplicationInfo)apps.get(i);
9739                            if (info != null &&
9740                                    !info.packageName.equals("android")) {
9741                                addAppLocked(info, false);
9742                            }
9743                        }
9744                    }
9745                } catch (RemoteException ex) {
9746                    // pm is in same process, this will never happen.
9747                }
9748            }
9749
9750            // Start up initial activity.
9751            mBooting = true;
9752
9753            try {
9754                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9755                    Message msg = Message.obtain();
9756                    msg.what = SHOW_UID_ERROR_MSG;
9757                    mHandler.sendMessage(msg);
9758                }
9759            } catch (RemoteException e) {
9760            }
9761
9762            long ident = Binder.clearCallingIdentity();
9763            try {
9764                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9765                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9766                        | Intent.FLAG_RECEIVER_FOREGROUND);
9767                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9768                broadcastIntentLocked(null, null, intent,
9769                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9770                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9771                intent = new Intent(Intent.ACTION_USER_STARTING);
9772                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9773                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9774                broadcastIntentLocked(null, null, intent,
9775                        null, new IIntentReceiver.Stub() {
9776                            @Override
9777                            public void performReceive(Intent intent, int resultCode, String data,
9778                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9779                                    throws RemoteException {
9780                            }
9781                        }, 0, null, null,
9782                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9783                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9784            } catch (Throwable t) {
9785                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
9786            } finally {
9787                Binder.restoreCallingIdentity(ident);
9788            }
9789            mStackSupervisor.resumeTopActivitiesLocked();
9790            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9791        }
9792    }
9793
9794    private boolean makeAppCrashingLocked(ProcessRecord app,
9795            String shortMsg, String longMsg, String stackTrace) {
9796        app.crashing = true;
9797        app.crashingReport = generateProcessError(app,
9798                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9799        startAppProblemLocked(app);
9800        app.stopFreezingAllLocked();
9801        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9802    }
9803
9804    private void makeAppNotRespondingLocked(ProcessRecord app,
9805            String activity, String shortMsg, String longMsg) {
9806        app.notResponding = true;
9807        app.notRespondingReport = generateProcessError(app,
9808                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9809                activity, shortMsg, longMsg, null);
9810        startAppProblemLocked(app);
9811        app.stopFreezingAllLocked();
9812    }
9813
9814    /**
9815     * Generate a process error record, suitable for attachment to a ProcessRecord.
9816     *
9817     * @param app The ProcessRecord in which the error occurred.
9818     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9819     *                      ActivityManager.AppErrorStateInfo
9820     * @param activity The activity associated with the crash, if known.
9821     * @param shortMsg Short message describing the crash.
9822     * @param longMsg Long message describing the crash.
9823     * @param stackTrace Full crash stack trace, may be null.
9824     *
9825     * @return Returns a fully-formed AppErrorStateInfo record.
9826     */
9827    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9828            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9829        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9830
9831        report.condition = condition;
9832        report.processName = app.processName;
9833        report.pid = app.pid;
9834        report.uid = app.info.uid;
9835        report.tag = activity;
9836        report.shortMsg = shortMsg;
9837        report.longMsg = longMsg;
9838        report.stackTrace = stackTrace;
9839
9840        return report;
9841    }
9842
9843    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9844        synchronized (this) {
9845            app.crashing = false;
9846            app.crashingReport = null;
9847            app.notResponding = false;
9848            app.notRespondingReport = null;
9849            if (app.anrDialog == fromDialog) {
9850                app.anrDialog = null;
9851            }
9852            if (app.waitDialog == fromDialog) {
9853                app.waitDialog = null;
9854            }
9855            if (app.pid > 0 && app.pid != MY_PID) {
9856                handleAppCrashLocked(app, null, null, null);
9857                killUnneededProcessLocked(app, "user request after error");
9858            }
9859        }
9860    }
9861
9862    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9863            String stackTrace) {
9864        long now = SystemClock.uptimeMillis();
9865
9866        Long crashTime;
9867        if (!app.isolated) {
9868            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9869        } else {
9870            crashTime = null;
9871        }
9872        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9873            // This process loses!
9874            Slog.w(TAG, "Process " + app.info.processName
9875                    + " has crashed too many times: killing!");
9876            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9877                    app.userId, app.info.processName, app.uid);
9878            mStackSupervisor.handleAppCrashLocked(app);
9879            if (!app.persistent) {
9880                // We don't want to start this process again until the user
9881                // explicitly does so...  but for persistent process, we really
9882                // need to keep it running.  If a persistent process is actually
9883                // repeatedly crashing, then badness for everyone.
9884                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9885                        app.info.processName);
9886                if (!app.isolated) {
9887                    // XXX We don't have a way to mark isolated processes
9888                    // as bad, since they don't have a peristent identity.
9889                    mBadProcesses.put(app.info.processName, app.uid,
9890                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9891                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9892                }
9893                app.bad = true;
9894                app.removed = true;
9895                // Don't let services in this process be restarted and potentially
9896                // annoy the user repeatedly.  Unless it is persistent, since those
9897                // processes run critical code.
9898                removeProcessLocked(app, false, false, "crash");
9899                mStackSupervisor.resumeTopActivitiesLocked();
9900                return false;
9901            }
9902            mStackSupervisor.resumeTopActivitiesLocked();
9903        } else {
9904            mStackSupervisor.finishTopRunningActivityLocked(app);
9905        }
9906
9907        // Bump up the crash count of any services currently running in the proc.
9908        for (int i=app.services.size()-1; i>=0; i--) {
9909            // Any services running in the application need to be placed
9910            // back in the pending list.
9911            ServiceRecord sr = app.services.valueAt(i);
9912            sr.crashCount++;
9913        }
9914
9915        // If the crashing process is what we consider to be the "home process" and it has been
9916        // replaced by a third-party app, clear the package preferred activities from packages
9917        // with a home activity running in the process to prevent a repeatedly crashing app
9918        // from blocking the user to manually clear the list.
9919        final ArrayList<ActivityRecord> activities = app.activities;
9920        if (app == mHomeProcess && activities.size() > 0
9921                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9922            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9923                final ActivityRecord r = activities.get(activityNdx);
9924                if (r.isHomeActivity()) {
9925                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9926                    try {
9927                        ActivityThread.getPackageManager()
9928                                .clearPackagePreferredActivities(r.packageName);
9929                    } catch (RemoteException c) {
9930                        // pm is in same process, this will never happen.
9931                    }
9932                }
9933            }
9934        }
9935
9936        if (!app.isolated) {
9937            // XXX Can't keep track of crash times for isolated processes,
9938            // because they don't have a perisistent identity.
9939            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9940        }
9941
9942        return true;
9943    }
9944
9945    void startAppProblemLocked(ProcessRecord app) {
9946        if (app.userId == mCurrentUserId) {
9947            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9948                    mContext, app.info.packageName, app.info.flags);
9949        } else {
9950            // If this app is not running under the current user, then we
9951            // can't give it a report button because that would require
9952            // launching the report UI under a different user.
9953            app.errorReportReceiver = null;
9954        }
9955        skipCurrentReceiverLocked(app);
9956    }
9957
9958    void skipCurrentReceiverLocked(ProcessRecord app) {
9959        for (BroadcastQueue queue : mBroadcastQueues) {
9960            queue.skipCurrentReceiverLocked(app);
9961        }
9962    }
9963
9964    /**
9965     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9966     * The application process will exit immediately after this call returns.
9967     * @param app object of the crashing app, null for the system server
9968     * @param crashInfo describing the exception
9969     */
9970    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9971        ProcessRecord r = findAppProcess(app, "Crash");
9972        final String processName = app == null ? "system_server"
9973                : (r == null ? "unknown" : r.processName);
9974
9975        handleApplicationCrashInner("crash", r, processName, crashInfo);
9976    }
9977
9978    /* Native crash reporting uses this inner version because it needs to be somewhat
9979     * decoupled from the AM-managed cleanup lifecycle
9980     */
9981    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
9982            ApplicationErrorReport.CrashInfo crashInfo) {
9983        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
9984                UserHandle.getUserId(Binder.getCallingUid()), processName,
9985                r == null ? -1 : r.info.flags,
9986                crashInfo.exceptionClassName,
9987                crashInfo.exceptionMessage,
9988                crashInfo.throwFileName,
9989                crashInfo.throwLineNumber);
9990
9991        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
9992
9993        crashApplication(r, crashInfo);
9994    }
9995
9996    public void handleApplicationStrictModeViolation(
9997            IBinder app,
9998            int violationMask,
9999            StrictMode.ViolationInfo info) {
10000        ProcessRecord r = findAppProcess(app, "StrictMode");
10001        if (r == null) {
10002            return;
10003        }
10004
10005        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10006            Integer stackFingerprint = info.hashCode();
10007            boolean logIt = true;
10008            synchronized (mAlreadyLoggedViolatedStacks) {
10009                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10010                    logIt = false;
10011                    // TODO: sub-sample into EventLog for these, with
10012                    // the info.durationMillis?  Then we'd get
10013                    // the relative pain numbers, without logging all
10014                    // the stack traces repeatedly.  We'd want to do
10015                    // likewise in the client code, which also does
10016                    // dup suppression, before the Binder call.
10017                } else {
10018                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10019                        mAlreadyLoggedViolatedStacks.clear();
10020                    }
10021                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10022                }
10023            }
10024            if (logIt) {
10025                logStrictModeViolationToDropBox(r, info);
10026            }
10027        }
10028
10029        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10030            AppErrorResult result = new AppErrorResult();
10031            synchronized (this) {
10032                final long origId = Binder.clearCallingIdentity();
10033
10034                Message msg = Message.obtain();
10035                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10036                HashMap<String, Object> data = new HashMap<String, Object>();
10037                data.put("result", result);
10038                data.put("app", r);
10039                data.put("violationMask", violationMask);
10040                data.put("info", info);
10041                msg.obj = data;
10042                mHandler.sendMessage(msg);
10043
10044                Binder.restoreCallingIdentity(origId);
10045            }
10046            int res = result.get();
10047            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10048        }
10049    }
10050
10051    // Depending on the policy in effect, there could be a bunch of
10052    // these in quick succession so we try to batch these together to
10053    // minimize disk writes, number of dropbox entries, and maximize
10054    // compression, by having more fewer, larger records.
10055    private void logStrictModeViolationToDropBox(
10056            ProcessRecord process,
10057            StrictMode.ViolationInfo info) {
10058        if (info == null) {
10059            return;
10060        }
10061        final boolean isSystemApp = process == null ||
10062                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10063                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10064        final String processName = process == null ? "unknown" : process.processName;
10065        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10066        final DropBoxManager dbox = (DropBoxManager)
10067                mContext.getSystemService(Context.DROPBOX_SERVICE);
10068
10069        // Exit early if the dropbox isn't configured to accept this report type.
10070        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10071
10072        boolean bufferWasEmpty;
10073        boolean needsFlush;
10074        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10075        synchronized (sb) {
10076            bufferWasEmpty = sb.length() == 0;
10077            appendDropBoxProcessHeaders(process, processName, sb);
10078            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10079            sb.append("System-App: ").append(isSystemApp).append("\n");
10080            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10081            if (info.violationNumThisLoop != 0) {
10082                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10083            }
10084            if (info.numAnimationsRunning != 0) {
10085                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10086            }
10087            if (info.broadcastIntentAction != null) {
10088                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10089            }
10090            if (info.durationMillis != -1) {
10091                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10092            }
10093            if (info.numInstances != -1) {
10094                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10095            }
10096            if (info.tags != null) {
10097                for (String tag : info.tags) {
10098                    sb.append("Span-Tag: ").append(tag).append("\n");
10099                }
10100            }
10101            sb.append("\n");
10102            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10103                sb.append(info.crashInfo.stackTrace);
10104            }
10105            sb.append("\n");
10106
10107            // Only buffer up to ~64k.  Various logging bits truncate
10108            // things at 128k.
10109            needsFlush = (sb.length() > 64 * 1024);
10110        }
10111
10112        // Flush immediately if the buffer's grown too large, or this
10113        // is a non-system app.  Non-system apps are isolated with a
10114        // different tag & policy and not batched.
10115        //
10116        // Batching is useful during internal testing with
10117        // StrictMode settings turned up high.  Without batching,
10118        // thousands of separate files could be created on boot.
10119        if (!isSystemApp || needsFlush) {
10120            new Thread("Error dump: " + dropboxTag) {
10121                @Override
10122                public void run() {
10123                    String report;
10124                    synchronized (sb) {
10125                        report = sb.toString();
10126                        sb.delete(0, sb.length());
10127                        sb.trimToSize();
10128                    }
10129                    if (report.length() != 0) {
10130                        dbox.addText(dropboxTag, report);
10131                    }
10132                }
10133            }.start();
10134            return;
10135        }
10136
10137        // System app batching:
10138        if (!bufferWasEmpty) {
10139            // An existing dropbox-writing thread is outstanding, so
10140            // we don't need to start it up.  The existing thread will
10141            // catch the buffer appends we just did.
10142            return;
10143        }
10144
10145        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10146        // (After this point, we shouldn't access AMS internal data structures.)
10147        new Thread("Error dump: " + dropboxTag) {
10148            @Override
10149            public void run() {
10150                // 5 second sleep to let stacks arrive and be batched together
10151                try {
10152                    Thread.sleep(5000);  // 5 seconds
10153                } catch (InterruptedException e) {}
10154
10155                String errorReport;
10156                synchronized (mStrictModeBuffer) {
10157                    errorReport = mStrictModeBuffer.toString();
10158                    if (errorReport.length() == 0) {
10159                        return;
10160                    }
10161                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10162                    mStrictModeBuffer.trimToSize();
10163                }
10164                dbox.addText(dropboxTag, errorReport);
10165            }
10166        }.start();
10167    }
10168
10169    /**
10170     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10171     * @param app object of the crashing app, null for the system server
10172     * @param tag reported by the caller
10173     * @param crashInfo describing the context of the error
10174     * @return true if the process should exit immediately (WTF is fatal)
10175     */
10176    public boolean handleApplicationWtf(IBinder app, String tag,
10177            ApplicationErrorReport.CrashInfo crashInfo) {
10178        ProcessRecord r = findAppProcess(app, "WTF");
10179        final String processName = app == null ? "system_server"
10180                : (r == null ? "unknown" : r.processName);
10181
10182        EventLog.writeEvent(EventLogTags.AM_WTF,
10183                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10184                processName,
10185                r == null ? -1 : r.info.flags,
10186                tag, crashInfo.exceptionMessage);
10187
10188        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10189
10190        if (r != null && r.pid != Process.myPid() &&
10191                Settings.Global.getInt(mContext.getContentResolver(),
10192                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10193            crashApplication(r, crashInfo);
10194            return true;
10195        } else {
10196            return false;
10197        }
10198    }
10199
10200    /**
10201     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10202     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10203     */
10204    private ProcessRecord findAppProcess(IBinder app, String reason) {
10205        if (app == null) {
10206            return null;
10207        }
10208
10209        synchronized (this) {
10210            final int NP = mProcessNames.getMap().size();
10211            for (int ip=0; ip<NP; ip++) {
10212                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10213                final int NA = apps.size();
10214                for (int ia=0; ia<NA; ia++) {
10215                    ProcessRecord p = apps.valueAt(ia);
10216                    if (p.thread != null && p.thread.asBinder() == app) {
10217                        return p;
10218                    }
10219                }
10220            }
10221
10222            Slog.w(TAG, "Can't find mystery application for " + reason
10223                    + " from pid=" + Binder.getCallingPid()
10224                    + " uid=" + Binder.getCallingUid() + ": " + app);
10225            return null;
10226        }
10227    }
10228
10229    /**
10230     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10231     * to append various headers to the dropbox log text.
10232     */
10233    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10234            StringBuilder sb) {
10235        // Watchdog thread ends up invoking this function (with
10236        // a null ProcessRecord) to add the stack file to dropbox.
10237        // Do not acquire a lock on this (am) in such cases, as it
10238        // could cause a potential deadlock, if and when watchdog
10239        // is invoked due to unavailability of lock on am and it
10240        // would prevent watchdog from killing system_server.
10241        if (process == null) {
10242            sb.append("Process: ").append(processName).append("\n");
10243            return;
10244        }
10245        // Note: ProcessRecord 'process' is guarded by the service
10246        // instance.  (notably process.pkgList, which could otherwise change
10247        // concurrently during execution of this method)
10248        synchronized (this) {
10249            sb.append("Process: ").append(processName).append("\n");
10250            int flags = process.info.flags;
10251            IPackageManager pm = AppGlobals.getPackageManager();
10252            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10253            for (int ip=0; ip<process.pkgList.size(); ip++) {
10254                String pkg = process.pkgList.keyAt(ip);
10255                sb.append("Package: ").append(pkg);
10256                try {
10257                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10258                    if (pi != null) {
10259                        sb.append(" v").append(pi.versionCode);
10260                        if (pi.versionName != null) {
10261                            sb.append(" (").append(pi.versionName).append(")");
10262                        }
10263                    }
10264                } catch (RemoteException e) {
10265                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10266                }
10267                sb.append("\n");
10268            }
10269        }
10270    }
10271
10272    private static String processClass(ProcessRecord process) {
10273        if (process == null || process.pid == MY_PID) {
10274            return "system_server";
10275        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10276            return "system_app";
10277        } else {
10278            return "data_app";
10279        }
10280    }
10281
10282    /**
10283     * Write a description of an error (crash, WTF, ANR) to the drop box.
10284     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10285     * @param process which caused the error, null means the system server
10286     * @param activity which triggered the error, null if unknown
10287     * @param parent activity related to the error, null if unknown
10288     * @param subject line related to the error, null if absent
10289     * @param report in long form describing the error, null if absent
10290     * @param logFile to include in the report, null if none
10291     * @param crashInfo giving an application stack trace, null if absent
10292     */
10293    public void addErrorToDropBox(String eventType,
10294            ProcessRecord process, String processName, ActivityRecord activity,
10295            ActivityRecord parent, String subject,
10296            final String report, final File logFile,
10297            final ApplicationErrorReport.CrashInfo crashInfo) {
10298        // NOTE -- this must never acquire the ActivityManagerService lock,
10299        // otherwise the watchdog may be prevented from resetting the system.
10300
10301        final String dropboxTag = processClass(process) + "_" + eventType;
10302        final DropBoxManager dbox = (DropBoxManager)
10303                mContext.getSystemService(Context.DROPBOX_SERVICE);
10304
10305        // Exit early if the dropbox isn't configured to accept this report type.
10306        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10307
10308        final StringBuilder sb = new StringBuilder(1024);
10309        appendDropBoxProcessHeaders(process, processName, sb);
10310        if (activity != null) {
10311            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10312        }
10313        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10314            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10315        }
10316        if (parent != null && parent != activity) {
10317            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10318        }
10319        if (subject != null) {
10320            sb.append("Subject: ").append(subject).append("\n");
10321        }
10322        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10323        if (Debug.isDebuggerConnected()) {
10324            sb.append("Debugger: Connected\n");
10325        }
10326        sb.append("\n");
10327
10328        // Do the rest in a worker thread to avoid blocking the caller on I/O
10329        // (After this point, we shouldn't access AMS internal data structures.)
10330        Thread worker = new Thread("Error dump: " + dropboxTag) {
10331            @Override
10332            public void run() {
10333                if (report != null) {
10334                    sb.append(report);
10335                }
10336                if (logFile != null) {
10337                    try {
10338                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10339                                    "\n\n[[TRUNCATED]]"));
10340                    } catch (IOException e) {
10341                        Slog.e(TAG, "Error reading " + logFile, e);
10342                    }
10343                }
10344                if (crashInfo != null && crashInfo.stackTrace != null) {
10345                    sb.append(crashInfo.stackTrace);
10346                }
10347
10348                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10349                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10350                if (lines > 0) {
10351                    sb.append("\n");
10352
10353                    // Merge several logcat streams, and take the last N lines
10354                    InputStreamReader input = null;
10355                    try {
10356                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10357                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10358                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10359
10360                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10361                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10362                        input = new InputStreamReader(logcat.getInputStream());
10363
10364                        int num;
10365                        char[] buf = new char[8192];
10366                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10367                    } catch (IOException e) {
10368                        Slog.e(TAG, "Error running logcat", e);
10369                    } finally {
10370                        if (input != null) try { input.close(); } catch (IOException e) {}
10371                    }
10372                }
10373
10374                dbox.addText(dropboxTag, sb.toString());
10375            }
10376        };
10377
10378        if (process == null) {
10379            // If process is null, we are being called from some internal code
10380            // and may be about to die -- run this synchronously.
10381            worker.run();
10382        } else {
10383            worker.start();
10384        }
10385    }
10386
10387    /**
10388     * Bring up the "unexpected error" dialog box for a crashing app.
10389     * Deal with edge cases (intercepts from instrumented applications,
10390     * ActivityController, error intent receivers, that sort of thing).
10391     * @param r the application crashing
10392     * @param crashInfo describing the failure
10393     */
10394    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10395        long timeMillis = System.currentTimeMillis();
10396        String shortMsg = crashInfo.exceptionClassName;
10397        String longMsg = crashInfo.exceptionMessage;
10398        String stackTrace = crashInfo.stackTrace;
10399        if (shortMsg != null && longMsg != null) {
10400            longMsg = shortMsg + ": " + longMsg;
10401        } else if (shortMsg != null) {
10402            longMsg = shortMsg;
10403        }
10404
10405        AppErrorResult result = new AppErrorResult();
10406        synchronized (this) {
10407            if (mController != null) {
10408                try {
10409                    String name = r != null ? r.processName : null;
10410                    int pid = r != null ? r.pid : Binder.getCallingPid();
10411                    if (!mController.appCrashed(name, pid,
10412                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10413                        Slog.w(TAG, "Force-killing crashed app " + name
10414                                + " at watcher's request");
10415                        Process.killProcess(pid);
10416                        return;
10417                    }
10418                } catch (RemoteException e) {
10419                    mController = null;
10420                    Watchdog.getInstance().setActivityController(null);
10421                }
10422            }
10423
10424            final long origId = Binder.clearCallingIdentity();
10425
10426            // If this process is running instrumentation, finish it.
10427            if (r != null && r.instrumentationClass != null) {
10428                Slog.w(TAG, "Error in app " + r.processName
10429                      + " running instrumentation " + r.instrumentationClass + ":");
10430                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10431                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10432                Bundle info = new Bundle();
10433                info.putString("shortMsg", shortMsg);
10434                info.putString("longMsg", longMsg);
10435                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10436                Binder.restoreCallingIdentity(origId);
10437                return;
10438            }
10439
10440            // If we can't identify the process or it's already exceeded its crash quota,
10441            // quit right away without showing a crash dialog.
10442            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10443                Binder.restoreCallingIdentity(origId);
10444                return;
10445            }
10446
10447            Message msg = Message.obtain();
10448            msg.what = SHOW_ERROR_MSG;
10449            HashMap data = new HashMap();
10450            data.put("result", result);
10451            data.put("app", r);
10452            msg.obj = data;
10453            mHandler.sendMessage(msg);
10454
10455            Binder.restoreCallingIdentity(origId);
10456        }
10457
10458        int res = result.get();
10459
10460        Intent appErrorIntent = null;
10461        synchronized (this) {
10462            if (r != null && !r.isolated) {
10463                // XXX Can't keep track of crash time for isolated processes,
10464                // since they don't have a persistent identity.
10465                mProcessCrashTimes.put(r.info.processName, r.uid,
10466                        SystemClock.uptimeMillis());
10467            }
10468            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10469                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10470            }
10471        }
10472
10473        if (appErrorIntent != null) {
10474            try {
10475                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10476            } catch (ActivityNotFoundException e) {
10477                Slog.w(TAG, "bug report receiver dissappeared", e);
10478            }
10479        }
10480    }
10481
10482    Intent createAppErrorIntentLocked(ProcessRecord r,
10483            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10484        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10485        if (report == null) {
10486            return null;
10487        }
10488        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10489        result.setComponent(r.errorReportReceiver);
10490        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10491        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10492        return result;
10493    }
10494
10495    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10496            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10497        if (r.errorReportReceiver == null) {
10498            return null;
10499        }
10500
10501        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10502            return null;
10503        }
10504
10505        ApplicationErrorReport report = new ApplicationErrorReport();
10506        report.packageName = r.info.packageName;
10507        report.installerPackageName = r.errorReportReceiver.getPackageName();
10508        report.processName = r.processName;
10509        report.time = timeMillis;
10510        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10511
10512        if (r.crashing || r.forceCrashReport) {
10513            report.type = ApplicationErrorReport.TYPE_CRASH;
10514            report.crashInfo = crashInfo;
10515        } else if (r.notResponding) {
10516            report.type = ApplicationErrorReport.TYPE_ANR;
10517            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10518
10519            report.anrInfo.activity = r.notRespondingReport.tag;
10520            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10521            report.anrInfo.info = r.notRespondingReport.longMsg;
10522        }
10523
10524        return report;
10525    }
10526
10527    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10528        enforceNotIsolatedCaller("getProcessesInErrorState");
10529        // assume our apps are happy - lazy create the list
10530        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10531
10532        final boolean allUsers = ActivityManager.checkUidPermission(
10533                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10534                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10535        int userId = UserHandle.getUserId(Binder.getCallingUid());
10536
10537        synchronized (this) {
10538
10539            // iterate across all processes
10540            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10541                ProcessRecord app = mLruProcesses.get(i);
10542                if (!allUsers && app.userId != userId) {
10543                    continue;
10544                }
10545                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10546                    // This one's in trouble, so we'll generate a report for it
10547                    // crashes are higher priority (in case there's a crash *and* an anr)
10548                    ActivityManager.ProcessErrorStateInfo report = null;
10549                    if (app.crashing) {
10550                        report = app.crashingReport;
10551                    } else if (app.notResponding) {
10552                        report = app.notRespondingReport;
10553                    }
10554
10555                    if (report != null) {
10556                        if (errList == null) {
10557                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10558                        }
10559                        errList.add(report);
10560                    } else {
10561                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10562                                " crashing = " + app.crashing +
10563                                " notResponding = " + app.notResponding);
10564                    }
10565                }
10566            }
10567        }
10568
10569        return errList;
10570    }
10571
10572    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10573        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10574            if (currApp != null) {
10575                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10576            }
10577            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10578        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10579            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10580        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10581            if (currApp != null) {
10582                currApp.lru = 0;
10583            }
10584            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10585        } else if (adj >= ProcessList.SERVICE_ADJ) {
10586            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10587        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10588            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10589        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10590            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10591        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10592            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10593        } else {
10594            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10595        }
10596    }
10597
10598    private void fillInProcMemInfo(ProcessRecord app,
10599            ActivityManager.RunningAppProcessInfo outInfo) {
10600        outInfo.pid = app.pid;
10601        outInfo.uid = app.info.uid;
10602        if (mHeavyWeightProcess == app) {
10603            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10604        }
10605        if (app.persistent) {
10606            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10607        }
10608        if (app.activities.size() > 0) {
10609            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10610        }
10611        outInfo.lastTrimLevel = app.trimMemoryLevel;
10612        int adj = app.curAdj;
10613        outInfo.importance = oomAdjToImportance(adj, outInfo);
10614        outInfo.importanceReasonCode = app.adjTypeCode;
10615        outInfo.processState = app.curProcState;
10616    }
10617
10618    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10619        enforceNotIsolatedCaller("getRunningAppProcesses");
10620        // Lazy instantiation of list
10621        List<ActivityManager.RunningAppProcessInfo> runList = null;
10622        final boolean allUsers = ActivityManager.checkUidPermission(
10623                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10624                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10625        int userId = UserHandle.getUserId(Binder.getCallingUid());
10626        synchronized (this) {
10627            // Iterate across all processes
10628            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10629                ProcessRecord app = mLruProcesses.get(i);
10630                if (!allUsers && app.userId != userId) {
10631                    continue;
10632                }
10633                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10634                    // Generate process state info for running application
10635                    ActivityManager.RunningAppProcessInfo currApp =
10636                        new ActivityManager.RunningAppProcessInfo(app.processName,
10637                                app.pid, app.getPackageList());
10638                    fillInProcMemInfo(app, currApp);
10639                    if (app.adjSource instanceof ProcessRecord) {
10640                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10641                        currApp.importanceReasonImportance = oomAdjToImportance(
10642                                app.adjSourceOom, null);
10643                    } else if (app.adjSource instanceof ActivityRecord) {
10644                        ActivityRecord r = (ActivityRecord)app.adjSource;
10645                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10646                    }
10647                    if (app.adjTarget instanceof ComponentName) {
10648                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10649                    }
10650                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10651                    //        + " lru=" + currApp.lru);
10652                    if (runList == null) {
10653                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10654                    }
10655                    runList.add(currApp);
10656                }
10657            }
10658        }
10659        return runList;
10660    }
10661
10662    public List<ApplicationInfo> getRunningExternalApplications() {
10663        enforceNotIsolatedCaller("getRunningExternalApplications");
10664        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10665        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10666        if (runningApps != null && runningApps.size() > 0) {
10667            Set<String> extList = new HashSet<String>();
10668            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10669                if (app.pkgList != null) {
10670                    for (String pkg : app.pkgList) {
10671                        extList.add(pkg);
10672                    }
10673                }
10674            }
10675            IPackageManager pm = AppGlobals.getPackageManager();
10676            for (String pkg : extList) {
10677                try {
10678                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10679                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10680                        retList.add(info);
10681                    }
10682                } catch (RemoteException e) {
10683                }
10684            }
10685        }
10686        return retList;
10687    }
10688
10689    @Override
10690    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10691        enforceNotIsolatedCaller("getMyMemoryState");
10692        synchronized (this) {
10693            ProcessRecord proc;
10694            synchronized (mPidsSelfLocked) {
10695                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10696            }
10697            fillInProcMemInfo(proc, outInfo);
10698        }
10699    }
10700
10701    @Override
10702    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10703        if (checkCallingPermission(android.Manifest.permission.DUMP)
10704                != PackageManager.PERMISSION_GRANTED) {
10705            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10706                    + Binder.getCallingPid()
10707                    + ", uid=" + Binder.getCallingUid()
10708                    + " without permission "
10709                    + android.Manifest.permission.DUMP);
10710            return;
10711        }
10712
10713        boolean dumpAll = false;
10714        boolean dumpClient = false;
10715        String dumpPackage = null;
10716
10717        int opti = 0;
10718        while (opti < args.length) {
10719            String opt = args[opti];
10720            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10721                break;
10722            }
10723            opti++;
10724            if ("-a".equals(opt)) {
10725                dumpAll = true;
10726            } else if ("-c".equals(opt)) {
10727                dumpClient = true;
10728            } else if ("-h".equals(opt)) {
10729                pw.println("Activity manager dump options:");
10730                pw.println("  [-a] [-c] [-h] [cmd] ...");
10731                pw.println("  cmd may be one of:");
10732                pw.println("    a[ctivities]: activity stack state");
10733                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10734                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10735                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10736                pw.println("    o[om]: out of memory management");
10737                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10738                pw.println("    provider [COMP_SPEC]: provider client-side state");
10739                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10740                pw.println("    service [COMP_SPEC]: service client-side state");
10741                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10742                pw.println("    all: dump all activities");
10743                pw.println("    top: dump the top activity");
10744                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10745                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10746                pw.println("    a partial substring in a component name, a");
10747                pw.println("    hex object identifier.");
10748                pw.println("  -a: include all available server state.");
10749                pw.println("  -c: include client state.");
10750                return;
10751            } else {
10752                pw.println("Unknown argument: " + opt + "; use -h for help");
10753            }
10754        }
10755
10756        long origId = Binder.clearCallingIdentity();
10757        boolean more = false;
10758        // Is the caller requesting to dump a particular piece of data?
10759        if (opti < args.length) {
10760            String cmd = args[opti];
10761            opti++;
10762            if ("activities".equals(cmd) || "a".equals(cmd)) {
10763                synchronized (this) {
10764                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10765                }
10766            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10767                String[] newArgs;
10768                String name;
10769                if (opti >= args.length) {
10770                    name = null;
10771                    newArgs = EMPTY_STRING_ARRAY;
10772                } else {
10773                    name = args[opti];
10774                    opti++;
10775                    newArgs = new String[args.length - opti];
10776                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10777                            args.length - opti);
10778                }
10779                synchronized (this) {
10780                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10781                }
10782            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10783                String[] newArgs;
10784                String name;
10785                if (opti >= args.length) {
10786                    name = null;
10787                    newArgs = EMPTY_STRING_ARRAY;
10788                } else {
10789                    name = args[opti];
10790                    opti++;
10791                    newArgs = new String[args.length - opti];
10792                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10793                            args.length - opti);
10794                }
10795                synchronized (this) {
10796                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10797                }
10798            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10799                String[] newArgs;
10800                String name;
10801                if (opti >= args.length) {
10802                    name = null;
10803                    newArgs = EMPTY_STRING_ARRAY;
10804                } else {
10805                    name = args[opti];
10806                    opti++;
10807                    newArgs = new String[args.length - opti];
10808                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10809                            args.length - opti);
10810                }
10811                synchronized (this) {
10812                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10813                }
10814            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10815                synchronized (this) {
10816                    dumpOomLocked(fd, pw, args, opti, true);
10817                }
10818            } else if ("provider".equals(cmd)) {
10819                String[] newArgs;
10820                String name;
10821                if (opti >= args.length) {
10822                    name = null;
10823                    newArgs = EMPTY_STRING_ARRAY;
10824                } else {
10825                    name = args[opti];
10826                    opti++;
10827                    newArgs = new String[args.length - opti];
10828                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10829                }
10830                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10831                    pw.println("No providers match: " + name);
10832                    pw.println("Use -h for help.");
10833                }
10834            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10835                synchronized (this) {
10836                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10837                }
10838            } else if ("service".equals(cmd)) {
10839                String[] newArgs;
10840                String name;
10841                if (opti >= args.length) {
10842                    name = null;
10843                    newArgs = EMPTY_STRING_ARRAY;
10844                } else {
10845                    name = args[opti];
10846                    opti++;
10847                    newArgs = new String[args.length - opti];
10848                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10849                            args.length - opti);
10850                }
10851                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10852                    pw.println("No services match: " + name);
10853                    pw.println("Use -h for help.");
10854                }
10855            } else if ("package".equals(cmd)) {
10856                String[] newArgs;
10857                if (opti >= args.length) {
10858                    pw.println("package: no package name specified");
10859                    pw.println("Use -h for help.");
10860                } else {
10861                    dumpPackage = args[opti];
10862                    opti++;
10863                    newArgs = new String[args.length - opti];
10864                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10865                            args.length - opti);
10866                    args = newArgs;
10867                    opti = 0;
10868                    more = true;
10869                }
10870            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10871                synchronized (this) {
10872                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10873                }
10874            } else {
10875                // Dumping a single activity?
10876                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10877                    pw.println("Bad activity command, or no activities match: " + cmd);
10878                    pw.println("Use -h for help.");
10879                }
10880            }
10881            if (!more) {
10882                Binder.restoreCallingIdentity(origId);
10883                return;
10884            }
10885        }
10886
10887        // No piece of data specified, dump everything.
10888        synchronized (this) {
10889            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10890            pw.println();
10891            if (dumpAll) {
10892                pw.println("-------------------------------------------------------------------------------");
10893            }
10894            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10895            pw.println();
10896            if (dumpAll) {
10897                pw.println("-------------------------------------------------------------------------------");
10898            }
10899            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10900            pw.println();
10901            if (dumpAll) {
10902                pw.println("-------------------------------------------------------------------------------");
10903            }
10904            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10905            pw.println();
10906            if (dumpAll) {
10907                pw.println("-------------------------------------------------------------------------------");
10908            }
10909            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10910            pw.println();
10911            if (dumpAll) {
10912                pw.println("-------------------------------------------------------------------------------");
10913            }
10914            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10915        }
10916        Binder.restoreCallingIdentity(origId);
10917    }
10918
10919    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10920            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10921        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10922
10923        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10924                dumpPackage);
10925        boolean needSep = printedAnything;
10926
10927        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10928                dumpPackage, needSep, "  mFocusedActivity: ");
10929        if (printed) {
10930            printedAnything = true;
10931            needSep = false;
10932        }
10933
10934        if (dumpPackage == null) {
10935            if (needSep) {
10936                pw.println();
10937            }
10938            needSep = true;
10939            printedAnything = true;
10940            mStackSupervisor.dump(pw, "  ");
10941        }
10942
10943        if (mRecentTasks.size() > 0) {
10944            boolean printedHeader = false;
10945
10946            final int N = mRecentTasks.size();
10947            for (int i=0; i<N; i++) {
10948                TaskRecord tr = mRecentTasks.get(i);
10949                if (dumpPackage != null) {
10950                    if (tr.realActivity == null ||
10951                            !dumpPackage.equals(tr.realActivity)) {
10952                        continue;
10953                    }
10954                }
10955                if (!printedHeader) {
10956                    if (needSep) {
10957                        pw.println();
10958                    }
10959                    pw.println("  Recent tasks:");
10960                    printedHeader = true;
10961                    printedAnything = true;
10962                }
10963                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10964                        pw.println(tr);
10965                if (dumpAll) {
10966                    mRecentTasks.get(i).dump(pw, "    ");
10967                }
10968            }
10969        }
10970
10971        if (!printedAnything) {
10972            pw.println("  (nothing)");
10973        }
10974    }
10975
10976    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10977            int opti, boolean dumpAll, String dumpPackage) {
10978        boolean needSep = false;
10979        boolean printedAnything = false;
10980        int numPers = 0;
10981
10982        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
10983
10984        if (dumpAll) {
10985            final int NP = mProcessNames.getMap().size();
10986            for (int ip=0; ip<NP; ip++) {
10987                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
10988                final int NA = procs.size();
10989                for (int ia=0; ia<NA; ia++) {
10990                    ProcessRecord r = procs.valueAt(ia);
10991                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10992                        continue;
10993                    }
10994                    if (!needSep) {
10995                        pw.println("  All known processes:");
10996                        needSep = true;
10997                        printedAnything = true;
10998                    }
10999                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11000                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11001                        pw.print(" "); pw.println(r);
11002                    r.dump(pw, "    ");
11003                    if (r.persistent) {
11004                        numPers++;
11005                    }
11006                }
11007            }
11008        }
11009
11010        if (mIsolatedProcesses.size() > 0) {
11011            boolean printed = false;
11012            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11013                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11014                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11015                    continue;
11016                }
11017                if (!printed) {
11018                    if (needSep) {
11019                        pw.println();
11020                    }
11021                    pw.println("  Isolated process list (sorted by uid):");
11022                    printedAnything = true;
11023                    printed = true;
11024                    needSep = true;
11025                }
11026                pw.println(String.format("%sIsolated #%2d: %s",
11027                        "    ", i, r.toString()));
11028            }
11029        }
11030
11031        if (mLruProcesses.size() > 0) {
11032            if (needSep) {
11033                pw.println();
11034            }
11035            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11036                    pw.print(" total, non-act at ");
11037                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11038                    pw.print(", non-svc at ");
11039                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11040                    pw.println("):");
11041            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11042            needSep = true;
11043            printedAnything = true;
11044        }
11045
11046        if (dumpAll || dumpPackage != null) {
11047            synchronized (mPidsSelfLocked) {
11048                boolean printed = false;
11049                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11050                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11051                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11052                        continue;
11053                    }
11054                    if (!printed) {
11055                        if (needSep) pw.println();
11056                        needSep = true;
11057                        pw.println("  PID mappings:");
11058                        printed = true;
11059                        printedAnything = true;
11060                    }
11061                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11062                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11063                }
11064            }
11065        }
11066
11067        if (mForegroundProcesses.size() > 0) {
11068            synchronized (mPidsSelfLocked) {
11069                boolean printed = false;
11070                for (int i=0; i<mForegroundProcesses.size(); i++) {
11071                    ProcessRecord r = mPidsSelfLocked.get(
11072                            mForegroundProcesses.valueAt(i).pid);
11073                    if (dumpPackage != null && (r == null
11074                            || !r.pkgList.containsKey(dumpPackage))) {
11075                        continue;
11076                    }
11077                    if (!printed) {
11078                        if (needSep) pw.println();
11079                        needSep = true;
11080                        pw.println("  Foreground Processes:");
11081                        printed = true;
11082                        printedAnything = true;
11083                    }
11084                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11085                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11086                }
11087            }
11088        }
11089
11090        if (mPersistentStartingProcesses.size() > 0) {
11091            if (needSep) pw.println();
11092            needSep = true;
11093            printedAnything = true;
11094            pw.println("  Persisent processes that are starting:");
11095            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11096                    "Starting Norm", "Restarting PERS", dumpPackage);
11097        }
11098
11099        if (mRemovedProcesses.size() > 0) {
11100            if (needSep) pw.println();
11101            needSep = true;
11102            printedAnything = true;
11103            pw.println("  Processes that are being removed:");
11104            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11105                    "Removed Norm", "Removed PERS", dumpPackage);
11106        }
11107
11108        if (mProcessesOnHold.size() > 0) {
11109            if (needSep) pw.println();
11110            needSep = true;
11111            printedAnything = true;
11112            pw.println("  Processes that are on old until the system is ready:");
11113            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11114                    "OnHold Norm", "OnHold PERS", dumpPackage);
11115        }
11116
11117        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11118
11119        if (mProcessCrashTimes.getMap().size() > 0) {
11120            boolean printed = false;
11121            long now = SystemClock.uptimeMillis();
11122            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11123            final int NP = pmap.size();
11124            for (int ip=0; ip<NP; ip++) {
11125                String pname = pmap.keyAt(ip);
11126                SparseArray<Long> uids = pmap.valueAt(ip);
11127                final int N = uids.size();
11128                for (int i=0; i<N; i++) {
11129                    int puid = uids.keyAt(i);
11130                    ProcessRecord r = mProcessNames.get(pname, puid);
11131                    if (dumpPackage != null && (r == null
11132                            || !r.pkgList.containsKey(dumpPackage))) {
11133                        continue;
11134                    }
11135                    if (!printed) {
11136                        if (needSep) pw.println();
11137                        needSep = true;
11138                        pw.println("  Time since processes crashed:");
11139                        printed = true;
11140                        printedAnything = true;
11141                    }
11142                    pw.print("    Process "); pw.print(pname);
11143                            pw.print(" uid "); pw.print(puid);
11144                            pw.print(": last crashed ");
11145                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11146                            pw.println(" ago");
11147                }
11148            }
11149        }
11150
11151        if (mBadProcesses.getMap().size() > 0) {
11152            boolean printed = false;
11153            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11154            final int NP = pmap.size();
11155            for (int ip=0; ip<NP; ip++) {
11156                String pname = pmap.keyAt(ip);
11157                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11158                final int N = uids.size();
11159                for (int i=0; i<N; i++) {
11160                    int puid = uids.keyAt(i);
11161                    ProcessRecord r = mProcessNames.get(pname, puid);
11162                    if (dumpPackage != null && (r == null
11163                            || !r.pkgList.containsKey(dumpPackage))) {
11164                        continue;
11165                    }
11166                    if (!printed) {
11167                        if (needSep) pw.println();
11168                        needSep = true;
11169                        pw.println("  Bad processes:");
11170                        printedAnything = true;
11171                    }
11172                    BadProcessInfo info = uids.valueAt(i);
11173                    pw.print("    Bad process "); pw.print(pname);
11174                            pw.print(" uid "); pw.print(puid);
11175                            pw.print(": crashed at time "); pw.println(info.time);
11176                    if (info.shortMsg != null) {
11177                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11178                    }
11179                    if (info.longMsg != null) {
11180                        pw.print("      Long msg: "); pw.println(info.longMsg);
11181                    }
11182                    if (info.stack != null) {
11183                        pw.println("      Stack:");
11184                        int lastPos = 0;
11185                        for (int pos=0; pos<info.stack.length(); pos++) {
11186                            if (info.stack.charAt(pos) == '\n') {
11187                                pw.print("        ");
11188                                pw.write(info.stack, lastPos, pos-lastPos);
11189                                pw.println();
11190                                lastPos = pos+1;
11191                            }
11192                        }
11193                        if (lastPos < info.stack.length()) {
11194                            pw.print("        ");
11195                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11196                            pw.println();
11197                        }
11198                    }
11199                }
11200            }
11201        }
11202
11203        if (dumpPackage == null) {
11204            pw.println();
11205            needSep = false;
11206            pw.println("  mStartedUsers:");
11207            for (int i=0; i<mStartedUsers.size(); i++) {
11208                UserStartedState uss = mStartedUsers.valueAt(i);
11209                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11210                        pw.print(": "); uss.dump("", pw);
11211            }
11212            pw.print("  mStartedUserArray: [");
11213            for (int i=0; i<mStartedUserArray.length; i++) {
11214                if (i > 0) pw.print(", ");
11215                pw.print(mStartedUserArray[i]);
11216            }
11217            pw.println("]");
11218            pw.print("  mUserLru: [");
11219            for (int i=0; i<mUserLru.size(); i++) {
11220                if (i > 0) pw.print(", ");
11221                pw.print(mUserLru.get(i));
11222            }
11223            pw.println("]");
11224            if (dumpAll) {
11225                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11226            }
11227        }
11228        if (mHomeProcess != null && (dumpPackage == null
11229                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11230            if (needSep) {
11231                pw.println();
11232                needSep = false;
11233            }
11234            pw.println("  mHomeProcess: " + mHomeProcess);
11235        }
11236        if (mPreviousProcess != null && (dumpPackage == null
11237                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11238            if (needSep) {
11239                pw.println();
11240                needSep = false;
11241            }
11242            pw.println("  mPreviousProcess: " + mPreviousProcess);
11243        }
11244        if (dumpAll) {
11245            StringBuilder sb = new StringBuilder(128);
11246            sb.append("  mPreviousProcessVisibleTime: ");
11247            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11248            pw.println(sb);
11249        }
11250        if (mHeavyWeightProcess != null && (dumpPackage == null
11251                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11252            if (needSep) {
11253                pw.println();
11254                needSep = false;
11255            }
11256            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11257        }
11258        if (dumpPackage == null) {
11259            pw.println("  mConfiguration: " + mConfiguration);
11260        }
11261        if (dumpAll) {
11262            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11263            if (mCompatModePackages.getPackages().size() > 0) {
11264                boolean printed = false;
11265                for (Map.Entry<String, Integer> entry
11266                        : mCompatModePackages.getPackages().entrySet()) {
11267                    String pkg = entry.getKey();
11268                    int mode = entry.getValue();
11269                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11270                        continue;
11271                    }
11272                    if (!printed) {
11273                        pw.println("  mScreenCompatPackages:");
11274                        printed = true;
11275                    }
11276                    pw.print("    "); pw.print(pkg); pw.print(": ");
11277                            pw.print(mode); pw.println();
11278                }
11279            }
11280        }
11281        if (dumpPackage == null) {
11282            if (mSleeping || mWentToSleep || mLockScreenShown) {
11283                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11284                        + " mLockScreenShown " + mLockScreenShown);
11285            }
11286            if (mShuttingDown || mRunningVoice) {
11287                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11288            }
11289        }
11290        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11291                || mOrigWaitForDebugger) {
11292            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11293                    || dumpPackage.equals(mOrigDebugApp)) {
11294                if (needSep) {
11295                    pw.println();
11296                    needSep = false;
11297                }
11298                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11299                        + " mDebugTransient=" + mDebugTransient
11300                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11301            }
11302        }
11303        if (mOpenGlTraceApp != null) {
11304            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11305                if (needSep) {
11306                    pw.println();
11307                    needSep = false;
11308                }
11309                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11310            }
11311        }
11312        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11313                || mProfileFd != null) {
11314            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11315                if (needSep) {
11316                    pw.println();
11317                    needSep = false;
11318                }
11319                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11320                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11321                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11322                        + mAutoStopProfiler);
11323            }
11324        }
11325        if (dumpPackage == null) {
11326            if (mAlwaysFinishActivities || mController != null) {
11327                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11328                        + " mController=" + mController);
11329            }
11330            if (dumpAll) {
11331                pw.println("  Total persistent processes: " + numPers);
11332                pw.println("  mProcessesReady=" + mProcessesReady
11333                        + " mSystemReady=" + mSystemReady);
11334                pw.println("  mBooting=" + mBooting
11335                        + " mBooted=" + mBooted
11336                        + " mFactoryTest=" + mFactoryTest);
11337                pw.print("  mLastPowerCheckRealtime=");
11338                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11339                        pw.println("");
11340                pw.print("  mLastPowerCheckUptime=");
11341                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11342                        pw.println("");
11343                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11344                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11345                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11346                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11347                        + " (" + mLruProcesses.size() + " total)"
11348                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11349                        + " mNumServiceProcs=" + mNumServiceProcs
11350                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11351                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11352                        + " mLastMemoryLevel" + mLastMemoryLevel
11353                        + " mLastNumProcesses" + mLastNumProcesses);
11354                long now = SystemClock.uptimeMillis();
11355                pw.print("  mLastIdleTime=");
11356                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11357                        pw.print(" mLowRamSinceLastIdle=");
11358                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11359                        pw.println();
11360            }
11361        }
11362
11363        if (!printedAnything) {
11364            pw.println("  (nothing)");
11365        }
11366    }
11367
11368    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11369            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11370        if (mProcessesToGc.size() > 0) {
11371            boolean printed = false;
11372            long now = SystemClock.uptimeMillis();
11373            for (int i=0; i<mProcessesToGc.size(); i++) {
11374                ProcessRecord proc = mProcessesToGc.get(i);
11375                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11376                    continue;
11377                }
11378                if (!printed) {
11379                    if (needSep) pw.println();
11380                    needSep = true;
11381                    pw.println("  Processes that are waiting to GC:");
11382                    printed = true;
11383                }
11384                pw.print("    Process "); pw.println(proc);
11385                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11386                        pw.print(", last gced=");
11387                        pw.print(now-proc.lastRequestedGc);
11388                        pw.print(" ms ago, last lowMem=");
11389                        pw.print(now-proc.lastLowMemory);
11390                        pw.println(" ms ago");
11391
11392            }
11393        }
11394        return needSep;
11395    }
11396
11397    void printOomLevel(PrintWriter pw, String name, int adj) {
11398        pw.print("    ");
11399        if (adj >= 0) {
11400            pw.print(' ');
11401            if (adj < 10) pw.print(' ');
11402        } else {
11403            if (adj > -10) pw.print(' ');
11404        }
11405        pw.print(adj);
11406        pw.print(": ");
11407        pw.print(name);
11408        pw.print(" (");
11409        pw.print(mProcessList.getMemLevel(adj)/1024);
11410        pw.println(" kB)");
11411    }
11412
11413    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11414            int opti, boolean dumpAll) {
11415        boolean needSep = false;
11416
11417        if (mLruProcesses.size() > 0) {
11418            if (needSep) pw.println();
11419            needSep = true;
11420            pw.println("  OOM levels:");
11421            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11422            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11423            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11424            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11425            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11426            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11427            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11428            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11429            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11430            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11431            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11432            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11433            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11434
11435            if (needSep) pw.println();
11436            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11437                    pw.print(" total, non-act at ");
11438                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11439                    pw.print(", non-svc at ");
11440                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11441                    pw.println("):");
11442            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11443            needSep = true;
11444        }
11445
11446        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11447
11448        pw.println();
11449        pw.println("  mHomeProcess: " + mHomeProcess);
11450        pw.println("  mPreviousProcess: " + mPreviousProcess);
11451        if (mHeavyWeightProcess != null) {
11452            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11453        }
11454
11455        return true;
11456    }
11457
11458    /**
11459     * There are three ways to call this:
11460     *  - no provider specified: dump all the providers
11461     *  - a flattened component name that matched an existing provider was specified as the
11462     *    first arg: dump that one provider
11463     *  - the first arg isn't the flattened component name of an existing provider:
11464     *    dump all providers whose component contains the first arg as a substring
11465     */
11466    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11467            int opti, boolean dumpAll) {
11468        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11469    }
11470
11471    static class ItemMatcher {
11472        ArrayList<ComponentName> components;
11473        ArrayList<String> strings;
11474        ArrayList<Integer> objects;
11475        boolean all;
11476
11477        ItemMatcher() {
11478            all = true;
11479        }
11480
11481        void build(String name) {
11482            ComponentName componentName = ComponentName.unflattenFromString(name);
11483            if (componentName != null) {
11484                if (components == null) {
11485                    components = new ArrayList<ComponentName>();
11486                }
11487                components.add(componentName);
11488                all = false;
11489            } else {
11490                int objectId = 0;
11491                // Not a '/' separated full component name; maybe an object ID?
11492                try {
11493                    objectId = Integer.parseInt(name, 16);
11494                    if (objects == null) {
11495                        objects = new ArrayList<Integer>();
11496                    }
11497                    objects.add(objectId);
11498                    all = false;
11499                } catch (RuntimeException e) {
11500                    // Not an integer; just do string match.
11501                    if (strings == null) {
11502                        strings = new ArrayList<String>();
11503                    }
11504                    strings.add(name);
11505                    all = false;
11506                }
11507            }
11508        }
11509
11510        int build(String[] args, int opti) {
11511            for (; opti<args.length; opti++) {
11512                String name = args[opti];
11513                if ("--".equals(name)) {
11514                    return opti+1;
11515                }
11516                build(name);
11517            }
11518            return opti;
11519        }
11520
11521        boolean match(Object object, ComponentName comp) {
11522            if (all) {
11523                return true;
11524            }
11525            if (components != null) {
11526                for (int i=0; i<components.size(); i++) {
11527                    if (components.get(i).equals(comp)) {
11528                        return true;
11529                    }
11530                }
11531            }
11532            if (objects != null) {
11533                for (int i=0; i<objects.size(); i++) {
11534                    if (System.identityHashCode(object) == objects.get(i)) {
11535                        return true;
11536                    }
11537                }
11538            }
11539            if (strings != null) {
11540                String flat = comp.flattenToString();
11541                for (int i=0; i<strings.size(); i++) {
11542                    if (flat.contains(strings.get(i))) {
11543                        return true;
11544                    }
11545                }
11546            }
11547            return false;
11548        }
11549    }
11550
11551    /**
11552     * There are three things that cmd can be:
11553     *  - a flattened component name that matches an existing activity
11554     *  - the cmd arg isn't the flattened component name of an existing activity:
11555     *    dump all activity whose component contains the cmd as a substring
11556     *  - A hex number of the ActivityRecord object instance.
11557     */
11558    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11559            int opti, boolean dumpAll) {
11560        ArrayList<ActivityRecord> activities;
11561
11562        synchronized (this) {
11563            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11564        }
11565
11566        if (activities.size() <= 0) {
11567            return false;
11568        }
11569
11570        String[] newArgs = new String[args.length - opti];
11571        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11572
11573        TaskRecord lastTask = null;
11574        boolean needSep = false;
11575        for (int i=activities.size()-1; i>=0; i--) {
11576            ActivityRecord r = activities.get(i);
11577            if (needSep) {
11578                pw.println();
11579            }
11580            needSep = true;
11581            synchronized (this) {
11582                if (lastTask != r.task) {
11583                    lastTask = r.task;
11584                    pw.print("TASK "); pw.print(lastTask.affinity);
11585                            pw.print(" id="); pw.println(lastTask.taskId);
11586                    if (dumpAll) {
11587                        lastTask.dump(pw, "  ");
11588                    }
11589                }
11590            }
11591            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11592        }
11593        return true;
11594    }
11595
11596    /**
11597     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11598     * there is a thread associated with the activity.
11599     */
11600    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11601            final ActivityRecord r, String[] args, boolean dumpAll) {
11602        String innerPrefix = prefix + "  ";
11603        synchronized (this) {
11604            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11605                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11606                    pw.print(" pid=");
11607                    if (r.app != null) pw.println(r.app.pid);
11608                    else pw.println("(not running)");
11609            if (dumpAll) {
11610                r.dump(pw, innerPrefix);
11611            }
11612        }
11613        if (r.app != null && r.app.thread != null) {
11614            // flush anything that is already in the PrintWriter since the thread is going
11615            // to write to the file descriptor directly
11616            pw.flush();
11617            try {
11618                TransferPipe tp = new TransferPipe();
11619                try {
11620                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11621                            r.appToken, innerPrefix, args);
11622                    tp.go(fd);
11623                } finally {
11624                    tp.kill();
11625                }
11626            } catch (IOException e) {
11627                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11628            } catch (RemoteException e) {
11629                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11630            }
11631        }
11632    }
11633
11634    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11635            int opti, boolean dumpAll, String dumpPackage) {
11636        boolean needSep = false;
11637        boolean onlyHistory = false;
11638        boolean printedAnything = false;
11639
11640        if ("history".equals(dumpPackage)) {
11641            if (opti < args.length && "-s".equals(args[opti])) {
11642                dumpAll = false;
11643            }
11644            onlyHistory = true;
11645            dumpPackage = null;
11646        }
11647
11648        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11649        if (!onlyHistory && dumpAll) {
11650            if (mRegisteredReceivers.size() > 0) {
11651                boolean printed = false;
11652                Iterator it = mRegisteredReceivers.values().iterator();
11653                while (it.hasNext()) {
11654                    ReceiverList r = (ReceiverList)it.next();
11655                    if (dumpPackage != null && (r.app == null ||
11656                            !dumpPackage.equals(r.app.info.packageName))) {
11657                        continue;
11658                    }
11659                    if (!printed) {
11660                        pw.println("  Registered Receivers:");
11661                        needSep = true;
11662                        printed = true;
11663                        printedAnything = true;
11664                    }
11665                    pw.print("  * "); pw.println(r);
11666                    r.dump(pw, "    ");
11667                }
11668            }
11669
11670            if (mReceiverResolver.dump(pw, needSep ?
11671                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11672                    "    ", dumpPackage, false)) {
11673                needSep = true;
11674                printedAnything = true;
11675            }
11676        }
11677
11678        for (BroadcastQueue q : mBroadcastQueues) {
11679            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11680            printedAnything |= needSep;
11681        }
11682
11683        needSep = true;
11684
11685        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11686            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11687                if (needSep) {
11688                    pw.println();
11689                }
11690                needSep = true;
11691                printedAnything = true;
11692                pw.print("  Sticky broadcasts for user ");
11693                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11694                StringBuilder sb = new StringBuilder(128);
11695                for (Map.Entry<String, ArrayList<Intent>> ent
11696                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11697                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11698                    if (dumpAll) {
11699                        pw.println(":");
11700                        ArrayList<Intent> intents = ent.getValue();
11701                        final int N = intents.size();
11702                        for (int i=0; i<N; i++) {
11703                            sb.setLength(0);
11704                            sb.append("    Intent: ");
11705                            intents.get(i).toShortString(sb, false, true, false, false);
11706                            pw.println(sb.toString());
11707                            Bundle bundle = intents.get(i).getExtras();
11708                            if (bundle != null) {
11709                                pw.print("      ");
11710                                pw.println(bundle.toString());
11711                            }
11712                        }
11713                    } else {
11714                        pw.println("");
11715                    }
11716                }
11717            }
11718        }
11719
11720        if (!onlyHistory && dumpAll) {
11721            pw.println();
11722            for (BroadcastQueue queue : mBroadcastQueues) {
11723                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11724                        + queue.mBroadcastsScheduled);
11725            }
11726            pw.println("  mHandler:");
11727            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11728            needSep = true;
11729            printedAnything = true;
11730        }
11731
11732        if (!printedAnything) {
11733            pw.println("  (nothing)");
11734        }
11735    }
11736
11737    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11738            int opti, boolean dumpAll, String dumpPackage) {
11739        boolean needSep;
11740        boolean printedAnything = false;
11741
11742        ItemMatcher matcher = new ItemMatcher();
11743        matcher.build(args, opti);
11744
11745        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11746
11747        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11748        printedAnything |= needSep;
11749
11750        if (mLaunchingProviders.size() > 0) {
11751            boolean printed = false;
11752            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11753                ContentProviderRecord r = mLaunchingProviders.get(i);
11754                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11755                    continue;
11756                }
11757                if (!printed) {
11758                    if (needSep) pw.println();
11759                    needSep = true;
11760                    pw.println("  Launching content providers:");
11761                    printed = true;
11762                    printedAnything = true;
11763                }
11764                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11765                        pw.println(r);
11766            }
11767        }
11768
11769        if (mGrantedUriPermissions.size() > 0) {
11770            boolean printed = false;
11771            int dumpUid = -2;
11772            if (dumpPackage != null) {
11773                try {
11774                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11775                } catch (NameNotFoundException e) {
11776                    dumpUid = -1;
11777                }
11778            }
11779            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11780                int uid = mGrantedUriPermissions.keyAt(i);
11781                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11782                    continue;
11783                }
11784                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
11785                if (!printed) {
11786                    if (needSep) pw.println();
11787                    needSep = true;
11788                    pw.println("  Granted Uri Permissions:");
11789                    printed = true;
11790                    printedAnything = true;
11791                }
11792                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
11793                for (UriPermission perm : perms.values()) {
11794                    pw.print("    "); pw.println(perm);
11795                    if (dumpAll) {
11796                        perm.dump(pw, "      ");
11797                    }
11798                }
11799            }
11800        }
11801
11802        if (!printedAnything) {
11803            pw.println("  (nothing)");
11804        }
11805    }
11806
11807    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11808            int opti, boolean dumpAll, String dumpPackage) {
11809        boolean printed = false;
11810
11811        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11812
11813        if (mIntentSenderRecords.size() > 0) {
11814            Iterator<WeakReference<PendingIntentRecord>> it
11815                    = mIntentSenderRecords.values().iterator();
11816            while (it.hasNext()) {
11817                WeakReference<PendingIntentRecord> ref = it.next();
11818                PendingIntentRecord rec = ref != null ? ref.get(): null;
11819                if (dumpPackage != null && (rec == null
11820                        || !dumpPackage.equals(rec.key.packageName))) {
11821                    continue;
11822                }
11823                printed = true;
11824                if (rec != null) {
11825                    pw.print("  * "); pw.println(rec);
11826                    if (dumpAll) {
11827                        rec.dump(pw, "    ");
11828                    }
11829                } else {
11830                    pw.print("  * "); pw.println(ref);
11831                }
11832            }
11833        }
11834
11835        if (!printed) {
11836            pw.println("  (nothing)");
11837        }
11838    }
11839
11840    private static final int dumpProcessList(PrintWriter pw,
11841            ActivityManagerService service, List list,
11842            String prefix, String normalLabel, String persistentLabel,
11843            String dumpPackage) {
11844        int numPers = 0;
11845        final int N = list.size()-1;
11846        for (int i=N; i>=0; i--) {
11847            ProcessRecord r = (ProcessRecord)list.get(i);
11848            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11849                continue;
11850            }
11851            pw.println(String.format("%s%s #%2d: %s",
11852                    prefix, (r.persistent ? persistentLabel : normalLabel),
11853                    i, r.toString()));
11854            if (r.persistent) {
11855                numPers++;
11856            }
11857        }
11858        return numPers;
11859    }
11860
11861    private static final boolean dumpProcessOomList(PrintWriter pw,
11862            ActivityManagerService service, List<ProcessRecord> origList,
11863            String prefix, String normalLabel, String persistentLabel,
11864            boolean inclDetails, String dumpPackage) {
11865
11866        ArrayList<Pair<ProcessRecord, Integer>> list
11867                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11868        for (int i=0; i<origList.size(); i++) {
11869            ProcessRecord r = origList.get(i);
11870            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11871                continue;
11872            }
11873            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11874        }
11875
11876        if (list.size() <= 0) {
11877            return false;
11878        }
11879
11880        Comparator<Pair<ProcessRecord, Integer>> comparator
11881                = new Comparator<Pair<ProcessRecord, Integer>>() {
11882            @Override
11883            public int compare(Pair<ProcessRecord, Integer> object1,
11884                    Pair<ProcessRecord, Integer> object2) {
11885                if (object1.first.setAdj != object2.first.setAdj) {
11886                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11887                }
11888                if (object1.second.intValue() != object2.second.intValue()) {
11889                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11890                }
11891                return 0;
11892            }
11893        };
11894
11895        Collections.sort(list, comparator);
11896
11897        final long curRealtime = SystemClock.elapsedRealtime();
11898        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11899        final long curUptime = SystemClock.uptimeMillis();
11900        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11901
11902        for (int i=list.size()-1; i>=0; i--) {
11903            ProcessRecord r = list.get(i).first;
11904            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11905            char schedGroup;
11906            switch (r.setSchedGroup) {
11907                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11908                    schedGroup = 'B';
11909                    break;
11910                case Process.THREAD_GROUP_DEFAULT:
11911                    schedGroup = 'F';
11912                    break;
11913                default:
11914                    schedGroup = '?';
11915                    break;
11916            }
11917            char foreground;
11918            if (r.foregroundActivities) {
11919                foreground = 'A';
11920            } else if (r.foregroundServices) {
11921                foreground = 'S';
11922            } else {
11923                foreground = ' ';
11924            }
11925            String procState = ProcessList.makeProcStateString(r.curProcState);
11926            pw.print(prefix);
11927            pw.print(r.persistent ? persistentLabel : normalLabel);
11928            pw.print(" #");
11929            int num = (origList.size()-1)-list.get(i).second;
11930            if (num < 10) pw.print(' ');
11931            pw.print(num);
11932            pw.print(": ");
11933            pw.print(oomAdj);
11934            pw.print(' ');
11935            pw.print(schedGroup);
11936            pw.print('/');
11937            pw.print(foreground);
11938            pw.print('/');
11939            pw.print(procState);
11940            pw.print(" trm:");
11941            if (r.trimMemoryLevel < 10) pw.print(' ');
11942            pw.print(r.trimMemoryLevel);
11943            pw.print(' ');
11944            pw.print(r.toShortString());
11945            pw.print(" (");
11946            pw.print(r.adjType);
11947            pw.println(')');
11948            if (r.adjSource != null || r.adjTarget != null) {
11949                pw.print(prefix);
11950                pw.print("    ");
11951                if (r.adjTarget instanceof ComponentName) {
11952                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11953                } else if (r.adjTarget != null) {
11954                    pw.print(r.adjTarget.toString());
11955                } else {
11956                    pw.print("{null}");
11957                }
11958                pw.print("<=");
11959                if (r.adjSource instanceof ProcessRecord) {
11960                    pw.print("Proc{");
11961                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11962                    pw.println("}");
11963                } else if (r.adjSource != null) {
11964                    pw.println(r.adjSource.toString());
11965                } else {
11966                    pw.println("{null}");
11967                }
11968            }
11969            if (inclDetails) {
11970                pw.print(prefix);
11971                pw.print("    ");
11972                pw.print("oom: max="); pw.print(r.maxAdj);
11973                pw.print(" curRaw="); pw.print(r.curRawAdj);
11974                pw.print(" setRaw="); pw.print(r.setRawAdj);
11975                pw.print(" cur="); pw.print(r.curAdj);
11976                pw.print(" set="); pw.println(r.setAdj);
11977                pw.print(prefix);
11978                pw.print("    ");
11979                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
11980                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
11981                pw.print(" lastPss="); pw.print(r.lastPss);
11982                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
11983                pw.print(prefix);
11984                pw.print("    ");
11985                pw.print("keeping="); pw.print(r.keeping);
11986                pw.print(" cached="); pw.print(r.cached);
11987                pw.print(" empty="); pw.print(r.empty);
11988                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
11989
11990                if (!r.keeping) {
11991                    if (r.lastWakeTime != 0) {
11992                        long wtime;
11993                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
11994                        synchronized (stats) {
11995                            wtime = stats.getProcessWakeTime(r.info.uid,
11996                                    r.pid, curRealtime);
11997                        }
11998                        long timeUsed = wtime - r.lastWakeTime;
11999                        pw.print(prefix);
12000                        pw.print("    ");
12001                        pw.print("keep awake over ");
12002                        TimeUtils.formatDuration(realtimeSince, pw);
12003                        pw.print(" used ");
12004                        TimeUtils.formatDuration(timeUsed, pw);
12005                        pw.print(" (");
12006                        pw.print((timeUsed*100)/realtimeSince);
12007                        pw.println("%)");
12008                    }
12009                    if (r.lastCpuTime != 0) {
12010                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12011                        pw.print(prefix);
12012                        pw.print("    ");
12013                        pw.print("run cpu over ");
12014                        TimeUtils.formatDuration(uptimeSince, pw);
12015                        pw.print(" used ");
12016                        TimeUtils.formatDuration(timeUsed, pw);
12017                        pw.print(" (");
12018                        pw.print((timeUsed*100)/uptimeSince);
12019                        pw.println("%)");
12020                    }
12021                }
12022            }
12023        }
12024        return true;
12025    }
12026
12027    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12028        ArrayList<ProcessRecord> procs;
12029        synchronized (this) {
12030            if (args != null && args.length > start
12031                    && args[start].charAt(0) != '-') {
12032                procs = new ArrayList<ProcessRecord>();
12033                int pid = -1;
12034                try {
12035                    pid = Integer.parseInt(args[start]);
12036                } catch (NumberFormatException e) {
12037                }
12038                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12039                    ProcessRecord proc = mLruProcesses.get(i);
12040                    if (proc.pid == pid) {
12041                        procs.add(proc);
12042                    } else if (proc.processName.equals(args[start])) {
12043                        procs.add(proc);
12044                    }
12045                }
12046                if (procs.size() <= 0) {
12047                    return null;
12048                }
12049            } else {
12050                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12051            }
12052        }
12053        return procs;
12054    }
12055
12056    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12057            PrintWriter pw, String[] args) {
12058        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12059        if (procs == null) {
12060            pw.println("No process found for: " + args[0]);
12061            return;
12062        }
12063
12064        long uptime = SystemClock.uptimeMillis();
12065        long realtime = SystemClock.elapsedRealtime();
12066        pw.println("Applications Graphics Acceleration Info:");
12067        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12068
12069        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12070            ProcessRecord r = procs.get(i);
12071            if (r.thread != null) {
12072                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12073                pw.flush();
12074                try {
12075                    TransferPipe tp = new TransferPipe();
12076                    try {
12077                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12078                        tp.go(fd);
12079                    } finally {
12080                        tp.kill();
12081                    }
12082                } catch (IOException e) {
12083                    pw.println("Failure while dumping the app: " + r);
12084                    pw.flush();
12085                } catch (RemoteException e) {
12086                    pw.println("Got a RemoteException while dumping the app " + r);
12087                    pw.flush();
12088                }
12089            }
12090        }
12091    }
12092
12093    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12094        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12095        if (procs == null) {
12096            pw.println("No process found for: " + args[0]);
12097            return;
12098        }
12099
12100        pw.println("Applications Database Info:");
12101
12102        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12103            ProcessRecord r = procs.get(i);
12104            if (r.thread != null) {
12105                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12106                pw.flush();
12107                try {
12108                    TransferPipe tp = new TransferPipe();
12109                    try {
12110                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12111                        tp.go(fd);
12112                    } finally {
12113                        tp.kill();
12114                    }
12115                } catch (IOException e) {
12116                    pw.println("Failure while dumping the app: " + r);
12117                    pw.flush();
12118                } catch (RemoteException e) {
12119                    pw.println("Got a RemoteException while dumping the app " + r);
12120                    pw.flush();
12121                }
12122            }
12123        }
12124    }
12125
12126    final static class MemItem {
12127        final boolean isProc;
12128        final String label;
12129        final String shortLabel;
12130        final long pss;
12131        final int id;
12132        final boolean hasActivities;
12133        ArrayList<MemItem> subitems;
12134
12135        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12136                boolean _hasActivities) {
12137            isProc = true;
12138            label = _label;
12139            shortLabel = _shortLabel;
12140            pss = _pss;
12141            id = _id;
12142            hasActivities = _hasActivities;
12143        }
12144
12145        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12146            isProc = false;
12147            label = _label;
12148            shortLabel = _shortLabel;
12149            pss = _pss;
12150            id = _id;
12151            hasActivities = false;
12152        }
12153    }
12154
12155    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12156            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12157        if (sort && !isCompact) {
12158            Collections.sort(items, new Comparator<MemItem>() {
12159                @Override
12160                public int compare(MemItem lhs, MemItem rhs) {
12161                    if (lhs.pss < rhs.pss) {
12162                        return 1;
12163                    } else if (lhs.pss > rhs.pss) {
12164                        return -1;
12165                    }
12166                    return 0;
12167                }
12168            });
12169        }
12170
12171        for (int i=0; i<items.size(); i++) {
12172            MemItem mi = items.get(i);
12173            if (!isCompact) {
12174                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12175            } else if (mi.isProc) {
12176                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12177                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12178                pw.println(mi.hasActivities ? ",a" : ",e");
12179            } else {
12180                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12181                pw.println(mi.pss);
12182            }
12183            if (mi.subitems != null) {
12184                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12185                        true, isCompact);
12186            }
12187        }
12188    }
12189
12190    // These are in KB.
12191    static final long[] DUMP_MEM_BUCKETS = new long[] {
12192        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12193        120*1024, 160*1024, 200*1024,
12194        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12195        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12196    };
12197
12198    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12199            boolean stackLike) {
12200        int start = label.lastIndexOf('.');
12201        if (start >= 0) start++;
12202        else start = 0;
12203        int end = label.length();
12204        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12205            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12206                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12207                out.append(bucket);
12208                out.append(stackLike ? "MB." : "MB ");
12209                out.append(label, start, end);
12210                return;
12211            }
12212        }
12213        out.append(memKB/1024);
12214        out.append(stackLike ? "MB." : "MB ");
12215        out.append(label, start, end);
12216    }
12217
12218    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12219            ProcessList.NATIVE_ADJ,
12220            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12221            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12222            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12223            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12224            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12225    };
12226    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12227            "Native",
12228            "System", "Persistent", "Foreground",
12229            "Visible", "Perceptible",
12230            "Heavy Weight", "Backup",
12231            "A Services", "Home",
12232            "Previous", "B Services", "Cached"
12233    };
12234    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12235            "native",
12236            "sys", "pers", "fore",
12237            "vis", "percept",
12238            "heavy", "backup",
12239            "servicea", "home",
12240            "prev", "serviceb", "cached"
12241    };
12242
12243    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12244            long realtime, boolean isCheckinRequest, boolean isCompact) {
12245        if (isCheckinRequest || isCompact) {
12246            // short checkin version
12247            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12248        } else {
12249            pw.println("Applications Memory Usage (kB):");
12250            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12251        }
12252    }
12253
12254    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12255            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12256        boolean dumpDetails = false;
12257        boolean dumpFullDetails = false;
12258        boolean dumpDalvik = false;
12259        boolean oomOnly = false;
12260        boolean isCompact = false;
12261        boolean localOnly = false;
12262
12263        int opti = 0;
12264        while (opti < args.length) {
12265            String opt = args[opti];
12266            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12267                break;
12268            }
12269            opti++;
12270            if ("-a".equals(opt)) {
12271                dumpDetails = true;
12272                dumpFullDetails = true;
12273                dumpDalvik = true;
12274            } else if ("-d".equals(opt)) {
12275                dumpDalvik = true;
12276            } else if ("-c".equals(opt)) {
12277                isCompact = true;
12278            } else if ("--oom".equals(opt)) {
12279                oomOnly = true;
12280            } else if ("--local".equals(opt)) {
12281                localOnly = true;
12282            } else if ("-h".equals(opt)) {
12283                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12284                pw.println("  -a: include all available information for each process.");
12285                pw.println("  -d: include dalvik details when dumping process details.");
12286                pw.println("  -c: dump in a compact machine-parseable representation.");
12287                pw.println("  --oom: only show processes organized by oom adj.");
12288                pw.println("  --local: only collect details locally, don't call process.");
12289                pw.println("If [process] is specified it can be the name or ");
12290                pw.println("pid of a specific process to dump.");
12291                return;
12292            } else {
12293                pw.println("Unknown argument: " + opt + "; use -h for help");
12294            }
12295        }
12296
12297        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12298        long uptime = SystemClock.uptimeMillis();
12299        long realtime = SystemClock.elapsedRealtime();
12300        final long[] tmpLong = new long[1];
12301
12302        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12303        if (procs == null) {
12304            // No Java processes.  Maybe they want to print a native process.
12305            if (args != null && args.length > opti
12306                    && args[opti].charAt(0) != '-') {
12307                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12308                        = new ArrayList<ProcessCpuTracker.Stats>();
12309                updateCpuStatsNow();
12310                int findPid = -1;
12311                try {
12312                    findPid = Integer.parseInt(args[opti]);
12313                } catch (NumberFormatException e) {
12314                }
12315                synchronized (mProcessCpuThread) {
12316                    final int N = mProcessCpuTracker.countStats();
12317                    for (int i=0; i<N; i++) {
12318                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12319                        if (st.pid == findPid || (st.baseName != null
12320                                && st.baseName.equals(args[opti]))) {
12321                            nativeProcs.add(st);
12322                        }
12323                    }
12324                }
12325                if (nativeProcs.size() > 0) {
12326                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12327                            isCompact);
12328                    Debug.MemoryInfo mi = null;
12329                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12330                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12331                        final int pid = r.pid;
12332                        if (!isCheckinRequest && dumpDetails) {
12333                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12334                        }
12335                        if (mi == null) {
12336                            mi = new Debug.MemoryInfo();
12337                        }
12338                        if (dumpDetails || (!brief && !oomOnly)) {
12339                            Debug.getMemoryInfo(pid, mi);
12340                        } else {
12341                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12342                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12343                        }
12344                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12345                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12346                        if (isCheckinRequest) {
12347                            pw.println();
12348                        }
12349                    }
12350                    return;
12351                }
12352            }
12353            pw.println("No process found for: " + args[opti]);
12354            return;
12355        }
12356
12357        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12358            dumpDetails = true;
12359        }
12360
12361        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12362
12363        String[] innerArgs = new String[args.length-opti];
12364        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12365
12366        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12367        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12368        long nativePss=0, dalvikPss=0, otherPss=0;
12369        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12370
12371        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12372        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12373                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12374
12375        long totalPss = 0;
12376        long cachedPss = 0;
12377
12378        Debug.MemoryInfo mi = null;
12379        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12380            final ProcessRecord r = procs.get(i);
12381            final IApplicationThread thread;
12382            final int pid;
12383            final int oomAdj;
12384            final boolean hasActivities;
12385            synchronized (this) {
12386                thread = r.thread;
12387                pid = r.pid;
12388                oomAdj = r.getSetAdjWithServices();
12389                hasActivities = r.activities.size() > 0;
12390            }
12391            if (thread != null) {
12392                if (!isCheckinRequest && dumpDetails) {
12393                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12394                }
12395                if (mi == null) {
12396                    mi = new Debug.MemoryInfo();
12397                }
12398                if (dumpDetails || (!brief && !oomOnly)) {
12399                    Debug.getMemoryInfo(pid, mi);
12400                } else {
12401                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12402                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12403                }
12404                if (dumpDetails) {
12405                    if (localOnly) {
12406                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12407                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12408                        if (isCheckinRequest) {
12409                            pw.println();
12410                        }
12411                    } else {
12412                        try {
12413                            pw.flush();
12414                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12415                                    dumpDalvik, innerArgs);
12416                        } catch (RemoteException e) {
12417                            if (!isCheckinRequest) {
12418                                pw.println("Got RemoteException!");
12419                                pw.flush();
12420                            }
12421                        }
12422                    }
12423                }
12424
12425                final long myTotalPss = mi.getTotalPss();
12426                final long myTotalUss = mi.getTotalUss();
12427
12428                synchronized (this) {
12429                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12430                        // Record this for posterity if the process has been stable.
12431                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12432                    }
12433                }
12434
12435                if (!isCheckinRequest && mi != null) {
12436                    totalPss += myTotalPss;
12437                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12438                            (hasActivities ? " / activities)" : ")"),
12439                            r.processName, myTotalPss, pid, hasActivities);
12440                    procMems.add(pssItem);
12441                    procMemsMap.put(pid, pssItem);
12442
12443                    nativePss += mi.nativePss;
12444                    dalvikPss += mi.dalvikPss;
12445                    otherPss += mi.otherPss;
12446                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12447                        long mem = mi.getOtherPss(j);
12448                        miscPss[j] += mem;
12449                        otherPss -= mem;
12450                    }
12451
12452                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12453                        cachedPss += myTotalPss;
12454                    }
12455
12456                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12457                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12458                                || oomIndex == (oomPss.length-1)) {
12459                            oomPss[oomIndex] += myTotalPss;
12460                            if (oomProcs[oomIndex] == null) {
12461                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12462                            }
12463                            oomProcs[oomIndex].add(pssItem);
12464                            break;
12465                        }
12466                    }
12467                }
12468            }
12469        }
12470
12471        if (!isCheckinRequest && procs.size() > 1) {
12472            // If we are showing aggregations, also look for native processes to
12473            // include so that our aggregations are more accurate.
12474            updateCpuStatsNow();
12475            synchronized (mProcessCpuThread) {
12476                final int N = mProcessCpuTracker.countStats();
12477                for (int i=0; i<N; i++) {
12478                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12479                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12480                        if (mi == null) {
12481                            mi = new Debug.MemoryInfo();
12482                        }
12483                        if (!brief && !oomOnly) {
12484                            Debug.getMemoryInfo(st.pid, mi);
12485                        } else {
12486                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12487                            mi.nativePrivateDirty = (int)tmpLong[0];
12488                        }
12489
12490                        final long myTotalPss = mi.getTotalPss();
12491                        totalPss += myTotalPss;
12492
12493                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12494                                st.name, myTotalPss, st.pid, false);
12495                        procMems.add(pssItem);
12496
12497                        nativePss += mi.nativePss;
12498                        dalvikPss += mi.dalvikPss;
12499                        otherPss += mi.otherPss;
12500                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12501                            long mem = mi.getOtherPss(j);
12502                            miscPss[j] += mem;
12503                            otherPss -= mem;
12504                        }
12505                        oomPss[0] += myTotalPss;
12506                        if (oomProcs[0] == null) {
12507                            oomProcs[0] = new ArrayList<MemItem>();
12508                        }
12509                        oomProcs[0].add(pssItem);
12510                    }
12511                }
12512            }
12513
12514            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12515
12516            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12517            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12518            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12519            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12520                String label = Debug.MemoryInfo.getOtherLabel(j);
12521                catMems.add(new MemItem(label, label, miscPss[j], j));
12522            }
12523
12524            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12525            for (int j=0; j<oomPss.length; j++) {
12526                if (oomPss[j] != 0) {
12527                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12528                            : DUMP_MEM_OOM_LABEL[j];
12529                    MemItem item = new MemItem(label, label, oomPss[j],
12530                            DUMP_MEM_OOM_ADJ[j]);
12531                    item.subitems = oomProcs[j];
12532                    oomMems.add(item);
12533                }
12534            }
12535
12536            if (!brief && !oomOnly && !isCompact) {
12537                pw.println();
12538                pw.println("Total PSS by process:");
12539                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12540                pw.println();
12541            }
12542            if (!isCompact) {
12543                pw.println("Total PSS by OOM adjustment:");
12544            }
12545            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12546            if (!brief && !oomOnly) {
12547                PrintWriter out = categoryPw != null ? categoryPw : pw;
12548                if (!isCompact) {
12549                    out.println();
12550                    out.println("Total PSS by category:");
12551                }
12552                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12553            }
12554            if (!isCompact) {
12555                pw.println();
12556            }
12557            MemInfoReader memInfo = new MemInfoReader();
12558            memInfo.readMemInfo();
12559            if (!brief) {
12560                if (!isCompact) {
12561                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12562                    pw.print(" kB (status ");
12563                    switch (mLastMemoryLevel) {
12564                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12565                            pw.println("normal)");
12566                            break;
12567                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12568                            pw.println("moderate)");
12569                            break;
12570                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12571                            pw.println("low)");
12572                            break;
12573                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12574                            pw.println("critical)");
12575                            break;
12576                        default:
12577                            pw.print(mLastMemoryLevel);
12578                            pw.println(")");
12579                            break;
12580                    }
12581                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12582                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12583                            pw.print(cachedPss); pw.print(" cached pss + ");
12584                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12585                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12586                } else {
12587                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12588                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12589                            + memInfo.getFreeSizeKb()); pw.print(",");
12590                    pw.println(totalPss - cachedPss);
12591                }
12592            }
12593            if (!isCompact) {
12594                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12595                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12596                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12597                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12598                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12599                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12600                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12601                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12602                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12603                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12604                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12605            }
12606            if (!brief) {
12607                if (memInfo.getZramTotalSizeKb() != 0) {
12608                    if (!isCompact) {
12609                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12610                                pw.print(" kB physical used for ");
12611                                pw.print(memInfo.getSwapTotalSizeKb()
12612                                        - memInfo.getSwapFreeSizeKb());
12613                                pw.print(" kB in swap (");
12614                                pw.print(memInfo.getSwapTotalSizeKb());
12615                                pw.println(" kB total swap)");
12616                    } else {
12617                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12618                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12619                                pw.println(memInfo.getSwapFreeSizeKb());
12620                    }
12621                }
12622                final int[] SINGLE_LONG_FORMAT = new int[] {
12623                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12624                };
12625                long[] longOut = new long[1];
12626                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12627                        SINGLE_LONG_FORMAT, null, longOut, null);
12628                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12629                longOut[0] = 0;
12630                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12631                        SINGLE_LONG_FORMAT, null, longOut, null);
12632                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12633                longOut[0] = 0;
12634                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12635                        SINGLE_LONG_FORMAT, null, longOut, null);
12636                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12637                longOut[0] = 0;
12638                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12639                        SINGLE_LONG_FORMAT, null, longOut, null);
12640                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12641                if (!isCompact) {
12642                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12643                        pw.print("      KSM: "); pw.print(sharing);
12644                                pw.print(" kB saved from shared ");
12645                                pw.print(shared); pw.println(" kB");
12646                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12647                                pw.print(voltile); pw.println(" kB volatile");
12648                    }
12649                    pw.print("   Tuning: ");
12650                    pw.print(ActivityManager.staticGetMemoryClass());
12651                    pw.print(" (large ");
12652                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12653                    pw.print("), oom ");
12654                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12655                    pw.print(" kB");
12656                    pw.print(", restore limit ");
12657                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12658                    pw.print(" kB");
12659                    if (ActivityManager.isLowRamDeviceStatic()) {
12660                        pw.print(" (low-ram)");
12661                    }
12662                    if (ActivityManager.isHighEndGfx()) {
12663                        pw.print(" (high-end-gfx)");
12664                    }
12665                    pw.println();
12666                } else {
12667                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12668                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12669                    pw.println(voltile);
12670                    pw.print("tuning,");
12671                    pw.print(ActivityManager.staticGetMemoryClass());
12672                    pw.print(',');
12673                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12674                    pw.print(',');
12675                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12676                    if (ActivityManager.isLowRamDeviceStatic()) {
12677                        pw.print(",low-ram");
12678                    }
12679                    if (ActivityManager.isHighEndGfx()) {
12680                        pw.print(",high-end-gfx");
12681                    }
12682                    pw.println();
12683                }
12684            }
12685        }
12686    }
12687
12688    /**
12689     * Searches array of arguments for the specified string
12690     * @param args array of argument strings
12691     * @param value value to search for
12692     * @return true if the value is contained in the array
12693     */
12694    private static boolean scanArgs(String[] args, String value) {
12695        if (args != null) {
12696            for (String arg : args) {
12697                if (value.equals(arg)) {
12698                    return true;
12699                }
12700            }
12701        }
12702        return false;
12703    }
12704
12705    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12706            ContentProviderRecord cpr, boolean always) {
12707        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12708
12709        if (!inLaunching || always) {
12710            synchronized (cpr) {
12711                cpr.launchingApp = null;
12712                cpr.notifyAll();
12713            }
12714            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12715            String names[] = cpr.info.authority.split(";");
12716            for (int j = 0; j < names.length; j++) {
12717                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12718            }
12719        }
12720
12721        for (int i=0; i<cpr.connections.size(); i++) {
12722            ContentProviderConnection conn = cpr.connections.get(i);
12723            if (conn.waiting) {
12724                // If this connection is waiting for the provider, then we don't
12725                // need to mess with its process unless we are always removing
12726                // or for some reason the provider is not currently launching.
12727                if (inLaunching && !always) {
12728                    continue;
12729                }
12730            }
12731            ProcessRecord capp = conn.client;
12732            conn.dead = true;
12733            if (conn.stableCount > 0) {
12734                if (!capp.persistent && capp.thread != null
12735                        && capp.pid != 0
12736                        && capp.pid != MY_PID) {
12737                    killUnneededProcessLocked(capp, "depends on provider "
12738                            + cpr.name.flattenToShortString()
12739                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12740                }
12741            } else if (capp.thread != null && conn.provider.provider != null) {
12742                try {
12743                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12744                } catch (RemoteException e) {
12745                }
12746                // In the protocol here, we don't expect the client to correctly
12747                // clean up this connection, we'll just remove it.
12748                cpr.connections.remove(i);
12749                conn.client.conProviders.remove(conn);
12750            }
12751        }
12752
12753        if (inLaunching && always) {
12754            mLaunchingProviders.remove(cpr);
12755        }
12756        return inLaunching;
12757    }
12758
12759    /**
12760     * Main code for cleaning up a process when it has gone away.  This is
12761     * called both as a result of the process dying, or directly when stopping
12762     * a process when running in single process mode.
12763     */
12764    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12765            boolean restarting, boolean allowRestart, int index) {
12766        if (index >= 0) {
12767            removeLruProcessLocked(app);
12768            ProcessList.remove(app.pid);
12769        }
12770
12771        mProcessesToGc.remove(app);
12772        mPendingPssProcesses.remove(app);
12773
12774        // Dismiss any open dialogs.
12775        if (app.crashDialog != null && !app.forceCrashReport) {
12776            app.crashDialog.dismiss();
12777            app.crashDialog = null;
12778        }
12779        if (app.anrDialog != null) {
12780            app.anrDialog.dismiss();
12781            app.anrDialog = null;
12782        }
12783        if (app.waitDialog != null) {
12784            app.waitDialog.dismiss();
12785            app.waitDialog = null;
12786        }
12787
12788        app.crashing = false;
12789        app.notResponding = false;
12790
12791        app.resetPackageList(mProcessStats);
12792        app.unlinkDeathRecipient();
12793        app.makeInactive(mProcessStats);
12794        app.forcingToForeground = null;
12795        updateProcessForegroundLocked(app, false, false);
12796        app.foregroundActivities = false;
12797        app.hasShownUi = false;
12798        app.treatLikeActivity = false;
12799        app.hasAboveClient = false;
12800        app.hasClientActivities = false;
12801
12802        mServices.killServicesLocked(app, allowRestart);
12803
12804        boolean restart = false;
12805
12806        // Remove published content providers.
12807        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12808            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12809            final boolean always = app.bad || !allowRestart;
12810            if (removeDyingProviderLocked(app, cpr, always) || always) {
12811                // We left the provider in the launching list, need to
12812                // restart it.
12813                restart = true;
12814            }
12815
12816            cpr.provider = null;
12817            cpr.proc = null;
12818        }
12819        app.pubProviders.clear();
12820
12821        // Take care of any launching providers waiting for this process.
12822        if (checkAppInLaunchingProvidersLocked(app, false)) {
12823            restart = true;
12824        }
12825
12826        // Unregister from connected content providers.
12827        if (!app.conProviders.isEmpty()) {
12828            for (int i=0; i<app.conProviders.size(); i++) {
12829                ContentProviderConnection conn = app.conProviders.get(i);
12830                conn.provider.connections.remove(conn);
12831            }
12832            app.conProviders.clear();
12833        }
12834
12835        // At this point there may be remaining entries in mLaunchingProviders
12836        // where we were the only one waiting, so they are no longer of use.
12837        // Look for these and clean up if found.
12838        // XXX Commented out for now.  Trying to figure out a way to reproduce
12839        // the actual situation to identify what is actually going on.
12840        if (false) {
12841            for (int i=0; i<mLaunchingProviders.size(); i++) {
12842                ContentProviderRecord cpr = (ContentProviderRecord)
12843                        mLaunchingProviders.get(i);
12844                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12845                    synchronized (cpr) {
12846                        cpr.launchingApp = null;
12847                        cpr.notifyAll();
12848                    }
12849                }
12850            }
12851        }
12852
12853        skipCurrentReceiverLocked(app);
12854
12855        // Unregister any receivers.
12856        for (int i=app.receivers.size()-1; i>=0; i--) {
12857            removeReceiverLocked(app.receivers.valueAt(i));
12858        }
12859        app.receivers.clear();
12860
12861        // If the app is undergoing backup, tell the backup manager about it
12862        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12863            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12864                    + mBackupTarget.appInfo + " died during backup");
12865            try {
12866                IBackupManager bm = IBackupManager.Stub.asInterface(
12867                        ServiceManager.getService(Context.BACKUP_SERVICE));
12868                bm.agentDisconnected(app.info.packageName);
12869            } catch (RemoteException e) {
12870                // can't happen; backup manager is local
12871            }
12872        }
12873
12874        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12875            ProcessChangeItem item = mPendingProcessChanges.get(i);
12876            if (item.pid == app.pid) {
12877                mPendingProcessChanges.remove(i);
12878                mAvailProcessChanges.add(item);
12879            }
12880        }
12881        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12882
12883        // If the caller is restarting this app, then leave it in its
12884        // current lists and let the caller take care of it.
12885        if (restarting) {
12886            return;
12887        }
12888
12889        if (!app.persistent || app.isolated) {
12890            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12891                    "Removing non-persistent process during cleanup: " + app);
12892            mProcessNames.remove(app.processName, app.uid);
12893            mIsolatedProcesses.remove(app.uid);
12894            if (mHeavyWeightProcess == app) {
12895                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12896                        mHeavyWeightProcess.userId, 0));
12897                mHeavyWeightProcess = null;
12898            }
12899        } else if (!app.removed) {
12900            // This app is persistent, so we need to keep its record around.
12901            // If it is not already on the pending app list, add it there
12902            // and start a new process for it.
12903            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12904                mPersistentStartingProcesses.add(app);
12905                restart = true;
12906            }
12907        }
12908        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12909                "Clean-up removing on hold: " + app);
12910        mProcessesOnHold.remove(app);
12911
12912        if (app == mHomeProcess) {
12913            mHomeProcess = null;
12914        }
12915        if (app == mPreviousProcess) {
12916            mPreviousProcess = null;
12917        }
12918
12919        if (restart && !app.isolated) {
12920            // We have components that still need to be running in the
12921            // process, so re-launch it.
12922            mProcessNames.put(app.processName, app.uid, app);
12923            startProcessLocked(app, "restart", app.processName);
12924        } else if (app.pid > 0 && app.pid != MY_PID) {
12925            // Goodbye!
12926            boolean removed;
12927            synchronized (mPidsSelfLocked) {
12928                mPidsSelfLocked.remove(app.pid);
12929                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12930            }
12931            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
12932                    app.processName, app.info.uid);
12933            if (app.isolated) {
12934                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
12935            }
12936            app.setPid(0);
12937        }
12938    }
12939
12940    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12941        // Look through the content providers we are waiting to have launched,
12942        // and if any run in this process then either schedule a restart of
12943        // the process or kill the client waiting for it if this process has
12944        // gone bad.
12945        int NL = mLaunchingProviders.size();
12946        boolean restart = false;
12947        for (int i=0; i<NL; i++) {
12948            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12949            if (cpr.launchingApp == app) {
12950                if (!alwaysBad && !app.bad) {
12951                    restart = true;
12952                } else {
12953                    removeDyingProviderLocked(app, cpr, true);
12954                    // cpr should have been removed from mLaunchingProviders
12955                    NL = mLaunchingProviders.size();
12956                    i--;
12957                }
12958            }
12959        }
12960        return restart;
12961    }
12962
12963    // =========================================================
12964    // SERVICES
12965    // =========================================================
12966
12967    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12968            int flags) {
12969        enforceNotIsolatedCaller("getServices");
12970        synchronized (this) {
12971            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12972        }
12973    }
12974
12975    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12976        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12977        synchronized (this) {
12978            return mServices.getRunningServiceControlPanelLocked(name);
12979        }
12980    }
12981
12982    public ComponentName startService(IApplicationThread caller, Intent service,
12983            String resolvedType, int userId) {
12984        enforceNotIsolatedCaller("startService");
12985        // Refuse possible leaked file descriptors
12986        if (service != null && service.hasFileDescriptors() == true) {
12987            throw new IllegalArgumentException("File descriptors passed in Intent");
12988        }
12989
12990        if (DEBUG_SERVICE)
12991            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
12992        synchronized(this) {
12993            final int callingPid = Binder.getCallingPid();
12994            final int callingUid = Binder.getCallingUid();
12995            final long origId = Binder.clearCallingIdentity();
12996            ComponentName res = mServices.startServiceLocked(caller, service,
12997                    resolvedType, callingPid, callingUid, userId);
12998            Binder.restoreCallingIdentity(origId);
12999            return res;
13000        }
13001    }
13002
13003    ComponentName startServiceInPackage(int uid,
13004            Intent service, String resolvedType, int userId) {
13005        synchronized(this) {
13006            if (DEBUG_SERVICE)
13007                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13008            final long origId = Binder.clearCallingIdentity();
13009            ComponentName res = mServices.startServiceLocked(null, service,
13010                    resolvedType, -1, uid, userId);
13011            Binder.restoreCallingIdentity(origId);
13012            return res;
13013        }
13014    }
13015
13016    public int stopService(IApplicationThread caller, Intent service,
13017            String resolvedType, int userId) {
13018        enforceNotIsolatedCaller("stopService");
13019        // Refuse possible leaked file descriptors
13020        if (service != null && service.hasFileDescriptors() == true) {
13021            throw new IllegalArgumentException("File descriptors passed in Intent");
13022        }
13023
13024        synchronized(this) {
13025            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13026        }
13027    }
13028
13029    public IBinder peekService(Intent service, String resolvedType) {
13030        enforceNotIsolatedCaller("peekService");
13031        // Refuse possible leaked file descriptors
13032        if (service != null && service.hasFileDescriptors() == true) {
13033            throw new IllegalArgumentException("File descriptors passed in Intent");
13034        }
13035        synchronized(this) {
13036            return mServices.peekServiceLocked(service, resolvedType);
13037        }
13038    }
13039
13040    public boolean stopServiceToken(ComponentName className, IBinder token,
13041            int startId) {
13042        synchronized(this) {
13043            return mServices.stopServiceTokenLocked(className, token, startId);
13044        }
13045    }
13046
13047    public void setServiceForeground(ComponentName className, IBinder token,
13048            int id, Notification notification, boolean removeNotification) {
13049        synchronized(this) {
13050            mServices.setServiceForegroundLocked(className, token, id, notification,
13051                    removeNotification);
13052        }
13053    }
13054
13055    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13056            boolean requireFull, String name, String callerPackage) {
13057        final int callingUserId = UserHandle.getUserId(callingUid);
13058        if (callingUserId != userId) {
13059            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13060                if ((requireFull || checkComponentPermission(
13061                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13062                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
13063                        && checkComponentPermission(
13064                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
13065                                callingPid, callingUid, -1, true)
13066                                != PackageManager.PERMISSION_GRANTED) {
13067                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13068                        // In this case, they would like to just execute as their
13069                        // owner user instead of failing.
13070                        userId = callingUserId;
13071                    } else {
13072                        StringBuilder builder = new StringBuilder(128);
13073                        builder.append("Permission Denial: ");
13074                        builder.append(name);
13075                        if (callerPackage != null) {
13076                            builder.append(" from ");
13077                            builder.append(callerPackage);
13078                        }
13079                        builder.append(" asks to run as user ");
13080                        builder.append(userId);
13081                        builder.append(" but is calling from user ");
13082                        builder.append(UserHandle.getUserId(callingUid));
13083                        builder.append("; this requires ");
13084                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
13085                        if (!requireFull) {
13086                            builder.append(" or ");
13087                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
13088                        }
13089                        String msg = builder.toString();
13090                        Slog.w(TAG, msg);
13091                        throw new SecurityException(msg);
13092                    }
13093                }
13094            }
13095            if (userId == UserHandle.USER_CURRENT
13096                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
13097                // Note that we may be accessing this outside of a lock...
13098                // shouldn't be a big deal, if this is being called outside
13099                // of a locked context there is intrinsically a race with
13100                // the value the caller will receive and someone else changing it.
13101                userId = mCurrentUserId;
13102            }
13103            if (!allowAll && userId < 0) {
13104                throw new IllegalArgumentException(
13105                        "Call does not support special user #" + userId);
13106            }
13107        }
13108        return userId;
13109    }
13110
13111    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13112            String className, int flags) {
13113        boolean result = false;
13114        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13115            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
13116                if (ActivityManager.checkUidPermission(
13117                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13118                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13119                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13120                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13121                            + " requests FLAG_SINGLE_USER, but app does not hold "
13122                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
13123                    Slog.w(TAG, msg);
13124                    throw new SecurityException(msg);
13125                }
13126                result = true;
13127            }
13128        } else if (componentProcessName == aInfo.packageName) {
13129            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13130        } else if ("system".equals(componentProcessName)) {
13131            result = true;
13132        }
13133        if (DEBUG_MU) {
13134            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13135                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13136        }
13137        return result;
13138    }
13139
13140    public int bindService(IApplicationThread caller, IBinder token,
13141            Intent service, String resolvedType,
13142            IServiceConnection connection, int flags, int userId) {
13143        enforceNotIsolatedCaller("bindService");
13144        // Refuse possible leaked file descriptors
13145        if (service != null && service.hasFileDescriptors() == true) {
13146            throw new IllegalArgumentException("File descriptors passed in Intent");
13147        }
13148
13149        synchronized(this) {
13150            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13151                    connection, flags, userId);
13152        }
13153    }
13154
13155    public boolean unbindService(IServiceConnection connection) {
13156        synchronized (this) {
13157            return mServices.unbindServiceLocked(connection);
13158        }
13159    }
13160
13161    public void publishService(IBinder token, Intent intent, IBinder service) {
13162        // Refuse possible leaked file descriptors
13163        if (intent != null && intent.hasFileDescriptors() == true) {
13164            throw new IllegalArgumentException("File descriptors passed in Intent");
13165        }
13166
13167        synchronized(this) {
13168            if (!(token instanceof ServiceRecord)) {
13169                throw new IllegalArgumentException("Invalid service token");
13170            }
13171            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13172        }
13173    }
13174
13175    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13176        // Refuse possible leaked file descriptors
13177        if (intent != null && intent.hasFileDescriptors() == true) {
13178            throw new IllegalArgumentException("File descriptors passed in Intent");
13179        }
13180
13181        synchronized(this) {
13182            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13183        }
13184    }
13185
13186    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13187        synchronized(this) {
13188            if (!(token instanceof ServiceRecord)) {
13189                throw new IllegalArgumentException("Invalid service token");
13190            }
13191            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13192        }
13193    }
13194
13195    // =========================================================
13196    // BACKUP AND RESTORE
13197    // =========================================================
13198
13199    // Cause the target app to be launched if necessary and its backup agent
13200    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13201    // activity manager to announce its creation.
13202    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13203        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13204        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
13205
13206        synchronized(this) {
13207            // !!! TODO: currently no check here that we're already bound
13208            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13209            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13210            synchronized (stats) {
13211                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13212            }
13213
13214            // Backup agent is now in use, its package can't be stopped.
13215            try {
13216                AppGlobals.getPackageManager().setPackageStoppedState(
13217                        app.packageName, false, UserHandle.getUserId(app.uid));
13218            } catch (RemoteException e) {
13219            } catch (IllegalArgumentException e) {
13220                Slog.w(TAG, "Failed trying to unstop package "
13221                        + app.packageName + ": " + e);
13222            }
13223
13224            BackupRecord r = new BackupRecord(ss, app, backupMode);
13225            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13226                    ? new ComponentName(app.packageName, app.backupAgentName)
13227                    : new ComponentName("android", "FullBackupAgent");
13228            // startProcessLocked() returns existing proc's record if it's already running
13229            ProcessRecord proc = startProcessLocked(app.processName, app,
13230                    false, 0, "backup", hostingName, false, false, false);
13231            if (proc == null) {
13232                Slog.e(TAG, "Unable to start backup agent process " + r);
13233                return false;
13234            }
13235
13236            r.app = proc;
13237            mBackupTarget = r;
13238            mBackupAppName = app.packageName;
13239
13240            // Try not to kill the process during backup
13241            updateOomAdjLocked(proc);
13242
13243            // If the process is already attached, schedule the creation of the backup agent now.
13244            // If it is not yet live, this will be done when it attaches to the framework.
13245            if (proc.thread != null) {
13246                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13247                try {
13248                    proc.thread.scheduleCreateBackupAgent(app,
13249                            compatibilityInfoForPackageLocked(app), backupMode);
13250                } catch (RemoteException e) {
13251                    // Will time out on the backup manager side
13252                }
13253            } else {
13254                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13255            }
13256            // Invariants: at this point, the target app process exists and the application
13257            // is either already running or in the process of coming up.  mBackupTarget and
13258            // mBackupAppName describe the app, so that when it binds back to the AM we
13259            // know that it's scheduled for a backup-agent operation.
13260        }
13261
13262        return true;
13263    }
13264
13265    @Override
13266    public void clearPendingBackup() {
13267        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13268        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13269
13270        synchronized (this) {
13271            mBackupTarget = null;
13272            mBackupAppName = null;
13273        }
13274    }
13275
13276    // A backup agent has just come up
13277    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13278        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13279                + " = " + agent);
13280
13281        synchronized(this) {
13282            if (!agentPackageName.equals(mBackupAppName)) {
13283                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13284                return;
13285            }
13286        }
13287
13288        long oldIdent = Binder.clearCallingIdentity();
13289        try {
13290            IBackupManager bm = IBackupManager.Stub.asInterface(
13291                    ServiceManager.getService(Context.BACKUP_SERVICE));
13292            bm.agentConnected(agentPackageName, agent);
13293        } catch (RemoteException e) {
13294            // can't happen; the backup manager service is local
13295        } catch (Exception e) {
13296            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13297            e.printStackTrace();
13298        } finally {
13299            Binder.restoreCallingIdentity(oldIdent);
13300        }
13301    }
13302
13303    // done with this agent
13304    public void unbindBackupAgent(ApplicationInfo appInfo) {
13305        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13306        if (appInfo == null) {
13307            Slog.w(TAG, "unbind backup agent for null app");
13308            return;
13309        }
13310
13311        synchronized(this) {
13312            try {
13313                if (mBackupAppName == null) {
13314                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13315                    return;
13316                }
13317
13318                if (!mBackupAppName.equals(appInfo.packageName)) {
13319                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13320                    return;
13321                }
13322
13323                // Not backing this app up any more; reset its OOM adjustment
13324                final ProcessRecord proc = mBackupTarget.app;
13325                updateOomAdjLocked(proc);
13326
13327                // If the app crashed during backup, 'thread' will be null here
13328                if (proc.thread != null) {
13329                    try {
13330                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13331                                compatibilityInfoForPackageLocked(appInfo));
13332                    } catch (Exception e) {
13333                        Slog.e(TAG, "Exception when unbinding backup agent:");
13334                        e.printStackTrace();
13335                    }
13336                }
13337            } finally {
13338                mBackupTarget = null;
13339                mBackupAppName = null;
13340            }
13341        }
13342    }
13343    // =========================================================
13344    // BROADCASTS
13345    // =========================================================
13346
13347    private final List getStickiesLocked(String action, IntentFilter filter,
13348            List cur, int userId) {
13349        final ContentResolver resolver = mContext.getContentResolver();
13350        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13351        if (stickies == null) {
13352            return cur;
13353        }
13354        final ArrayList<Intent> list = stickies.get(action);
13355        if (list == null) {
13356            return cur;
13357        }
13358        int N = list.size();
13359        for (int i=0; i<N; i++) {
13360            Intent intent = list.get(i);
13361            if (filter.match(resolver, intent, true, TAG) >= 0) {
13362                if (cur == null) {
13363                    cur = new ArrayList<Intent>();
13364                }
13365                cur.add(intent);
13366            }
13367        }
13368        return cur;
13369    }
13370
13371    boolean isPendingBroadcastProcessLocked(int pid) {
13372        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13373                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13374    }
13375
13376    void skipPendingBroadcastLocked(int pid) {
13377            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13378            for (BroadcastQueue queue : mBroadcastQueues) {
13379                queue.skipPendingBroadcastLocked(pid);
13380            }
13381    }
13382
13383    // The app just attached; send any pending broadcasts that it should receive
13384    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13385        boolean didSomething = false;
13386        for (BroadcastQueue queue : mBroadcastQueues) {
13387            didSomething |= queue.sendPendingBroadcastsLocked(app);
13388        }
13389        return didSomething;
13390    }
13391
13392    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13393            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13394        enforceNotIsolatedCaller("registerReceiver");
13395        int callingUid;
13396        int callingPid;
13397        synchronized(this) {
13398            ProcessRecord callerApp = null;
13399            if (caller != null) {
13400                callerApp = getRecordForAppLocked(caller);
13401                if (callerApp == null) {
13402                    throw new SecurityException(
13403                            "Unable to find app for caller " + caller
13404                            + " (pid=" + Binder.getCallingPid()
13405                            + ") when registering receiver " + receiver);
13406                }
13407                if (callerApp.info.uid != Process.SYSTEM_UID &&
13408                        !callerApp.pkgList.containsKey(callerPackage) &&
13409                        !"android".equals(callerPackage)) {
13410                    throw new SecurityException("Given caller package " + callerPackage
13411                            + " is not running in process " + callerApp);
13412                }
13413                callingUid = callerApp.info.uid;
13414                callingPid = callerApp.pid;
13415            } else {
13416                callerPackage = null;
13417                callingUid = Binder.getCallingUid();
13418                callingPid = Binder.getCallingPid();
13419            }
13420
13421            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13422                    true, true, "registerReceiver", callerPackage);
13423
13424            List allSticky = null;
13425
13426            // Look for any matching sticky broadcasts...
13427            Iterator actions = filter.actionsIterator();
13428            if (actions != null) {
13429                while (actions.hasNext()) {
13430                    String action = (String)actions.next();
13431                    allSticky = getStickiesLocked(action, filter, allSticky,
13432                            UserHandle.USER_ALL);
13433                    allSticky = getStickiesLocked(action, filter, allSticky,
13434                            UserHandle.getUserId(callingUid));
13435                }
13436            } else {
13437                allSticky = getStickiesLocked(null, filter, allSticky,
13438                        UserHandle.USER_ALL);
13439                allSticky = getStickiesLocked(null, filter, allSticky,
13440                        UserHandle.getUserId(callingUid));
13441            }
13442
13443            // The first sticky in the list is returned directly back to
13444            // the client.
13445            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13446
13447            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13448                    + ": " + sticky);
13449
13450            if (receiver == null) {
13451                return sticky;
13452            }
13453
13454            ReceiverList rl
13455                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13456            if (rl == null) {
13457                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13458                        userId, receiver);
13459                if (rl.app != null) {
13460                    rl.app.receivers.add(rl);
13461                } else {
13462                    try {
13463                        receiver.asBinder().linkToDeath(rl, 0);
13464                    } catch (RemoteException e) {
13465                        return sticky;
13466                    }
13467                    rl.linkedToDeath = true;
13468                }
13469                mRegisteredReceivers.put(receiver.asBinder(), rl);
13470            } else if (rl.uid != callingUid) {
13471                throw new IllegalArgumentException(
13472                        "Receiver requested to register for uid " + callingUid
13473                        + " was previously registered for uid " + rl.uid);
13474            } else if (rl.pid != callingPid) {
13475                throw new IllegalArgumentException(
13476                        "Receiver requested to register for pid " + callingPid
13477                        + " was previously registered for pid " + rl.pid);
13478            } else if (rl.userId != userId) {
13479                throw new IllegalArgumentException(
13480                        "Receiver requested to register for user " + userId
13481                        + " was previously registered for user " + rl.userId);
13482            }
13483            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13484                    permission, callingUid, userId);
13485            rl.add(bf);
13486            if (!bf.debugCheck()) {
13487                Slog.w(TAG, "==> For Dynamic broadast");
13488            }
13489            mReceiverResolver.addFilter(bf);
13490
13491            // Enqueue broadcasts for all existing stickies that match
13492            // this filter.
13493            if (allSticky != null) {
13494                ArrayList receivers = new ArrayList();
13495                receivers.add(bf);
13496
13497                int N = allSticky.size();
13498                for (int i=0; i<N; i++) {
13499                    Intent intent = (Intent)allSticky.get(i);
13500                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13501                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13502                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13503                            null, null, false, true, true, -1);
13504                    queue.enqueueParallelBroadcastLocked(r);
13505                    queue.scheduleBroadcastsLocked();
13506                }
13507            }
13508
13509            return sticky;
13510        }
13511    }
13512
13513    public void unregisterReceiver(IIntentReceiver receiver) {
13514        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13515
13516        final long origId = Binder.clearCallingIdentity();
13517        try {
13518            boolean doTrim = false;
13519
13520            synchronized(this) {
13521                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13522                if (rl != null) {
13523                    if (rl.curBroadcast != null) {
13524                        BroadcastRecord r = rl.curBroadcast;
13525                        final boolean doNext = finishReceiverLocked(
13526                                receiver.asBinder(), r.resultCode, r.resultData,
13527                                r.resultExtras, r.resultAbort);
13528                        if (doNext) {
13529                            doTrim = true;
13530                            r.queue.processNextBroadcast(false);
13531                        }
13532                    }
13533
13534                    if (rl.app != null) {
13535                        rl.app.receivers.remove(rl);
13536                    }
13537                    removeReceiverLocked(rl);
13538                    if (rl.linkedToDeath) {
13539                        rl.linkedToDeath = false;
13540                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13541                    }
13542                }
13543            }
13544
13545            // If we actually concluded any broadcasts, we might now be able
13546            // to trim the recipients' apps from our working set
13547            if (doTrim) {
13548                trimApplications();
13549                return;
13550            }
13551
13552        } finally {
13553            Binder.restoreCallingIdentity(origId);
13554        }
13555    }
13556
13557    void removeReceiverLocked(ReceiverList rl) {
13558        mRegisteredReceivers.remove(rl.receiver.asBinder());
13559        int N = rl.size();
13560        for (int i=0; i<N; i++) {
13561            mReceiverResolver.removeFilter(rl.get(i));
13562        }
13563    }
13564
13565    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13566        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13567            ProcessRecord r = mLruProcesses.get(i);
13568            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13569                try {
13570                    r.thread.dispatchPackageBroadcast(cmd, packages);
13571                } catch (RemoteException ex) {
13572                }
13573            }
13574        }
13575    }
13576
13577    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13578            int[] users) {
13579        List<ResolveInfo> receivers = null;
13580        try {
13581            HashSet<ComponentName> singleUserReceivers = null;
13582            boolean scannedFirstReceivers = false;
13583            for (int user : users) {
13584                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13585                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13586                if (user != 0 && newReceivers != null) {
13587                    // If this is not the primary user, we need to check for
13588                    // any receivers that should be filtered out.
13589                    for (int i=0; i<newReceivers.size(); i++) {
13590                        ResolveInfo ri = newReceivers.get(i);
13591                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13592                            newReceivers.remove(i);
13593                            i--;
13594                        }
13595                    }
13596                }
13597                if (newReceivers != null && newReceivers.size() == 0) {
13598                    newReceivers = null;
13599                }
13600                if (receivers == null) {
13601                    receivers = newReceivers;
13602                } else if (newReceivers != null) {
13603                    // We need to concatenate the additional receivers
13604                    // found with what we have do far.  This would be easy,
13605                    // but we also need to de-dup any receivers that are
13606                    // singleUser.
13607                    if (!scannedFirstReceivers) {
13608                        // Collect any single user receivers we had already retrieved.
13609                        scannedFirstReceivers = true;
13610                        for (int i=0; i<receivers.size(); i++) {
13611                            ResolveInfo ri = receivers.get(i);
13612                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13613                                ComponentName cn = new ComponentName(
13614                                        ri.activityInfo.packageName, ri.activityInfo.name);
13615                                if (singleUserReceivers == null) {
13616                                    singleUserReceivers = new HashSet<ComponentName>();
13617                                }
13618                                singleUserReceivers.add(cn);
13619                            }
13620                        }
13621                    }
13622                    // Add the new results to the existing results, tracking
13623                    // and de-dupping single user receivers.
13624                    for (int i=0; i<newReceivers.size(); i++) {
13625                        ResolveInfo ri = newReceivers.get(i);
13626                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13627                            ComponentName cn = new ComponentName(
13628                                    ri.activityInfo.packageName, ri.activityInfo.name);
13629                            if (singleUserReceivers == null) {
13630                                singleUserReceivers = new HashSet<ComponentName>();
13631                            }
13632                            if (!singleUserReceivers.contains(cn)) {
13633                                singleUserReceivers.add(cn);
13634                                receivers.add(ri);
13635                            }
13636                        } else {
13637                            receivers.add(ri);
13638                        }
13639                    }
13640                }
13641            }
13642        } catch (RemoteException ex) {
13643            // pm is in same process, this will never happen.
13644        }
13645        return receivers;
13646    }
13647
13648    private final int broadcastIntentLocked(ProcessRecord callerApp,
13649            String callerPackage, Intent intent, String resolvedType,
13650            IIntentReceiver resultTo, int resultCode, String resultData,
13651            Bundle map, String requiredPermission, int appOp,
13652            boolean ordered, boolean sticky, int callingPid, int callingUid,
13653            int userId) {
13654        intent = new Intent(intent);
13655
13656        // By default broadcasts do not go to stopped apps.
13657        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13658
13659        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13660            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13661            + " ordered=" + ordered + " userid=" + userId);
13662        if ((resultTo != null) && !ordered) {
13663            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13664        }
13665
13666        userId = handleIncomingUser(callingPid, callingUid, userId,
13667                true, false, "broadcast", callerPackage);
13668
13669        // Make sure that the user who is receiving this broadcast is started.
13670        // If not, we will just skip it.
13671        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13672            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13673                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13674                Slog.w(TAG, "Skipping broadcast of " + intent
13675                        + ": user " + userId + " is stopped");
13676                return ActivityManager.BROADCAST_SUCCESS;
13677            }
13678        }
13679
13680        /*
13681         * Prevent non-system code (defined here to be non-persistent
13682         * processes) from sending protected broadcasts.
13683         */
13684        int callingAppId = UserHandle.getAppId(callingUid);
13685        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13686            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13687            callingUid == 0) {
13688            // Always okay.
13689        } else if (callerApp == null || !callerApp.persistent) {
13690            try {
13691                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13692                        intent.getAction())) {
13693                    String msg = "Permission Denial: not allowed to send broadcast "
13694                            + intent.getAction() + " from pid="
13695                            + callingPid + ", uid=" + callingUid;
13696                    Slog.w(TAG, msg);
13697                    throw new SecurityException(msg);
13698                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13699                    // Special case for compatibility: we don't want apps to send this,
13700                    // but historically it has not been protected and apps may be using it
13701                    // to poke their own app widget.  So, instead of making it protected,
13702                    // just limit it to the caller.
13703                    if (callerApp == null) {
13704                        String msg = "Permission Denial: not allowed to send broadcast "
13705                                + intent.getAction() + " from unknown caller.";
13706                        Slog.w(TAG, msg);
13707                        throw new SecurityException(msg);
13708                    } else if (intent.getComponent() != null) {
13709                        // They are good enough to send to an explicit component...  verify
13710                        // it is being sent to the calling app.
13711                        if (!intent.getComponent().getPackageName().equals(
13712                                callerApp.info.packageName)) {
13713                            String msg = "Permission Denial: not allowed to send broadcast "
13714                                    + intent.getAction() + " to "
13715                                    + intent.getComponent().getPackageName() + " from "
13716                                    + callerApp.info.packageName;
13717                            Slog.w(TAG, msg);
13718                            throw new SecurityException(msg);
13719                        }
13720                    } else {
13721                        // Limit broadcast to their own package.
13722                        intent.setPackage(callerApp.info.packageName);
13723                    }
13724                }
13725            } catch (RemoteException e) {
13726                Slog.w(TAG, "Remote exception", e);
13727                return ActivityManager.BROADCAST_SUCCESS;
13728            }
13729        }
13730
13731        // Handle special intents: if this broadcast is from the package
13732        // manager about a package being removed, we need to remove all of
13733        // its activities from the history stack.
13734        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13735                intent.getAction());
13736        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13737                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13738                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13739                || uidRemoved) {
13740            if (checkComponentPermission(
13741                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13742                    callingPid, callingUid, -1, true)
13743                    == PackageManager.PERMISSION_GRANTED) {
13744                if (uidRemoved) {
13745                    final Bundle intentExtras = intent.getExtras();
13746                    final int uid = intentExtras != null
13747                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13748                    if (uid >= 0) {
13749                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13750                        synchronized (bs) {
13751                            bs.removeUidStatsLocked(uid);
13752                        }
13753                        mAppOpsService.uidRemoved(uid);
13754                    }
13755                } else {
13756                    // If resources are unavailable just force stop all
13757                    // those packages and flush the attribute cache as well.
13758                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13759                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13760                        if (list != null && (list.length > 0)) {
13761                            for (String pkg : list) {
13762                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13763                                        "storage unmount");
13764                            }
13765                            sendPackageBroadcastLocked(
13766                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13767                        }
13768                    } else {
13769                        Uri data = intent.getData();
13770                        String ssp;
13771                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13772                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13773                                    intent.getAction());
13774                            boolean fullUninstall = removed &&
13775                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13776                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13777                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13778                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13779                                        false, fullUninstall, userId,
13780                                        removed ? "pkg removed" : "pkg changed");
13781                            }
13782                            if (removed) {
13783                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13784                                        new String[] {ssp}, userId);
13785                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13786                                    mAppOpsService.packageRemoved(
13787                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13788
13789                                    // Remove all permissions granted from/to this package
13790                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13791                                }
13792                            }
13793                        }
13794                    }
13795                }
13796            } else {
13797                String msg = "Permission Denial: " + intent.getAction()
13798                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13799                        + ", uid=" + callingUid + ")"
13800                        + " requires "
13801                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13802                Slog.w(TAG, msg);
13803                throw new SecurityException(msg);
13804            }
13805
13806        // Special case for adding a package: by default turn on compatibility
13807        // mode.
13808        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13809            Uri data = intent.getData();
13810            String ssp;
13811            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13812                mCompatModePackages.handlePackageAddedLocked(ssp,
13813                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13814            }
13815        }
13816
13817        /*
13818         * If this is the time zone changed action, queue up a message that will reset the timezone
13819         * of all currently running processes. This message will get queued up before the broadcast
13820         * happens.
13821         */
13822        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13823            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13824        }
13825
13826        /*
13827         * If the user set the time, let all running processes know.
13828         */
13829        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
13830            final int is24Hour = intent.getBooleanExtra(
13831                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
13832            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
13833        }
13834
13835        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13836            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13837        }
13838
13839        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13840            ProxyInfo proxy = intent.getParcelableExtra("proxy");
13841            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13842        }
13843
13844        // Add to the sticky list if requested.
13845        if (sticky) {
13846            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13847                    callingPid, callingUid)
13848                    != PackageManager.PERMISSION_GRANTED) {
13849                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13850                        + callingPid + ", uid=" + callingUid
13851                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13852                Slog.w(TAG, msg);
13853                throw new SecurityException(msg);
13854            }
13855            if (requiredPermission != null) {
13856                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13857                        + " and enforce permission " + requiredPermission);
13858                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13859            }
13860            if (intent.getComponent() != null) {
13861                throw new SecurityException(
13862                        "Sticky broadcasts can't target a specific component");
13863            }
13864            // We use userId directly here, since the "all" target is maintained
13865            // as a separate set of sticky broadcasts.
13866            if (userId != UserHandle.USER_ALL) {
13867                // But first, if this is not a broadcast to all users, then
13868                // make sure it doesn't conflict with an existing broadcast to
13869                // all users.
13870                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13871                        UserHandle.USER_ALL);
13872                if (stickies != null) {
13873                    ArrayList<Intent> list = stickies.get(intent.getAction());
13874                    if (list != null) {
13875                        int N = list.size();
13876                        int i;
13877                        for (i=0; i<N; i++) {
13878                            if (intent.filterEquals(list.get(i))) {
13879                                throw new IllegalArgumentException(
13880                                        "Sticky broadcast " + intent + " for user "
13881                                        + userId + " conflicts with existing global broadcast");
13882                            }
13883                        }
13884                    }
13885                }
13886            }
13887            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13888            if (stickies == null) {
13889                stickies = new ArrayMap<String, ArrayList<Intent>>();
13890                mStickyBroadcasts.put(userId, stickies);
13891            }
13892            ArrayList<Intent> list = stickies.get(intent.getAction());
13893            if (list == null) {
13894                list = new ArrayList<Intent>();
13895                stickies.put(intent.getAction(), list);
13896            }
13897            int N = list.size();
13898            int i;
13899            for (i=0; i<N; i++) {
13900                if (intent.filterEquals(list.get(i))) {
13901                    // This sticky already exists, replace it.
13902                    list.set(i, new Intent(intent));
13903                    break;
13904                }
13905            }
13906            if (i >= N) {
13907                list.add(new Intent(intent));
13908            }
13909        }
13910
13911        int[] users;
13912        if (userId == UserHandle.USER_ALL) {
13913            // Caller wants broadcast to go to all started users.
13914            users = mStartedUserArray;
13915        } else {
13916            // Caller wants broadcast to go to one specific user.
13917            users = new int[] {userId};
13918        }
13919
13920        // Figure out who all will receive this broadcast.
13921        List receivers = null;
13922        List<BroadcastFilter> registeredReceivers = null;
13923        // Need to resolve the intent to interested receivers...
13924        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13925                 == 0) {
13926            receivers = collectReceiverComponents(intent, resolvedType, users);
13927        }
13928        if (intent.getComponent() == null) {
13929            registeredReceivers = mReceiverResolver.queryIntent(intent,
13930                    resolvedType, false, userId);
13931        }
13932
13933        final boolean replacePending =
13934                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13935
13936        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13937                + " replacePending=" + replacePending);
13938
13939        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13940        if (!ordered && NR > 0) {
13941            // If we are not serializing this broadcast, then send the
13942            // registered receivers separately so they don't wait for the
13943            // components to be launched.
13944            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13945            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13946                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13947                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13948                    ordered, sticky, false, userId);
13949            if (DEBUG_BROADCAST) Slog.v(
13950                    TAG, "Enqueueing parallel broadcast " + r);
13951            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13952            if (!replaced) {
13953                queue.enqueueParallelBroadcastLocked(r);
13954                queue.scheduleBroadcastsLocked();
13955            }
13956            registeredReceivers = null;
13957            NR = 0;
13958        }
13959
13960        // Merge into one list.
13961        int ir = 0;
13962        if (receivers != null) {
13963            // A special case for PACKAGE_ADDED: do not allow the package
13964            // being added to see this broadcast.  This prevents them from
13965            // using this as a back door to get run as soon as they are
13966            // installed.  Maybe in the future we want to have a special install
13967            // broadcast or such for apps, but we'd like to deliberately make
13968            // this decision.
13969            String skipPackages[] = null;
13970            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13971                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13972                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13973                Uri data = intent.getData();
13974                if (data != null) {
13975                    String pkgName = data.getSchemeSpecificPart();
13976                    if (pkgName != null) {
13977                        skipPackages = new String[] { pkgName };
13978                    }
13979                }
13980            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13981                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13982            }
13983            if (skipPackages != null && (skipPackages.length > 0)) {
13984                for (String skipPackage : skipPackages) {
13985                    if (skipPackage != null) {
13986                        int NT = receivers.size();
13987                        for (int it=0; it<NT; it++) {
13988                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
13989                            if (curt.activityInfo.packageName.equals(skipPackage)) {
13990                                receivers.remove(it);
13991                                it--;
13992                                NT--;
13993                            }
13994                        }
13995                    }
13996                }
13997            }
13998
13999            int NT = receivers != null ? receivers.size() : 0;
14000            int it = 0;
14001            ResolveInfo curt = null;
14002            BroadcastFilter curr = null;
14003            while (it < NT && ir < NR) {
14004                if (curt == null) {
14005                    curt = (ResolveInfo)receivers.get(it);
14006                }
14007                if (curr == null) {
14008                    curr = registeredReceivers.get(ir);
14009                }
14010                if (curr.getPriority() >= curt.priority) {
14011                    // Insert this broadcast record into the final list.
14012                    receivers.add(it, curr);
14013                    ir++;
14014                    curr = null;
14015                    it++;
14016                    NT++;
14017                } else {
14018                    // Skip to the next ResolveInfo in the final list.
14019                    it++;
14020                    curt = null;
14021                }
14022            }
14023        }
14024        while (ir < NR) {
14025            if (receivers == null) {
14026                receivers = new ArrayList();
14027            }
14028            receivers.add(registeredReceivers.get(ir));
14029            ir++;
14030        }
14031
14032        if ((receivers != null && receivers.size() > 0)
14033                || resultTo != null) {
14034            BroadcastQueue queue = broadcastQueueForIntent(intent);
14035            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14036                    callerPackage, callingPid, callingUid, resolvedType,
14037                    requiredPermission, appOp, receivers, resultTo, resultCode,
14038                    resultData, map, ordered, sticky, false, userId);
14039            if (DEBUG_BROADCAST) Slog.v(
14040                    TAG, "Enqueueing ordered broadcast " + r
14041                    + ": prev had " + queue.mOrderedBroadcasts.size());
14042            if (DEBUG_BROADCAST) {
14043                int seq = r.intent.getIntExtra("seq", -1);
14044                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14045            }
14046            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14047            if (!replaced) {
14048                queue.enqueueOrderedBroadcastLocked(r);
14049                queue.scheduleBroadcastsLocked();
14050            }
14051        }
14052
14053        return ActivityManager.BROADCAST_SUCCESS;
14054    }
14055
14056    final Intent verifyBroadcastLocked(Intent intent) {
14057        // Refuse possible leaked file descriptors
14058        if (intent != null && intent.hasFileDescriptors() == true) {
14059            throw new IllegalArgumentException("File descriptors passed in Intent");
14060        }
14061
14062        int flags = intent.getFlags();
14063
14064        if (!mProcessesReady) {
14065            // if the caller really truly claims to know what they're doing, go
14066            // ahead and allow the broadcast without launching any receivers
14067            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14068                intent = new Intent(intent);
14069                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14070            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14071                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14072                        + " before boot completion");
14073                throw new IllegalStateException("Cannot broadcast before boot completed");
14074            }
14075        }
14076
14077        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14078            throw new IllegalArgumentException(
14079                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14080        }
14081
14082        return intent;
14083    }
14084
14085    public final int broadcastIntent(IApplicationThread caller,
14086            Intent intent, String resolvedType, IIntentReceiver resultTo,
14087            int resultCode, String resultData, Bundle map,
14088            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14089        enforceNotIsolatedCaller("broadcastIntent");
14090        synchronized(this) {
14091            intent = verifyBroadcastLocked(intent);
14092
14093            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14094            final int callingPid = Binder.getCallingPid();
14095            final int callingUid = Binder.getCallingUid();
14096            final long origId = Binder.clearCallingIdentity();
14097            int res = broadcastIntentLocked(callerApp,
14098                    callerApp != null ? callerApp.info.packageName : null,
14099                    intent, resolvedType, resultTo,
14100                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14101                    callingPid, callingUid, userId);
14102            Binder.restoreCallingIdentity(origId);
14103            return res;
14104        }
14105    }
14106
14107    int broadcastIntentInPackage(String packageName, int uid,
14108            Intent intent, String resolvedType, IIntentReceiver resultTo,
14109            int resultCode, String resultData, Bundle map,
14110            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14111        synchronized(this) {
14112            intent = verifyBroadcastLocked(intent);
14113
14114            final long origId = Binder.clearCallingIdentity();
14115            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14116                    resultTo, resultCode, resultData, map, requiredPermission,
14117                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14118            Binder.restoreCallingIdentity(origId);
14119            return res;
14120        }
14121    }
14122
14123    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14124        // Refuse possible leaked file descriptors
14125        if (intent != null && intent.hasFileDescriptors() == true) {
14126            throw new IllegalArgumentException("File descriptors passed in Intent");
14127        }
14128
14129        userId = handleIncomingUser(Binder.getCallingPid(),
14130                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
14131
14132        synchronized(this) {
14133            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14134                    != PackageManager.PERMISSION_GRANTED) {
14135                String msg = "Permission Denial: unbroadcastIntent() from pid="
14136                        + Binder.getCallingPid()
14137                        + ", uid=" + Binder.getCallingUid()
14138                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14139                Slog.w(TAG, msg);
14140                throw new SecurityException(msg);
14141            }
14142            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14143            if (stickies != null) {
14144                ArrayList<Intent> list = stickies.get(intent.getAction());
14145                if (list != null) {
14146                    int N = list.size();
14147                    int i;
14148                    for (i=0; i<N; i++) {
14149                        if (intent.filterEquals(list.get(i))) {
14150                            list.remove(i);
14151                            break;
14152                        }
14153                    }
14154                    if (list.size() <= 0) {
14155                        stickies.remove(intent.getAction());
14156                    }
14157                }
14158                if (stickies.size() <= 0) {
14159                    mStickyBroadcasts.remove(userId);
14160                }
14161            }
14162        }
14163    }
14164
14165    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14166            String resultData, Bundle resultExtras, boolean resultAbort) {
14167        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14168        if (r == null) {
14169            Slog.w(TAG, "finishReceiver called but not found on queue");
14170            return false;
14171        }
14172
14173        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14174    }
14175
14176    void backgroundServicesFinishedLocked(int userId) {
14177        for (BroadcastQueue queue : mBroadcastQueues) {
14178            queue.backgroundServicesFinishedLocked(userId);
14179        }
14180    }
14181
14182    public void finishReceiver(IBinder who, int resultCode, String resultData,
14183            Bundle resultExtras, boolean resultAbort) {
14184        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14185
14186        // Refuse possible leaked file descriptors
14187        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14188            throw new IllegalArgumentException("File descriptors passed in Bundle");
14189        }
14190
14191        final long origId = Binder.clearCallingIdentity();
14192        try {
14193            boolean doNext = false;
14194            BroadcastRecord r;
14195
14196            synchronized(this) {
14197                r = broadcastRecordForReceiverLocked(who);
14198                if (r != null) {
14199                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14200                        resultData, resultExtras, resultAbort, true);
14201                }
14202            }
14203
14204            if (doNext) {
14205                r.queue.processNextBroadcast(false);
14206            }
14207            trimApplications();
14208        } finally {
14209            Binder.restoreCallingIdentity(origId);
14210        }
14211    }
14212
14213    // =========================================================
14214    // INSTRUMENTATION
14215    // =========================================================
14216
14217    public boolean startInstrumentation(ComponentName className,
14218            String profileFile, int flags, Bundle arguments,
14219            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14220            int userId) {
14221        enforceNotIsolatedCaller("startInstrumentation");
14222        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14223                userId, false, true, "startInstrumentation", null);
14224        // Refuse possible leaked file descriptors
14225        if (arguments != null && arguments.hasFileDescriptors()) {
14226            throw new IllegalArgumentException("File descriptors passed in Bundle");
14227        }
14228
14229        synchronized(this) {
14230            InstrumentationInfo ii = null;
14231            ApplicationInfo ai = null;
14232            try {
14233                ii = mContext.getPackageManager().getInstrumentationInfo(
14234                    className, STOCK_PM_FLAGS);
14235                ai = AppGlobals.getPackageManager().getApplicationInfo(
14236                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14237            } catch (PackageManager.NameNotFoundException e) {
14238            } catch (RemoteException e) {
14239            }
14240            if (ii == null) {
14241                reportStartInstrumentationFailure(watcher, className,
14242                        "Unable to find instrumentation info for: " + className);
14243                return false;
14244            }
14245            if (ai == null) {
14246                reportStartInstrumentationFailure(watcher, className,
14247                        "Unable to find instrumentation target package: " + ii.targetPackage);
14248                return false;
14249            }
14250
14251            int match = mContext.getPackageManager().checkSignatures(
14252                    ii.targetPackage, ii.packageName);
14253            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14254                String msg = "Permission Denial: starting instrumentation "
14255                        + className + " from pid="
14256                        + Binder.getCallingPid()
14257                        + ", uid=" + Binder.getCallingPid()
14258                        + " not allowed because package " + ii.packageName
14259                        + " does not have a signature matching the target "
14260                        + ii.targetPackage;
14261                reportStartInstrumentationFailure(watcher, className, msg);
14262                throw new SecurityException(msg);
14263            }
14264
14265            final long origId = Binder.clearCallingIdentity();
14266            // Instrumentation can kill and relaunch even persistent processes
14267            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14268                    "start instr");
14269            ProcessRecord app = addAppLocked(ai, false);
14270            app.instrumentationClass = className;
14271            app.instrumentationInfo = ai;
14272            app.instrumentationProfileFile = profileFile;
14273            app.instrumentationArguments = arguments;
14274            app.instrumentationWatcher = watcher;
14275            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14276            app.instrumentationResultClass = className;
14277            Binder.restoreCallingIdentity(origId);
14278        }
14279
14280        return true;
14281    }
14282
14283    /**
14284     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14285     * error to the logs, but if somebody is watching, send the report there too.  This enables
14286     * the "am" command to report errors with more information.
14287     *
14288     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14289     * @param cn The component name of the instrumentation.
14290     * @param report The error report.
14291     */
14292    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14293            ComponentName cn, String report) {
14294        Slog.w(TAG, report);
14295        try {
14296            if (watcher != null) {
14297                Bundle results = new Bundle();
14298                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14299                results.putString("Error", report);
14300                watcher.instrumentationStatus(cn, -1, results);
14301            }
14302        } catch (RemoteException e) {
14303            Slog.w(TAG, e);
14304        }
14305    }
14306
14307    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14308        if (app.instrumentationWatcher != null) {
14309            try {
14310                // NOTE:  IInstrumentationWatcher *must* be oneway here
14311                app.instrumentationWatcher.instrumentationFinished(
14312                    app.instrumentationClass,
14313                    resultCode,
14314                    results);
14315            } catch (RemoteException e) {
14316            }
14317        }
14318        if (app.instrumentationUiAutomationConnection != null) {
14319            try {
14320                app.instrumentationUiAutomationConnection.shutdown();
14321            } catch (RemoteException re) {
14322                /* ignore */
14323            }
14324            // Only a UiAutomation can set this flag and now that
14325            // it is finished we make sure it is reset to its default.
14326            mUserIsMonkey = false;
14327        }
14328        app.instrumentationWatcher = null;
14329        app.instrumentationUiAutomationConnection = null;
14330        app.instrumentationClass = null;
14331        app.instrumentationInfo = null;
14332        app.instrumentationProfileFile = null;
14333        app.instrumentationArguments = null;
14334
14335        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14336                "finished inst");
14337    }
14338
14339    public void finishInstrumentation(IApplicationThread target,
14340            int resultCode, Bundle results) {
14341        int userId = UserHandle.getCallingUserId();
14342        // Refuse possible leaked file descriptors
14343        if (results != null && results.hasFileDescriptors()) {
14344            throw new IllegalArgumentException("File descriptors passed in Intent");
14345        }
14346
14347        synchronized(this) {
14348            ProcessRecord app = getRecordForAppLocked(target);
14349            if (app == null) {
14350                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14351                return;
14352            }
14353            final long origId = Binder.clearCallingIdentity();
14354            finishInstrumentationLocked(app, resultCode, results);
14355            Binder.restoreCallingIdentity(origId);
14356        }
14357    }
14358
14359    // =========================================================
14360    // CONFIGURATION
14361    // =========================================================
14362
14363    public ConfigurationInfo getDeviceConfigurationInfo() {
14364        ConfigurationInfo config = new ConfigurationInfo();
14365        synchronized (this) {
14366            config.reqTouchScreen = mConfiguration.touchscreen;
14367            config.reqKeyboardType = mConfiguration.keyboard;
14368            config.reqNavigation = mConfiguration.navigation;
14369            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14370                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14371                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14372            }
14373            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14374                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14375                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14376            }
14377            config.reqGlEsVersion = GL_ES_VERSION;
14378        }
14379        return config;
14380    }
14381
14382    ActivityStack getFocusedStack() {
14383        return mStackSupervisor.getFocusedStack();
14384    }
14385
14386    public Configuration getConfiguration() {
14387        Configuration ci;
14388        synchronized(this) {
14389            ci = new Configuration(mConfiguration);
14390        }
14391        return ci;
14392    }
14393
14394    public void updatePersistentConfiguration(Configuration values) {
14395        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14396                "updateConfiguration()");
14397        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14398                "updateConfiguration()");
14399        if (values == null) {
14400            throw new NullPointerException("Configuration must not be null");
14401        }
14402
14403        synchronized(this) {
14404            final long origId = Binder.clearCallingIdentity();
14405            updateConfigurationLocked(values, null, true, false);
14406            Binder.restoreCallingIdentity(origId);
14407        }
14408    }
14409
14410    public void updateConfiguration(Configuration values) {
14411        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14412                "updateConfiguration()");
14413
14414        synchronized(this) {
14415            if (values == null && mWindowManager != null) {
14416                // sentinel: fetch the current configuration from the window manager
14417                values = mWindowManager.computeNewConfiguration();
14418            }
14419
14420            if (mWindowManager != null) {
14421                mProcessList.applyDisplaySize(mWindowManager);
14422            }
14423
14424            final long origId = Binder.clearCallingIdentity();
14425            if (values != null) {
14426                Settings.System.clearConfiguration(values);
14427            }
14428            updateConfigurationLocked(values, null, false, false);
14429            Binder.restoreCallingIdentity(origId);
14430        }
14431    }
14432
14433    /**
14434     * Do either or both things: (1) change the current configuration, and (2)
14435     * make sure the given activity is running with the (now) current
14436     * configuration.  Returns true if the activity has been left running, or
14437     * false if <var>starting</var> is being destroyed to match the new
14438     * configuration.
14439     * @param persistent TODO
14440     */
14441    boolean updateConfigurationLocked(Configuration values,
14442            ActivityRecord starting, boolean persistent, boolean initLocale) {
14443        int changes = 0;
14444
14445        if (values != null) {
14446            Configuration newConfig = new Configuration(mConfiguration);
14447            changes = newConfig.updateFrom(values);
14448            if (changes != 0) {
14449                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14450                    Slog.i(TAG, "Updating configuration to: " + values);
14451                }
14452
14453                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14454
14455                if (values.locale != null && !initLocale) {
14456                    saveLocaleLocked(values.locale,
14457                                     !values.locale.equals(mConfiguration.locale),
14458                                     values.userSetLocale);
14459                }
14460
14461                mConfigurationSeq++;
14462                if (mConfigurationSeq <= 0) {
14463                    mConfigurationSeq = 1;
14464                }
14465                newConfig.seq = mConfigurationSeq;
14466                mConfiguration = newConfig;
14467                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14468                mUsageStatsService.noteStartConfig(newConfig);
14469
14470                final Configuration configCopy = new Configuration(mConfiguration);
14471
14472                // TODO: If our config changes, should we auto dismiss any currently
14473                // showing dialogs?
14474                mShowDialogs = shouldShowDialogs(newConfig);
14475
14476                AttributeCache ac = AttributeCache.instance();
14477                if (ac != null) {
14478                    ac.updateConfiguration(configCopy);
14479                }
14480
14481                // Make sure all resources in our process are updated
14482                // right now, so that anyone who is going to retrieve
14483                // resource values after we return will be sure to get
14484                // the new ones.  This is especially important during
14485                // boot, where the first config change needs to guarantee
14486                // all resources have that config before following boot
14487                // code is executed.
14488                mSystemThread.applyConfigurationToResources(configCopy);
14489
14490                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14491                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14492                    msg.obj = new Configuration(configCopy);
14493                    mHandler.sendMessage(msg);
14494                }
14495
14496                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14497                    ProcessRecord app = mLruProcesses.get(i);
14498                    try {
14499                        if (app.thread != null) {
14500                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14501                                    + app.processName + " new config " + mConfiguration);
14502                            app.thread.scheduleConfigurationChanged(configCopy);
14503                        }
14504                    } catch (Exception e) {
14505                    }
14506                }
14507                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14508                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14509                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14510                        | Intent.FLAG_RECEIVER_FOREGROUND);
14511                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14512                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14513                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14514                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14515                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14516                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14517                    broadcastIntentLocked(null, null, intent,
14518                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14519                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14520                }
14521            }
14522        }
14523
14524        boolean kept = true;
14525        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14526        // mainStack is null during startup.
14527        if (mainStack != null) {
14528            if (changes != 0 && starting == null) {
14529                // If the configuration changed, and the caller is not already
14530                // in the process of starting an activity, then find the top
14531                // activity to check if its configuration needs to change.
14532                starting = mainStack.topRunningActivityLocked(null);
14533            }
14534
14535            if (starting != null) {
14536                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14537                // And we need to make sure at this point that all other activities
14538                // are made visible with the correct configuration.
14539                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14540            }
14541        }
14542
14543        if (values != null && mWindowManager != null) {
14544            mWindowManager.setNewConfiguration(mConfiguration);
14545        }
14546
14547        return kept;
14548    }
14549
14550    /**
14551     * Decide based on the configuration whether we should shouw the ANR,
14552     * crash, etc dialogs.  The idea is that if there is no affordnace to
14553     * press the on-screen buttons, we shouldn't show the dialog.
14554     *
14555     * A thought: SystemUI might also want to get told about this, the Power
14556     * dialog / global actions also might want different behaviors.
14557     */
14558    private static final boolean shouldShowDialogs(Configuration config) {
14559        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14560                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14561    }
14562
14563    /**
14564     * Save the locale.  You must be inside a synchronized (this) block.
14565     */
14566    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14567        if(isDiff) {
14568            SystemProperties.set("user.language", l.getLanguage());
14569            SystemProperties.set("user.region", l.getCountry());
14570        }
14571
14572        if(isPersist) {
14573            SystemProperties.set("persist.sys.language", l.getLanguage());
14574            SystemProperties.set("persist.sys.country", l.getCountry());
14575            SystemProperties.set("persist.sys.localevar", l.getVariant());
14576        }
14577    }
14578
14579    @Override
14580    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14581        ActivityRecord srec = ActivityRecord.forToken(token);
14582        return srec != null && srec.task.affinity != null &&
14583                srec.task.affinity.equals(destAffinity);
14584    }
14585
14586    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14587            Intent resultData) {
14588
14589        synchronized (this) {
14590            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14591            if (stack != null) {
14592                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14593            }
14594            return false;
14595        }
14596    }
14597
14598    public int getLaunchedFromUid(IBinder activityToken) {
14599        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14600        if (srec == null) {
14601            return -1;
14602        }
14603        return srec.launchedFromUid;
14604    }
14605
14606    public String getLaunchedFromPackage(IBinder activityToken) {
14607        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14608        if (srec == null) {
14609            return null;
14610        }
14611        return srec.launchedFromPackage;
14612    }
14613
14614    // =========================================================
14615    // LIFETIME MANAGEMENT
14616    // =========================================================
14617
14618    // Returns which broadcast queue the app is the current [or imminent] receiver
14619    // on, or 'null' if the app is not an active broadcast recipient.
14620    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14621        BroadcastRecord r = app.curReceiver;
14622        if (r != null) {
14623            return r.queue;
14624        }
14625
14626        // It's not the current receiver, but it might be starting up to become one
14627        synchronized (this) {
14628            for (BroadcastQueue queue : mBroadcastQueues) {
14629                r = queue.mPendingBroadcast;
14630                if (r != null && r.curApp == app) {
14631                    // found it; report which queue it's in
14632                    return queue;
14633                }
14634            }
14635        }
14636
14637        return null;
14638    }
14639
14640    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14641            boolean doingAll, long now) {
14642        if (mAdjSeq == app.adjSeq) {
14643            // This adjustment has already been computed.
14644            return app.curRawAdj;
14645        }
14646
14647        if (app.thread == null) {
14648            app.adjSeq = mAdjSeq;
14649            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14650            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14651            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14652        }
14653
14654        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14655        app.adjSource = null;
14656        app.adjTarget = null;
14657        app.empty = false;
14658        app.cached = false;
14659
14660        final int activitiesSize = app.activities.size();
14661
14662        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14663            // The max adjustment doesn't allow this app to be anything
14664            // below foreground, so it is not worth doing work for it.
14665            app.adjType = "fixed";
14666            app.adjSeq = mAdjSeq;
14667            app.curRawAdj = app.maxAdj;
14668            app.foregroundActivities = false;
14669            app.keeping = true;
14670            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14671            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14672            // System processes can do UI, and when they do we want to have
14673            // them trim their memory after the user leaves the UI.  To
14674            // facilitate this, here we need to determine whether or not it
14675            // is currently showing UI.
14676            app.systemNoUi = true;
14677            if (app == TOP_APP) {
14678                app.systemNoUi = false;
14679            } else if (activitiesSize > 0) {
14680                for (int j = 0; j < activitiesSize; j++) {
14681                    final ActivityRecord r = app.activities.get(j);
14682                    if (r.visible) {
14683                        app.systemNoUi = false;
14684                    }
14685                }
14686            }
14687            if (!app.systemNoUi) {
14688                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14689            }
14690            return (app.curAdj=app.maxAdj);
14691        }
14692
14693        app.keeping = false;
14694        app.systemNoUi = false;
14695
14696        // Determine the importance of the process, starting with most
14697        // important to least, and assign an appropriate OOM adjustment.
14698        int adj;
14699        int schedGroup;
14700        int procState;
14701        boolean foregroundActivities = false;
14702        boolean interesting = false;
14703        BroadcastQueue queue;
14704        if (app == TOP_APP) {
14705            // The last app on the list is the foreground app.
14706            adj = ProcessList.FOREGROUND_APP_ADJ;
14707            schedGroup = Process.THREAD_GROUP_DEFAULT;
14708            app.adjType = "top-activity";
14709            foregroundActivities = true;
14710            interesting = true;
14711            procState = ActivityManager.PROCESS_STATE_TOP;
14712        } else if (app.instrumentationClass != null) {
14713            // Don't want to kill running instrumentation.
14714            adj = ProcessList.FOREGROUND_APP_ADJ;
14715            schedGroup = Process.THREAD_GROUP_DEFAULT;
14716            app.adjType = "instrumentation";
14717            interesting = true;
14718            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14719        } else if ((queue = isReceivingBroadcast(app)) != null) {
14720            // An app that is currently receiving a broadcast also
14721            // counts as being in the foreground for OOM killer purposes.
14722            // It's placed in a sched group based on the nature of the
14723            // broadcast as reflected by which queue it's active in.
14724            adj = ProcessList.FOREGROUND_APP_ADJ;
14725            schedGroup = (queue == mFgBroadcastQueue)
14726                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14727            app.adjType = "broadcast";
14728            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14729        } else if (app.executingServices.size() > 0) {
14730            // An app that is currently executing a service callback also
14731            // counts as being in the foreground.
14732            adj = ProcessList.FOREGROUND_APP_ADJ;
14733            schedGroup = app.execServicesFg ?
14734                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14735            app.adjType = "exec-service";
14736            procState = ActivityManager.PROCESS_STATE_SERVICE;
14737            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14738        } else {
14739            // As far as we know the process is empty.  We may change our mind later.
14740            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14741            // At this point we don't actually know the adjustment.  Use the cached adj
14742            // value that the caller wants us to.
14743            adj = cachedAdj;
14744            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14745            app.cached = true;
14746            app.empty = true;
14747            app.adjType = "cch-empty";
14748        }
14749
14750        // Examine all activities if not already foreground.
14751        if (!foregroundActivities && activitiesSize > 0) {
14752            for (int j = 0; j < activitiesSize; j++) {
14753                final ActivityRecord r = app.activities.get(j);
14754                if (r.app != app) {
14755                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14756                            + app + "?!?");
14757                    continue;
14758                }
14759                if (r.visible) {
14760                    // App has a visible activity; only upgrade adjustment.
14761                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14762                        adj = ProcessList.VISIBLE_APP_ADJ;
14763                        app.adjType = "visible";
14764                    }
14765                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14766                        procState = ActivityManager.PROCESS_STATE_TOP;
14767                    }
14768                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14769                    app.cached = false;
14770                    app.empty = false;
14771                    foregroundActivities = true;
14772                    break;
14773                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14774                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14775                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14776                        app.adjType = "pausing";
14777                    }
14778                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14779                        procState = ActivityManager.PROCESS_STATE_TOP;
14780                    }
14781                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14782                    app.cached = false;
14783                    app.empty = false;
14784                    foregroundActivities = true;
14785                } else if (r.state == ActivityState.STOPPING) {
14786                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14787                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14788                        app.adjType = "stopping";
14789                    }
14790                    // For the process state, we will at this point consider the
14791                    // process to be cached.  It will be cached either as an activity
14792                    // or empty depending on whether the activity is finishing.  We do
14793                    // this so that we can treat the process as cached for purposes of
14794                    // memory trimming (determing current memory level, trim command to
14795                    // send to process) since there can be an arbitrary number of stopping
14796                    // processes and they should soon all go into the cached state.
14797                    if (!r.finishing) {
14798                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14799                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14800                        }
14801                    }
14802                    app.cached = false;
14803                    app.empty = false;
14804                    foregroundActivities = true;
14805                } else {
14806                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14807                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14808                        app.adjType = "cch-act";
14809                    }
14810                }
14811            }
14812        }
14813
14814        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14815            if (app.foregroundServices) {
14816                // The user is aware of this app, so make it visible.
14817                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14818                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14819                app.cached = false;
14820                app.adjType = "fg-service";
14821                schedGroup = Process.THREAD_GROUP_DEFAULT;
14822            } else if (app.forcingToForeground != null) {
14823                // The user is aware of this app, so make it visible.
14824                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14825                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14826                app.cached = false;
14827                app.adjType = "force-fg";
14828                app.adjSource = app.forcingToForeground;
14829                schedGroup = Process.THREAD_GROUP_DEFAULT;
14830            }
14831        }
14832
14833        if (app.foregroundServices) {
14834            interesting = true;
14835        }
14836
14837        if (app == mHeavyWeightProcess) {
14838            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14839                // We don't want to kill the current heavy-weight process.
14840                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14841                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14842                app.cached = false;
14843                app.adjType = "heavy";
14844            }
14845            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14846                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14847            }
14848        }
14849
14850        if (app == mHomeProcess) {
14851            if (adj > ProcessList.HOME_APP_ADJ) {
14852                // This process is hosting what we currently consider to be the
14853                // home app, so we don't want to let it go into the background.
14854                adj = ProcessList.HOME_APP_ADJ;
14855                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14856                app.cached = false;
14857                app.adjType = "home";
14858            }
14859            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14860                procState = ActivityManager.PROCESS_STATE_HOME;
14861            }
14862        }
14863
14864        if (app == mPreviousProcess && app.activities.size() > 0) {
14865            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14866                // This was the previous process that showed UI to the user.
14867                // We want to try to keep it around more aggressively, to give
14868                // a good experience around switching between two apps.
14869                adj = ProcessList.PREVIOUS_APP_ADJ;
14870                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14871                app.cached = false;
14872                app.adjType = "previous";
14873            }
14874            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14875                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14876            }
14877        }
14878
14879        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14880                + " reason=" + app.adjType);
14881
14882        // By default, we use the computed adjustment.  It may be changed if
14883        // there are applications dependent on our services or providers, but
14884        // this gives us a baseline and makes sure we don't get into an
14885        // infinite recursion.
14886        app.adjSeq = mAdjSeq;
14887        app.curRawAdj = adj;
14888        app.hasStartedServices = false;
14889
14890        if (mBackupTarget != null && app == mBackupTarget.app) {
14891            // If possible we want to avoid killing apps while they're being backed up
14892            if (adj > ProcessList.BACKUP_APP_ADJ) {
14893                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14894                adj = ProcessList.BACKUP_APP_ADJ;
14895                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14896                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14897                }
14898                app.adjType = "backup";
14899                app.cached = false;
14900            }
14901            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14902                procState = ActivityManager.PROCESS_STATE_BACKUP;
14903            }
14904        }
14905
14906        boolean mayBeTop = false;
14907
14908        for (int is = app.services.size()-1;
14909                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14910                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14911                        || procState > ActivityManager.PROCESS_STATE_TOP);
14912                is--) {
14913            ServiceRecord s = app.services.valueAt(is);
14914            if (s.startRequested) {
14915                app.hasStartedServices = true;
14916                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14917                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14918                }
14919                if (app.hasShownUi && app != mHomeProcess) {
14920                    // If this process has shown some UI, let it immediately
14921                    // go to the LRU list because it may be pretty heavy with
14922                    // UI stuff.  We'll tag it with a label just to help
14923                    // debug and understand what is going on.
14924                    if (adj > ProcessList.SERVICE_ADJ) {
14925                        app.adjType = "cch-started-ui-services";
14926                    }
14927                } else {
14928                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14929                        // This service has seen some activity within
14930                        // recent memory, so we will keep its process ahead
14931                        // of the background processes.
14932                        if (adj > ProcessList.SERVICE_ADJ) {
14933                            adj = ProcessList.SERVICE_ADJ;
14934                            app.adjType = "started-services";
14935                            app.cached = false;
14936                        }
14937                    }
14938                    // If we have let the service slide into the background
14939                    // state, still have some text describing what it is doing
14940                    // even though the service no longer has an impact.
14941                    if (adj > ProcessList.SERVICE_ADJ) {
14942                        app.adjType = "cch-started-services";
14943                    }
14944                }
14945                // Don't kill this process because it is doing work; it
14946                // has said it is doing work.
14947                app.keeping = true;
14948            }
14949            for (int conni = s.connections.size()-1;
14950                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14951                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14952                            || procState > ActivityManager.PROCESS_STATE_TOP);
14953                    conni--) {
14954                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14955                for (int i = 0;
14956                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14957                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14958                                || procState > ActivityManager.PROCESS_STATE_TOP);
14959                        i++) {
14960                    // XXX should compute this based on the max of
14961                    // all connected clients.
14962                    ConnectionRecord cr = clist.get(i);
14963                    if (cr.binding.client == app) {
14964                        // Binding to ourself is not interesting.
14965                        continue;
14966                    }
14967                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14968                        ProcessRecord client = cr.binding.client;
14969                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14970                                TOP_APP, doingAll, now);
14971                        int clientProcState = client.curProcState;
14972                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14973                            // If the other app is cached for any reason, for purposes here
14974                            // we are going to consider it empty.  The specific cached state
14975                            // doesn't propagate except under certain conditions.
14976                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14977                        }
14978                        String adjType = null;
14979                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14980                            // Not doing bind OOM management, so treat
14981                            // this guy more like a started service.
14982                            if (app.hasShownUi && app != mHomeProcess) {
14983                                // If this process has shown some UI, let it immediately
14984                                // go to the LRU list because it may be pretty heavy with
14985                                // UI stuff.  We'll tag it with a label just to help
14986                                // debug and understand what is going on.
14987                                if (adj > clientAdj) {
14988                                    adjType = "cch-bound-ui-services";
14989                                }
14990                                app.cached = false;
14991                                clientAdj = adj;
14992                                clientProcState = procState;
14993                            } else {
14994                                if (now >= (s.lastActivity
14995                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14996                                    // This service has not seen activity within
14997                                    // recent memory, so allow it to drop to the
14998                                    // LRU list if there is no other reason to keep
14999                                    // it around.  We'll also tag it with a label just
15000                                    // to help debug and undertand what is going on.
15001                                    if (adj > clientAdj) {
15002                                        adjType = "cch-bound-services";
15003                                    }
15004                                    clientAdj = adj;
15005                                }
15006                            }
15007                        }
15008                        if (adj > clientAdj) {
15009                            // If this process has recently shown UI, and
15010                            // the process that is binding to it is less
15011                            // important than being visible, then we don't
15012                            // care about the binding as much as we care
15013                            // about letting this process get into the LRU
15014                            // list to be killed and restarted if needed for
15015                            // memory.
15016                            if (app.hasShownUi && app != mHomeProcess
15017                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15018                                adjType = "cch-bound-ui-services";
15019                            } else {
15020                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15021                                        |Context.BIND_IMPORTANT)) != 0) {
15022                                    adj = clientAdj;
15023                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15024                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15025                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15026                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15027                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15028                                    adj = clientAdj;
15029                                } else {
15030                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15031                                        adj = ProcessList.VISIBLE_APP_ADJ;
15032                                    }
15033                                }
15034                                if (!client.cached) {
15035                                    app.cached = false;
15036                                }
15037                                if (client.keeping) {
15038                                    app.keeping = true;
15039                                }
15040                                adjType = "service";
15041                            }
15042                        }
15043                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15044                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15045                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15046                            }
15047                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15048                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15049                                    // Special handling of clients who are in the top state.
15050                                    // We *may* want to consider this process to be in the
15051                                    // top state as well, but only if there is not another
15052                                    // reason for it to be running.  Being on the top is a
15053                                    // special state, meaning you are specifically running
15054                                    // for the current top app.  If the process is already
15055                                    // running in the background for some other reason, it
15056                                    // is more important to continue considering it to be
15057                                    // in the background state.
15058                                    mayBeTop = true;
15059                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15060                                } else {
15061                                    // Special handling for above-top states (persistent
15062                                    // processes).  These should not bring the current process
15063                                    // into the top state, since they are not on top.  Instead
15064                                    // give them the best state after that.
15065                                    clientProcState =
15066                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15067                                }
15068                            }
15069                        } else {
15070                            if (clientProcState <
15071                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15072                                clientProcState =
15073                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15074                            }
15075                        }
15076                        if (procState > clientProcState) {
15077                            procState = clientProcState;
15078                        }
15079                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15080                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15081                            app.pendingUiClean = true;
15082                        }
15083                        if (adjType != null) {
15084                            app.adjType = adjType;
15085                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15086                                    .REASON_SERVICE_IN_USE;
15087                            app.adjSource = cr.binding.client;
15088                            app.adjSourceOom = clientAdj;
15089                            app.adjTarget = s.name;
15090                        }
15091                    }
15092                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15093                        app.treatLikeActivity = true;
15094                    }
15095                    final ActivityRecord a = cr.activity;
15096                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15097                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15098                                (a.visible || a.state == ActivityState.RESUMED
15099                                 || a.state == ActivityState.PAUSING)) {
15100                            adj = ProcessList.FOREGROUND_APP_ADJ;
15101                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15102                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15103                            }
15104                            app.cached = false;
15105                            app.adjType = "service";
15106                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15107                                    .REASON_SERVICE_IN_USE;
15108                            app.adjSource = a;
15109                            app.adjSourceOom = adj;
15110                            app.adjTarget = s.name;
15111                        }
15112                    }
15113                }
15114            }
15115        }
15116
15117        for (int provi = app.pubProviders.size()-1;
15118                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15119                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15120                        || procState > ActivityManager.PROCESS_STATE_TOP);
15121                provi--) {
15122            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15123            for (int i = cpr.connections.size()-1;
15124                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15125                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15126                            || procState > ActivityManager.PROCESS_STATE_TOP);
15127                    i--) {
15128                ContentProviderConnection conn = cpr.connections.get(i);
15129                ProcessRecord client = conn.client;
15130                if (client == app) {
15131                    // Being our own client is not interesting.
15132                    continue;
15133                }
15134                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15135                int clientProcState = client.curProcState;
15136                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15137                    // If the other app is cached for any reason, for purposes here
15138                    // we are going to consider it empty.
15139                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15140                }
15141                if (adj > clientAdj) {
15142                    if (app.hasShownUi && app != mHomeProcess
15143                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15144                        app.adjType = "cch-ui-provider";
15145                    } else {
15146                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15147                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15148                        app.adjType = "provider";
15149                    }
15150                    app.cached &= client.cached;
15151                    app.keeping |= client.keeping;
15152                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15153                            .REASON_PROVIDER_IN_USE;
15154                    app.adjSource = client;
15155                    app.adjSourceOom = clientAdj;
15156                    app.adjTarget = cpr.name;
15157                }
15158                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15159                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15160                        // Special handling of clients who are in the top state.
15161                        // We *may* want to consider this process to be in the
15162                        // top state as well, but only if there is not another
15163                        // reason for it to be running.  Being on the top is a
15164                        // special state, meaning you are specifically running
15165                        // for the current top app.  If the process is already
15166                        // running in the background for some other reason, it
15167                        // is more important to continue considering it to be
15168                        // in the background state.
15169                        mayBeTop = true;
15170                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15171                    } else {
15172                        // Special handling for above-top states (persistent
15173                        // processes).  These should not bring the current process
15174                        // into the top state, since they are not on top.  Instead
15175                        // give them the best state after that.
15176                        clientProcState =
15177                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15178                    }
15179                }
15180                if (procState > clientProcState) {
15181                    procState = clientProcState;
15182                }
15183                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15184                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15185                }
15186            }
15187            // If the provider has external (non-framework) process
15188            // dependencies, ensure that its adjustment is at least
15189            // FOREGROUND_APP_ADJ.
15190            if (cpr.hasExternalProcessHandles()) {
15191                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15192                    adj = ProcessList.FOREGROUND_APP_ADJ;
15193                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15194                    app.cached = false;
15195                    app.keeping = true;
15196                    app.adjType = "provider";
15197                    app.adjTarget = cpr.name;
15198                }
15199                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15200                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15201                }
15202            }
15203        }
15204
15205        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15206            // A client of one of our services or providers is in the top state.  We
15207            // *may* want to be in the top state, but not if we are already running in
15208            // the background for some other reason.  For the decision here, we are going
15209            // to pick out a few specific states that we want to remain in when a client
15210            // is top (states that tend to be longer-term) and otherwise allow it to go
15211            // to the top state.
15212            switch (procState) {
15213                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15214                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15215                case ActivityManager.PROCESS_STATE_SERVICE:
15216                    // These all are longer-term states, so pull them up to the top
15217                    // of the background states, but not all the way to the top state.
15218                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15219                    break;
15220                default:
15221                    // Otherwise, top is a better choice, so take it.
15222                    procState = ActivityManager.PROCESS_STATE_TOP;
15223                    break;
15224            }
15225        }
15226
15227        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15228            if (app.hasClientActivities) {
15229                // This is a cached process, but with client activities.  Mark it so.
15230                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15231                app.adjType = "cch-client-act";
15232            } else if (app.treatLikeActivity) {
15233                // This is a cached process, but somebody wants us to treat it like it has
15234                // an activity, okay!
15235                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15236                app.adjType = "cch-as-act";
15237            }
15238        }
15239
15240        if (adj == ProcessList.SERVICE_ADJ) {
15241            if (doingAll) {
15242                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15243                mNewNumServiceProcs++;
15244                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15245                if (!app.serviceb) {
15246                    // This service isn't far enough down on the LRU list to
15247                    // normally be a B service, but if we are low on RAM and it
15248                    // is large we want to force it down since we would prefer to
15249                    // keep launcher over it.
15250                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15251                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15252                        app.serviceHighRam = true;
15253                        app.serviceb = true;
15254                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15255                    } else {
15256                        mNewNumAServiceProcs++;
15257                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15258                    }
15259                } else {
15260                    app.serviceHighRam = false;
15261                }
15262            }
15263            if (app.serviceb) {
15264                adj = ProcessList.SERVICE_B_ADJ;
15265            }
15266        }
15267
15268        app.curRawAdj = adj;
15269
15270        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15271        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15272        if (adj > app.maxAdj) {
15273            adj = app.maxAdj;
15274            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15275                schedGroup = Process.THREAD_GROUP_DEFAULT;
15276            }
15277        }
15278        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15279            app.keeping = true;
15280        }
15281
15282        // Do final modification to adj.  Everything we do between here and applying
15283        // the final setAdj must be done in this function, because we will also use
15284        // it when computing the final cached adj later.  Note that we don't need to
15285        // worry about this for max adj above, since max adj will always be used to
15286        // keep it out of the cached vaues.
15287        app.curAdj = app.modifyRawOomAdj(adj);
15288        app.curSchedGroup = schedGroup;
15289        app.curProcState = procState;
15290        app.foregroundActivities = foregroundActivities;
15291
15292        return app.curRawAdj;
15293    }
15294
15295    /**
15296     * Schedule PSS collection of a process.
15297     */
15298    void requestPssLocked(ProcessRecord proc, int procState) {
15299        if (mPendingPssProcesses.contains(proc)) {
15300            return;
15301        }
15302        if (mPendingPssProcesses.size() == 0) {
15303            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15304        }
15305        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15306        proc.pssProcState = procState;
15307        mPendingPssProcesses.add(proc);
15308    }
15309
15310    /**
15311     * Schedule PSS collection of all processes.
15312     */
15313    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15314        if (!always) {
15315            if (now < (mLastFullPssTime +
15316                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15317                return;
15318            }
15319        }
15320        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15321        mLastFullPssTime = now;
15322        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15323        mPendingPssProcesses.clear();
15324        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15325            ProcessRecord app = mLruProcesses.get(i);
15326            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15327                app.pssProcState = app.setProcState;
15328                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15329                        isSleeping(), now);
15330                mPendingPssProcesses.add(app);
15331            }
15332        }
15333        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15334    }
15335
15336    /**
15337     * Ask a given process to GC right now.
15338     */
15339    final void performAppGcLocked(ProcessRecord app) {
15340        try {
15341            app.lastRequestedGc = SystemClock.uptimeMillis();
15342            if (app.thread != null) {
15343                if (app.reportLowMemory) {
15344                    app.reportLowMemory = false;
15345                    app.thread.scheduleLowMemory();
15346                } else {
15347                    app.thread.processInBackground();
15348                }
15349            }
15350        } catch (Exception e) {
15351            // whatever.
15352        }
15353    }
15354
15355    /**
15356     * Returns true if things are idle enough to perform GCs.
15357     */
15358    private final boolean canGcNowLocked() {
15359        boolean processingBroadcasts = false;
15360        for (BroadcastQueue q : mBroadcastQueues) {
15361            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15362                processingBroadcasts = true;
15363            }
15364        }
15365        return !processingBroadcasts
15366                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15367    }
15368
15369    /**
15370     * Perform GCs on all processes that are waiting for it, but only
15371     * if things are idle.
15372     */
15373    final void performAppGcsLocked() {
15374        final int N = mProcessesToGc.size();
15375        if (N <= 0) {
15376            return;
15377        }
15378        if (canGcNowLocked()) {
15379            while (mProcessesToGc.size() > 0) {
15380                ProcessRecord proc = mProcessesToGc.remove(0);
15381                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15382                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15383                            <= SystemClock.uptimeMillis()) {
15384                        // To avoid spamming the system, we will GC processes one
15385                        // at a time, waiting a few seconds between each.
15386                        performAppGcLocked(proc);
15387                        scheduleAppGcsLocked();
15388                        return;
15389                    } else {
15390                        // It hasn't been long enough since we last GCed this
15391                        // process...  put it in the list to wait for its time.
15392                        addProcessToGcListLocked(proc);
15393                        break;
15394                    }
15395                }
15396            }
15397
15398            scheduleAppGcsLocked();
15399        }
15400    }
15401
15402    /**
15403     * If all looks good, perform GCs on all processes waiting for them.
15404     */
15405    final void performAppGcsIfAppropriateLocked() {
15406        if (canGcNowLocked()) {
15407            performAppGcsLocked();
15408            return;
15409        }
15410        // Still not idle, wait some more.
15411        scheduleAppGcsLocked();
15412    }
15413
15414    /**
15415     * Schedule the execution of all pending app GCs.
15416     */
15417    final void scheduleAppGcsLocked() {
15418        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15419
15420        if (mProcessesToGc.size() > 0) {
15421            // Schedule a GC for the time to the next process.
15422            ProcessRecord proc = mProcessesToGc.get(0);
15423            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15424
15425            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15426            long now = SystemClock.uptimeMillis();
15427            if (when < (now+GC_TIMEOUT)) {
15428                when = now + GC_TIMEOUT;
15429            }
15430            mHandler.sendMessageAtTime(msg, when);
15431        }
15432    }
15433
15434    /**
15435     * Add a process to the array of processes waiting to be GCed.  Keeps the
15436     * list in sorted order by the last GC time.  The process can't already be
15437     * on the list.
15438     */
15439    final void addProcessToGcListLocked(ProcessRecord proc) {
15440        boolean added = false;
15441        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15442            if (mProcessesToGc.get(i).lastRequestedGc <
15443                    proc.lastRequestedGc) {
15444                added = true;
15445                mProcessesToGc.add(i+1, proc);
15446                break;
15447            }
15448        }
15449        if (!added) {
15450            mProcessesToGc.add(0, proc);
15451        }
15452    }
15453
15454    /**
15455     * Set up to ask a process to GC itself.  This will either do it
15456     * immediately, or put it on the list of processes to gc the next
15457     * time things are idle.
15458     */
15459    final void scheduleAppGcLocked(ProcessRecord app) {
15460        long now = SystemClock.uptimeMillis();
15461        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15462            return;
15463        }
15464        if (!mProcessesToGc.contains(app)) {
15465            addProcessToGcListLocked(app);
15466            scheduleAppGcsLocked();
15467        }
15468    }
15469
15470    final void checkExcessivePowerUsageLocked(boolean doKills) {
15471        updateCpuStatsNow();
15472
15473        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15474        boolean doWakeKills = doKills;
15475        boolean doCpuKills = doKills;
15476        if (mLastPowerCheckRealtime == 0) {
15477            doWakeKills = false;
15478        }
15479        if (mLastPowerCheckUptime == 0) {
15480            doCpuKills = false;
15481        }
15482        if (stats.isScreenOn()) {
15483            doWakeKills = false;
15484        }
15485        final long curRealtime = SystemClock.elapsedRealtime();
15486        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15487        final long curUptime = SystemClock.uptimeMillis();
15488        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15489        mLastPowerCheckRealtime = curRealtime;
15490        mLastPowerCheckUptime = curUptime;
15491        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15492            doWakeKills = false;
15493        }
15494        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15495            doCpuKills = false;
15496        }
15497        int i = mLruProcesses.size();
15498        while (i > 0) {
15499            i--;
15500            ProcessRecord app = mLruProcesses.get(i);
15501            if (!app.keeping) {
15502                long wtime;
15503                synchronized (stats) {
15504                    wtime = stats.getProcessWakeTime(app.info.uid,
15505                            app.pid, curRealtime);
15506                }
15507                long wtimeUsed = wtime - app.lastWakeTime;
15508                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15509                if (DEBUG_POWER) {
15510                    StringBuilder sb = new StringBuilder(128);
15511                    sb.append("Wake for ");
15512                    app.toShortString(sb);
15513                    sb.append(": over ");
15514                    TimeUtils.formatDuration(realtimeSince, sb);
15515                    sb.append(" used ");
15516                    TimeUtils.formatDuration(wtimeUsed, sb);
15517                    sb.append(" (");
15518                    sb.append((wtimeUsed*100)/realtimeSince);
15519                    sb.append("%)");
15520                    Slog.i(TAG, sb.toString());
15521                    sb.setLength(0);
15522                    sb.append("CPU for ");
15523                    app.toShortString(sb);
15524                    sb.append(": over ");
15525                    TimeUtils.formatDuration(uptimeSince, sb);
15526                    sb.append(" used ");
15527                    TimeUtils.formatDuration(cputimeUsed, sb);
15528                    sb.append(" (");
15529                    sb.append((cputimeUsed*100)/uptimeSince);
15530                    sb.append("%)");
15531                    Slog.i(TAG, sb.toString());
15532                }
15533                // If a process has held a wake lock for more
15534                // than 50% of the time during this period,
15535                // that sounds bad.  Kill!
15536                if (doWakeKills && realtimeSince > 0
15537                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15538                    synchronized (stats) {
15539                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15540                                realtimeSince, wtimeUsed);
15541                    }
15542                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15543                            + " during " + realtimeSince);
15544                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15545                } else if (doCpuKills && uptimeSince > 0
15546                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15547                    synchronized (stats) {
15548                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15549                                uptimeSince, cputimeUsed);
15550                    }
15551                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15552                            + " during " + uptimeSince);
15553                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15554                } else {
15555                    app.lastWakeTime = wtime;
15556                    app.lastCpuTime = app.curCpuTime;
15557                }
15558            }
15559        }
15560    }
15561
15562    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15563            ProcessRecord TOP_APP, boolean doingAll, long now) {
15564        boolean success = true;
15565
15566        if (app.curRawAdj != app.setRawAdj) {
15567            if (wasKeeping && !app.keeping) {
15568                // This app is no longer something we want to keep.  Note
15569                // its current wake lock time to later know to kill it if
15570                // it is not behaving well.
15571                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15572                synchronized (stats) {
15573                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15574                            app.pid, SystemClock.elapsedRealtime());
15575                }
15576                app.lastCpuTime = app.curCpuTime;
15577            }
15578
15579            app.setRawAdj = app.curRawAdj;
15580        }
15581
15582        int changes = 0;
15583
15584        if (app.curAdj != app.setAdj) {
15585            ProcessList.setOomAdj(app.pid, app.curAdj);
15586            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15587                TAG, "Set " + app.pid + " " + app.processName +
15588                " adj " + app.curAdj + ": " + app.adjType);
15589            app.setAdj = app.curAdj;
15590        }
15591
15592        if (app.setSchedGroup != app.curSchedGroup) {
15593            app.setSchedGroup = app.curSchedGroup;
15594            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15595                    "Setting process group of " + app.processName
15596                    + " to " + app.curSchedGroup);
15597            if (app.waitingToKill != null &&
15598                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15599                killUnneededProcessLocked(app, app.waitingToKill);
15600                success = false;
15601            } else {
15602                if (true) {
15603                    long oldId = Binder.clearCallingIdentity();
15604                    try {
15605                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15606                    } catch (Exception e) {
15607                        Slog.w(TAG, "Failed setting process group of " + app.pid
15608                                + " to " + app.curSchedGroup);
15609                        e.printStackTrace();
15610                    } finally {
15611                        Binder.restoreCallingIdentity(oldId);
15612                    }
15613                } else {
15614                    if (app.thread != null) {
15615                        try {
15616                            app.thread.setSchedulingGroup(app.curSchedGroup);
15617                        } catch (RemoteException e) {
15618                        }
15619                    }
15620                }
15621                Process.setSwappiness(app.pid,
15622                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15623            }
15624        }
15625        if (app.repForegroundActivities != app.foregroundActivities) {
15626            app.repForegroundActivities = app.foregroundActivities;
15627            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15628        }
15629        if (app.repProcState != app.curProcState) {
15630            app.repProcState = app.curProcState;
15631            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
15632            if (app.thread != null) {
15633                try {
15634                    if (false) {
15635                        //RuntimeException h = new RuntimeException("here");
15636                        Slog.i(TAG, "Sending new process state " + app.repProcState
15637                                + " to " + app /*, h*/);
15638                    }
15639                    app.thread.setProcessState(app.repProcState);
15640                } catch (RemoteException e) {
15641                }
15642            }
15643        }
15644        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15645                app.setProcState)) {
15646            app.lastStateTime = now;
15647            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15648                    isSleeping(), now);
15649            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15650                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15651                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15652                    + (app.nextPssTime-now) + ": " + app);
15653        } else {
15654            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15655                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15656                requestPssLocked(app, app.setProcState);
15657                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15658                        isSleeping(), now);
15659            } else if (false && DEBUG_PSS) {
15660                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15661            }
15662        }
15663        if (app.setProcState != app.curProcState) {
15664            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15665                    "Proc state change of " + app.processName
15666                    + " to " + app.curProcState);
15667            app.setProcState = app.curProcState;
15668            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15669                app.notCachedSinceIdle = false;
15670            }
15671            if (!doingAll) {
15672                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15673            } else {
15674                app.procStateChanged = true;
15675            }
15676        }
15677
15678        if (changes != 0) {
15679            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15680            int i = mPendingProcessChanges.size()-1;
15681            ProcessChangeItem item = null;
15682            while (i >= 0) {
15683                item = mPendingProcessChanges.get(i);
15684                if (item.pid == app.pid) {
15685                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15686                    break;
15687                }
15688                i--;
15689            }
15690            if (i < 0) {
15691                // No existing item in pending changes; need a new one.
15692                final int NA = mAvailProcessChanges.size();
15693                if (NA > 0) {
15694                    item = mAvailProcessChanges.remove(NA-1);
15695                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15696                } else {
15697                    item = new ProcessChangeItem();
15698                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15699                }
15700                item.changes = 0;
15701                item.pid = app.pid;
15702                item.uid = app.info.uid;
15703                if (mPendingProcessChanges.size() == 0) {
15704                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15705                            "*** Enqueueing dispatch processes changed!");
15706                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15707                }
15708                mPendingProcessChanges.add(item);
15709            }
15710            item.changes |= changes;
15711            item.processState = app.repProcState;
15712            item.foregroundActivities = app.repForegroundActivities;
15713            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
15714                    + Integer.toHexString(System.identityHashCode(item))
15715                    + " " + app.toShortString() + ": changes=" + item.changes
15716                    + " procState=" + item.processState
15717                    + " foreground=" + item.foregroundActivities
15718                    + " type=" + app.adjType + " source=" + app.adjSource
15719                    + " target=" + app.adjTarget);
15720        }
15721
15722        return success;
15723    }
15724
15725    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15726        if (proc.thread != null && proc.baseProcessTracker != null) {
15727            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15728        }
15729    }
15730
15731    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15732            ProcessRecord TOP_APP, boolean doingAll, long now) {
15733        if (app.thread == null) {
15734            return false;
15735        }
15736
15737        final boolean wasKeeping = app.keeping;
15738
15739        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15740
15741        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now);
15742    }
15743
15744    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15745            boolean oomAdj) {
15746        if (isForeground != proc.foregroundServices) {
15747            proc.foregroundServices = isForeground;
15748            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15749                    proc.info.uid);
15750            if (isForeground) {
15751                if (curProcs == null) {
15752                    curProcs = new ArrayList<ProcessRecord>();
15753                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15754                }
15755                if (!curProcs.contains(proc)) {
15756                    curProcs.add(proc);
15757                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15758                            proc.info.packageName, proc.info.uid);
15759                }
15760            } else {
15761                if (curProcs != null) {
15762                    if (curProcs.remove(proc)) {
15763                        mBatteryStatsService.noteEvent(
15764                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15765                                proc.info.packageName, proc.info.uid);
15766                        if (curProcs.size() <= 0) {
15767                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15768                        }
15769                    }
15770                }
15771            }
15772            if (oomAdj) {
15773                updateOomAdjLocked();
15774            }
15775        }
15776    }
15777
15778    private final ActivityRecord resumedAppLocked() {
15779        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15780        String pkg;
15781        int uid;
15782        if (act != null && !act.sleeping) {
15783            pkg = act.packageName;
15784            uid = act.info.applicationInfo.uid;
15785        } else {
15786            pkg = null;
15787            uid = -1;
15788        }
15789        // Has the UID or resumed package name changed?
15790        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15791                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15792            if (mCurResumedPackage != null) {
15793                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15794                        mCurResumedPackage, mCurResumedUid);
15795            }
15796            mCurResumedPackage = pkg;
15797            mCurResumedUid = uid;
15798            if (mCurResumedPackage != null) {
15799                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15800                        mCurResumedPackage, mCurResumedUid);
15801            }
15802        }
15803        return act;
15804    }
15805
15806    final boolean updateOomAdjLocked(ProcessRecord app) {
15807        final ActivityRecord TOP_ACT = resumedAppLocked();
15808        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15809        final boolean wasCached = app.cached;
15810
15811        mAdjSeq++;
15812
15813        // This is the desired cached adjusment we want to tell it to use.
15814        // If our app is currently cached, we know it, and that is it.  Otherwise,
15815        // we don't know it yet, and it needs to now be cached we will then
15816        // need to do a complete oom adj.
15817        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15818                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15819        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
15820                SystemClock.uptimeMillis());
15821        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15822            // Changed to/from cached state, so apps after it in the LRU
15823            // list may also be changed.
15824            updateOomAdjLocked();
15825        }
15826        return success;
15827    }
15828
15829    final void updateOomAdjLocked() {
15830        final ActivityRecord TOP_ACT = resumedAppLocked();
15831        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15832        final long now = SystemClock.uptimeMillis();
15833        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15834        final int N = mLruProcesses.size();
15835
15836        if (false) {
15837            RuntimeException e = new RuntimeException();
15838            e.fillInStackTrace();
15839            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15840        }
15841
15842        mAdjSeq++;
15843        mNewNumServiceProcs = 0;
15844        mNewNumAServiceProcs = 0;
15845
15846        final int emptyProcessLimit;
15847        final int cachedProcessLimit;
15848        if (mProcessLimit <= 0) {
15849            emptyProcessLimit = cachedProcessLimit = 0;
15850        } else if (mProcessLimit == 1) {
15851            emptyProcessLimit = 1;
15852            cachedProcessLimit = 0;
15853        } else {
15854            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15855            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15856        }
15857
15858        // Let's determine how many processes we have running vs.
15859        // how many slots we have for background processes; we may want
15860        // to put multiple processes in a slot of there are enough of
15861        // them.
15862        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15863                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15864        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15865        if (numEmptyProcs > cachedProcessLimit) {
15866            // If there are more empty processes than our limit on cached
15867            // processes, then use the cached process limit for the factor.
15868            // This ensures that the really old empty processes get pushed
15869            // down to the bottom, so if we are running low on memory we will
15870            // have a better chance at keeping around more cached processes
15871            // instead of a gazillion empty processes.
15872            numEmptyProcs = cachedProcessLimit;
15873        }
15874        int emptyFactor = numEmptyProcs/numSlots;
15875        if (emptyFactor < 1) emptyFactor = 1;
15876        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15877        if (cachedFactor < 1) cachedFactor = 1;
15878        int stepCached = 0;
15879        int stepEmpty = 0;
15880        int numCached = 0;
15881        int numEmpty = 0;
15882        int numTrimming = 0;
15883
15884        mNumNonCachedProcs = 0;
15885        mNumCachedHiddenProcs = 0;
15886
15887        // First update the OOM adjustment for each of the
15888        // application processes based on their current state.
15889        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15890        int nextCachedAdj = curCachedAdj+1;
15891        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15892        int nextEmptyAdj = curEmptyAdj+2;
15893        for (int i=N-1; i>=0; i--) {
15894            ProcessRecord app = mLruProcesses.get(i);
15895            if (!app.killedByAm && app.thread != null) {
15896                app.procStateChanged = false;
15897                final boolean wasKeeping = app.keeping;
15898                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15899
15900                // If we haven't yet assigned the final cached adj
15901                // to the process, do that now.
15902                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15903                    switch (app.curProcState) {
15904                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15905                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15906                            // This process is a cached process holding activities...
15907                            // assign it the next cached value for that type, and then
15908                            // step that cached level.
15909                            app.curRawAdj = curCachedAdj;
15910                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15911                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15912                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15913                                    + ")");
15914                            if (curCachedAdj != nextCachedAdj) {
15915                                stepCached++;
15916                                if (stepCached >= cachedFactor) {
15917                                    stepCached = 0;
15918                                    curCachedAdj = nextCachedAdj;
15919                                    nextCachedAdj += 2;
15920                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15921                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15922                                    }
15923                                }
15924                            }
15925                            break;
15926                        default:
15927                            // For everything else, assign next empty cached process
15928                            // level and bump that up.  Note that this means that
15929                            // long-running services that have dropped down to the
15930                            // cached level will be treated as empty (since their process
15931                            // state is still as a service), which is what we want.
15932                            app.curRawAdj = curEmptyAdj;
15933                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15934                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15935                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15936                                    + ")");
15937                            if (curEmptyAdj != nextEmptyAdj) {
15938                                stepEmpty++;
15939                                if (stepEmpty >= emptyFactor) {
15940                                    stepEmpty = 0;
15941                                    curEmptyAdj = nextEmptyAdj;
15942                                    nextEmptyAdj += 2;
15943                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15944                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15945                                    }
15946                                }
15947                            }
15948                            break;
15949                    }
15950                }
15951
15952                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now);
15953
15954                // Count the number of process types.
15955                switch (app.curProcState) {
15956                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15957                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15958                        mNumCachedHiddenProcs++;
15959                        numCached++;
15960                        if (numCached > cachedProcessLimit) {
15961                            killUnneededProcessLocked(app, "cached #" + numCached);
15962                        }
15963                        break;
15964                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15965                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15966                                && app.lastActivityTime < oldTime) {
15967                            killUnneededProcessLocked(app, "empty for "
15968                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15969                                    / 1000) + "s");
15970                        } else {
15971                            numEmpty++;
15972                            if (numEmpty > emptyProcessLimit) {
15973                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15974                            }
15975                        }
15976                        break;
15977                    default:
15978                        mNumNonCachedProcs++;
15979                        break;
15980                }
15981
15982                if (app.isolated && app.services.size() <= 0) {
15983                    // If this is an isolated process, and there are no
15984                    // services running in it, then the process is no longer
15985                    // needed.  We agressively kill these because we can by
15986                    // definition not re-use the same process again, and it is
15987                    // good to avoid having whatever code was running in them
15988                    // left sitting around after no longer needed.
15989                    killUnneededProcessLocked(app, "isolated not needed");
15990                }
15991
15992                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15993                        && !app.killedByAm) {
15994                    numTrimming++;
15995                }
15996            }
15997        }
15998
15999        mNumServiceProcs = mNewNumServiceProcs;
16000
16001        // Now determine the memory trimming level of background processes.
16002        // Unfortunately we need to start at the back of the list to do this
16003        // properly.  We only do this if the number of background apps we
16004        // are managing to keep around is less than half the maximum we desire;
16005        // if we are keeping a good number around, we'll let them use whatever
16006        // memory they want.
16007        final int numCachedAndEmpty = numCached + numEmpty;
16008        int memFactor;
16009        if (numCached <= ProcessList.TRIM_CACHED_APPS
16010                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16011            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16012                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16013            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16014                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16015            } else {
16016                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16017            }
16018        } else {
16019            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16020        }
16021        // We always allow the memory level to go up (better).  We only allow it to go
16022        // down if we are in a state where that is allowed, *and* the total number of processes
16023        // has gone down since last time.
16024        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16025                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16026                + " last=" + mLastNumProcesses);
16027        if (memFactor > mLastMemoryLevel) {
16028            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16029                memFactor = mLastMemoryLevel;
16030                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16031            }
16032        }
16033        mLastMemoryLevel = memFactor;
16034        mLastNumProcesses = mLruProcesses.size();
16035        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16036        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16037        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16038            if (mLowRamStartTime == 0) {
16039                mLowRamStartTime = now;
16040            }
16041            int step = 0;
16042            int fgTrimLevel;
16043            switch (memFactor) {
16044                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16045                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16046                    break;
16047                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16048                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16049                    break;
16050                default:
16051                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16052                    break;
16053            }
16054            int factor = numTrimming/3;
16055            int minFactor = 2;
16056            if (mHomeProcess != null) minFactor++;
16057            if (mPreviousProcess != null) minFactor++;
16058            if (factor < minFactor) factor = minFactor;
16059            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16060            for (int i=N-1; i>=0; i--) {
16061                ProcessRecord app = mLruProcesses.get(i);
16062                if (allChanged || app.procStateChanged) {
16063                    setProcessTrackerState(app, trackerMemFactor, now);
16064                    app.procStateChanged = false;
16065                }
16066                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16067                        && !app.killedByAm) {
16068                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16069                        try {
16070                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16071                                    "Trimming memory of " + app.processName
16072                                    + " to " + curLevel);
16073                            app.thread.scheduleTrimMemory(curLevel);
16074                        } catch (RemoteException e) {
16075                        }
16076                        if (false) {
16077                            // For now we won't do this; our memory trimming seems
16078                            // to be good enough at this point that destroying
16079                            // activities causes more harm than good.
16080                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16081                                    && app != mHomeProcess && app != mPreviousProcess) {
16082                                // Need to do this on its own message because the stack may not
16083                                // be in a consistent state at this point.
16084                                // For these apps we will also finish their activities
16085                                // to help them free memory.
16086                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16087                            }
16088                        }
16089                    }
16090                    app.trimMemoryLevel = curLevel;
16091                    step++;
16092                    if (step >= factor) {
16093                        step = 0;
16094                        switch (curLevel) {
16095                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16096                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16097                                break;
16098                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16099                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16100                                break;
16101                        }
16102                    }
16103                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16104                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16105                            && app.thread != null) {
16106                        try {
16107                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16108                                    "Trimming memory of heavy-weight " + app.processName
16109                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16110                            app.thread.scheduleTrimMemory(
16111                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16112                        } catch (RemoteException e) {
16113                        }
16114                    }
16115                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16116                } else {
16117                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16118                            || app.systemNoUi) && app.pendingUiClean) {
16119                        // If this application is now in the background and it
16120                        // had done UI, then give it the special trim level to
16121                        // have it free UI resources.
16122                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16123                        if (app.trimMemoryLevel < level && app.thread != null) {
16124                            try {
16125                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16126                                        "Trimming memory of bg-ui " + app.processName
16127                                        + " to " + level);
16128                                app.thread.scheduleTrimMemory(level);
16129                            } catch (RemoteException e) {
16130                            }
16131                        }
16132                        app.pendingUiClean = false;
16133                    }
16134                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16135                        try {
16136                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16137                                    "Trimming memory of fg " + app.processName
16138                                    + " to " + fgTrimLevel);
16139                            app.thread.scheduleTrimMemory(fgTrimLevel);
16140                        } catch (RemoteException e) {
16141                        }
16142                    }
16143                    app.trimMemoryLevel = fgTrimLevel;
16144                }
16145            }
16146        } else {
16147            if (mLowRamStartTime != 0) {
16148                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16149                mLowRamStartTime = 0;
16150            }
16151            for (int i=N-1; i>=0; i--) {
16152                ProcessRecord app = mLruProcesses.get(i);
16153                if (allChanged || app.procStateChanged) {
16154                    setProcessTrackerState(app, trackerMemFactor, now);
16155                    app.procStateChanged = false;
16156                }
16157                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16158                        || app.systemNoUi) && app.pendingUiClean) {
16159                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16160                            && app.thread != null) {
16161                        try {
16162                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16163                                    "Trimming memory of ui hidden " + app.processName
16164                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16165                            app.thread.scheduleTrimMemory(
16166                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16167                        } catch (RemoteException e) {
16168                        }
16169                    }
16170                    app.pendingUiClean = false;
16171                }
16172                app.trimMemoryLevel = 0;
16173            }
16174        }
16175
16176        if (mAlwaysFinishActivities) {
16177            // Need to do this on its own message because the stack may not
16178            // be in a consistent state at this point.
16179            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16180        }
16181
16182        if (allChanged) {
16183            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16184        }
16185
16186        if (mProcessStats.shouldWriteNowLocked(now)) {
16187            mHandler.post(new Runnable() {
16188                @Override public void run() {
16189                    synchronized (ActivityManagerService.this) {
16190                        mProcessStats.writeStateAsyncLocked();
16191                    }
16192                }
16193            });
16194        }
16195
16196        if (DEBUG_OOM_ADJ) {
16197            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16198        }
16199    }
16200
16201    final void trimApplications() {
16202        synchronized (this) {
16203            int i;
16204
16205            // First remove any unused application processes whose package
16206            // has been removed.
16207            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16208                final ProcessRecord app = mRemovedProcesses.get(i);
16209                if (app.activities.size() == 0
16210                        && app.curReceiver == null && app.services.size() == 0) {
16211                    Slog.i(
16212                        TAG, "Exiting empty application process "
16213                        + app.processName + " ("
16214                        + (app.thread != null ? app.thread.asBinder() : null)
16215                        + ")\n");
16216                    if (app.pid > 0 && app.pid != MY_PID) {
16217                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16218                                app.processName, app.setAdj, "empty");
16219                        app.killedByAm = true;
16220                        Process.killProcessQuiet(app.pid);
16221                    } else {
16222                        try {
16223                            app.thread.scheduleExit();
16224                        } catch (Exception e) {
16225                            // Ignore exceptions.
16226                        }
16227                    }
16228                    cleanUpApplicationRecordLocked(app, false, true, -1);
16229                    mRemovedProcesses.remove(i);
16230
16231                    if (app.persistent) {
16232                        if (app.persistent) {
16233                            addAppLocked(app.info, false);
16234                        }
16235                    }
16236                }
16237            }
16238
16239            // Now update the oom adj for all processes.
16240            updateOomAdjLocked();
16241        }
16242    }
16243
16244    /** This method sends the specified signal to each of the persistent apps */
16245    public void signalPersistentProcesses(int sig) throws RemoteException {
16246        if (sig != Process.SIGNAL_USR1) {
16247            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16248        }
16249
16250        synchronized (this) {
16251            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16252                    != PackageManager.PERMISSION_GRANTED) {
16253                throw new SecurityException("Requires permission "
16254                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16255            }
16256
16257            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16258                ProcessRecord r = mLruProcesses.get(i);
16259                if (r.thread != null && r.persistent) {
16260                    Process.sendSignal(r.pid, sig);
16261                }
16262            }
16263        }
16264    }
16265
16266    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16267        if (proc == null || proc == mProfileProc) {
16268            proc = mProfileProc;
16269            path = mProfileFile;
16270            profileType = mProfileType;
16271            clearProfilerLocked();
16272        }
16273        if (proc == null) {
16274            return;
16275        }
16276        try {
16277            proc.thread.profilerControl(false, path, null, profileType);
16278        } catch (RemoteException e) {
16279            throw new IllegalStateException("Process disappeared");
16280        }
16281    }
16282
16283    private void clearProfilerLocked() {
16284        if (mProfileFd != null) {
16285            try {
16286                mProfileFd.close();
16287            } catch (IOException e) {
16288            }
16289        }
16290        mProfileApp = null;
16291        mProfileProc = null;
16292        mProfileFile = null;
16293        mProfileType = 0;
16294        mAutoStopProfiler = false;
16295    }
16296
16297    public boolean profileControl(String process, int userId, boolean start,
16298            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16299
16300        try {
16301            synchronized (this) {
16302                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16303                // its own permission.
16304                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16305                        != PackageManager.PERMISSION_GRANTED) {
16306                    throw new SecurityException("Requires permission "
16307                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16308                }
16309
16310                if (start && fd == null) {
16311                    throw new IllegalArgumentException("null fd");
16312                }
16313
16314                ProcessRecord proc = null;
16315                if (process != null) {
16316                    proc = findProcessLocked(process, userId, "profileControl");
16317                }
16318
16319                if (start && (proc == null || proc.thread == null)) {
16320                    throw new IllegalArgumentException("Unknown process: " + process);
16321                }
16322
16323                if (start) {
16324                    stopProfilerLocked(null, null, 0);
16325                    setProfileApp(proc.info, proc.processName, path, fd, false);
16326                    mProfileProc = proc;
16327                    mProfileType = profileType;
16328                    try {
16329                        fd = fd.dup();
16330                    } catch (IOException e) {
16331                        fd = null;
16332                    }
16333                    proc.thread.profilerControl(start, path, fd, profileType);
16334                    fd = null;
16335                    mProfileFd = null;
16336                } else {
16337                    stopProfilerLocked(proc, path, profileType);
16338                    if (fd != null) {
16339                        try {
16340                            fd.close();
16341                        } catch (IOException e) {
16342                        }
16343                    }
16344                }
16345
16346                return true;
16347            }
16348        } catch (RemoteException e) {
16349            throw new IllegalStateException("Process disappeared");
16350        } finally {
16351            if (fd != null) {
16352                try {
16353                    fd.close();
16354                } catch (IOException e) {
16355                }
16356            }
16357        }
16358    }
16359
16360    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16361        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16362                userId, true, true, callName, null);
16363        ProcessRecord proc = null;
16364        try {
16365            int pid = Integer.parseInt(process);
16366            synchronized (mPidsSelfLocked) {
16367                proc = mPidsSelfLocked.get(pid);
16368            }
16369        } catch (NumberFormatException e) {
16370        }
16371
16372        if (proc == null) {
16373            ArrayMap<String, SparseArray<ProcessRecord>> all
16374                    = mProcessNames.getMap();
16375            SparseArray<ProcessRecord> procs = all.get(process);
16376            if (procs != null && procs.size() > 0) {
16377                proc = procs.valueAt(0);
16378                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16379                    for (int i=1; i<procs.size(); i++) {
16380                        ProcessRecord thisProc = procs.valueAt(i);
16381                        if (thisProc.userId == userId) {
16382                            proc = thisProc;
16383                            break;
16384                        }
16385                    }
16386                }
16387            }
16388        }
16389
16390        return proc;
16391    }
16392
16393    public boolean dumpHeap(String process, int userId, boolean managed,
16394            String path, ParcelFileDescriptor fd) throws RemoteException {
16395
16396        try {
16397            synchronized (this) {
16398                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16399                // its own permission (same as profileControl).
16400                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16401                        != PackageManager.PERMISSION_GRANTED) {
16402                    throw new SecurityException("Requires permission "
16403                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16404                }
16405
16406                if (fd == null) {
16407                    throw new IllegalArgumentException("null fd");
16408                }
16409
16410                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16411                if (proc == null || proc.thread == null) {
16412                    throw new IllegalArgumentException("Unknown process: " + process);
16413                }
16414
16415                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16416                if (!isDebuggable) {
16417                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16418                        throw new SecurityException("Process not debuggable: " + proc);
16419                    }
16420                }
16421
16422                proc.thread.dumpHeap(managed, path, fd);
16423                fd = null;
16424                return true;
16425            }
16426        } catch (RemoteException e) {
16427            throw new IllegalStateException("Process disappeared");
16428        } finally {
16429            if (fd != null) {
16430                try {
16431                    fd.close();
16432                } catch (IOException e) {
16433                }
16434            }
16435        }
16436    }
16437
16438    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16439    public void monitor() {
16440        synchronized (this) { }
16441    }
16442
16443    void onCoreSettingsChange(Bundle settings) {
16444        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16445            ProcessRecord processRecord = mLruProcesses.get(i);
16446            try {
16447                if (processRecord.thread != null) {
16448                    processRecord.thread.setCoreSettings(settings);
16449                }
16450            } catch (RemoteException re) {
16451                /* ignore */
16452            }
16453        }
16454    }
16455
16456    // Multi-user methods
16457
16458    /**
16459     * Start user, if its not already running, but don't bring it to foreground.
16460     */
16461    @Override
16462    public boolean startUserInBackground(final int userId) {
16463        return startUser(userId, /* foreground */ false);
16464    }
16465
16466    /**
16467     * Refreshes the list of users related to the current user when either a
16468     * user switch happens or when a new related user is started in the
16469     * background.
16470     */
16471    private void updateCurrentProfileIdsLocked() {
16472        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16473                mCurrentUserId, false /* enabledOnly */);
16474        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16475        for (int i = 0; i < currentProfileIds.length; i++) {
16476            currentProfileIds[i] = profiles.get(i).id;
16477        }
16478        mCurrentProfileIds = currentProfileIds;
16479    }
16480
16481    private Set getProfileIdsLocked(int userId) {
16482        Set userIds = new HashSet<Integer>();
16483        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16484                userId, false /* enabledOnly */);
16485        for (UserInfo user : profiles) {
16486            userIds.add(Integer.valueOf(user.id));
16487        }
16488        return userIds;
16489    }
16490
16491    @Override
16492    public boolean switchUser(final int userId) {
16493        return startUser(userId, /* foregound */ true);
16494    }
16495
16496    private boolean startUser(final int userId, boolean foreground) {
16497        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16498                != PackageManager.PERMISSION_GRANTED) {
16499            String msg = "Permission Denial: switchUser() from pid="
16500                    + Binder.getCallingPid()
16501                    + ", uid=" + Binder.getCallingUid()
16502                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16503            Slog.w(TAG, msg);
16504            throw new SecurityException(msg);
16505        }
16506
16507        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16508
16509        final long ident = Binder.clearCallingIdentity();
16510        try {
16511            synchronized (this) {
16512                final int oldUserId = mCurrentUserId;
16513                if (oldUserId == userId) {
16514                    return true;
16515                }
16516
16517                mStackSupervisor.setLockTaskModeLocked(null);
16518
16519                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16520                if (userInfo == null) {
16521                    Slog.w(TAG, "No user info for user #" + userId);
16522                    return false;
16523                }
16524
16525                if (foreground) {
16526                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16527                            R.anim.screen_user_enter);
16528                }
16529
16530                boolean needStart = false;
16531
16532                // If the user we are switching to is not currently started, then
16533                // we need to start it now.
16534                if (mStartedUsers.get(userId) == null) {
16535                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16536                    updateStartedUserArrayLocked();
16537                    needStart = true;
16538                }
16539
16540                final Integer userIdInt = Integer.valueOf(userId);
16541                mUserLru.remove(userIdInt);
16542                mUserLru.add(userIdInt);
16543
16544                if (foreground) {
16545                    mCurrentUserId = userId;
16546                    updateCurrentProfileIdsLocked();
16547                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16548                    // Once the internal notion of the active user has switched, we lock the device
16549                    // with the option to show the user switcher on the keyguard.
16550                    mWindowManager.lockNow(null);
16551                } else {
16552                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16553                    updateCurrentProfileIdsLocked();
16554                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16555                    mUserLru.remove(currentUserIdInt);
16556                    mUserLru.add(currentUserIdInt);
16557                }
16558
16559                final UserStartedState uss = mStartedUsers.get(userId);
16560
16561                // Make sure user is in the started state.  If it is currently
16562                // stopping, we need to knock that off.
16563                if (uss.mState == UserStartedState.STATE_STOPPING) {
16564                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16565                    // so we can just fairly silently bring the user back from
16566                    // the almost-dead.
16567                    uss.mState = UserStartedState.STATE_RUNNING;
16568                    updateStartedUserArrayLocked();
16569                    needStart = true;
16570                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16571                    // This means ACTION_SHUTDOWN has been sent, so we will
16572                    // need to treat this as a new boot of the user.
16573                    uss.mState = UserStartedState.STATE_BOOTING;
16574                    updateStartedUserArrayLocked();
16575                    needStart = true;
16576                }
16577
16578                if (uss.mState == UserStartedState.STATE_BOOTING) {
16579                    // Booting up a new user, need to tell system services about it.
16580                    // Note that this is on the same handler as scheduling of broadcasts,
16581                    // which is important because it needs to go first.
16582                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
16583                }
16584
16585                if (foreground) {
16586                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId));
16587                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16588                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16589                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16590                            oldUserId, userId, uss));
16591                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16592                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16593                }
16594
16595                if (needStart) {
16596                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16597                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16598                            | Intent.FLAG_RECEIVER_FOREGROUND);
16599                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16600                    broadcastIntentLocked(null, null, intent,
16601                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16602                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16603                }
16604
16605                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16606                    if (userId != UserHandle.USER_OWNER) {
16607                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16608                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16609                        broadcastIntentLocked(null, null, intent, null,
16610                                new IIntentReceiver.Stub() {
16611                                    public void performReceive(Intent intent, int resultCode,
16612                                            String data, Bundle extras, boolean ordered,
16613                                            boolean sticky, int sendingUser) {
16614                                        userInitialized(uss, userId);
16615                                    }
16616                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16617                                true, false, MY_PID, Process.SYSTEM_UID,
16618                                userId);
16619                        uss.initializing = true;
16620                    } else {
16621                        getUserManagerLocked().makeInitialized(userInfo.id);
16622                    }
16623                }
16624
16625                if (foreground) {
16626                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16627                    if (homeInFront) {
16628                        startHomeActivityLocked(userId);
16629                    } else {
16630                        mStackSupervisor.resumeTopActivitiesLocked();
16631                    }
16632                    EventLogTags.writeAmSwitchUser(userId);
16633                    getUserManagerLocked().userForeground(userId);
16634                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16635                } else {
16636                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
16637                }
16638
16639                if (needStart) {
16640                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16641                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16642                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16643                    broadcastIntentLocked(null, null, intent,
16644                            null, new IIntentReceiver.Stub() {
16645                                @Override
16646                                public void performReceive(Intent intent, int resultCode, String data,
16647                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16648                                        throws RemoteException {
16649                                }
16650                            }, 0, null, null,
16651                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16652                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16653                }
16654            }
16655        } finally {
16656            Binder.restoreCallingIdentity(ident);
16657        }
16658
16659        return true;
16660    }
16661
16662    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16663        long ident = Binder.clearCallingIdentity();
16664        try {
16665            Intent intent;
16666            if (oldUserId >= 0) {
16667                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16668                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16669                        | Intent.FLAG_RECEIVER_FOREGROUND);
16670                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16671                broadcastIntentLocked(null, null, intent,
16672                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16673                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16674            }
16675            if (newUserId >= 0) {
16676                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16677                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16678                        | Intent.FLAG_RECEIVER_FOREGROUND);
16679                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16680                broadcastIntentLocked(null, null, intent,
16681                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16682                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16683                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16684                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16685                        | Intent.FLAG_RECEIVER_FOREGROUND);
16686                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16687                broadcastIntentLocked(null, null, intent,
16688                        null, null, 0, null, null,
16689                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16690                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16691            }
16692        } finally {
16693            Binder.restoreCallingIdentity(ident);
16694        }
16695    }
16696
16697    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16698            final int newUserId) {
16699        final int N = mUserSwitchObservers.beginBroadcast();
16700        if (N > 0) {
16701            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16702                int mCount = 0;
16703                @Override
16704                public void sendResult(Bundle data) throws RemoteException {
16705                    synchronized (ActivityManagerService.this) {
16706                        if (mCurUserSwitchCallback == this) {
16707                            mCount++;
16708                            if (mCount == N) {
16709                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16710                            }
16711                        }
16712                    }
16713                }
16714            };
16715            synchronized (this) {
16716                uss.switching = true;
16717                mCurUserSwitchCallback = callback;
16718            }
16719            for (int i=0; i<N; i++) {
16720                try {
16721                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16722                            newUserId, callback);
16723                } catch (RemoteException e) {
16724                }
16725            }
16726        } else {
16727            synchronized (this) {
16728                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16729            }
16730        }
16731        mUserSwitchObservers.finishBroadcast();
16732    }
16733
16734    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16735        synchronized (this) {
16736            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16737            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16738        }
16739    }
16740
16741    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16742        mCurUserSwitchCallback = null;
16743        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16744        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16745                oldUserId, newUserId, uss));
16746    }
16747
16748    void userInitialized(UserStartedState uss, int newUserId) {
16749        completeSwitchAndInitalize(uss, newUserId, true, false);
16750    }
16751
16752    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16753        completeSwitchAndInitalize(uss, newUserId, false, true);
16754    }
16755
16756    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16757            boolean clearInitializing, boolean clearSwitching) {
16758        boolean unfrozen = false;
16759        synchronized (this) {
16760            if (clearInitializing) {
16761                uss.initializing = false;
16762                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16763            }
16764            if (clearSwitching) {
16765                uss.switching = false;
16766            }
16767            if (!uss.switching && !uss.initializing) {
16768                mWindowManager.stopFreezingScreen();
16769                unfrozen = true;
16770            }
16771        }
16772        if (unfrozen) {
16773            final int N = mUserSwitchObservers.beginBroadcast();
16774            for (int i=0; i<N; i++) {
16775                try {
16776                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16777                } catch (RemoteException e) {
16778                }
16779            }
16780            mUserSwitchObservers.finishBroadcast();
16781        }
16782    }
16783
16784    void scheduleStartProfilesLocked() {
16785        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
16786            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
16787                    DateUtils.SECOND_IN_MILLIS);
16788        }
16789    }
16790
16791    void startProfilesLocked() {
16792        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
16793        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16794                mCurrentUserId, false /* enabledOnly */);
16795        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
16796        for (UserInfo user : profiles) {
16797            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
16798                    && user.id != mCurrentUserId) {
16799                toStart.add(user);
16800            }
16801        }
16802        final int n = toStart.size();
16803        int i = 0;
16804        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
16805            startUserInBackground(toStart.get(i).id);
16806        }
16807        if (i < n) {
16808            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
16809        }
16810    }
16811
16812    void finishUserBoot(UserStartedState uss) {
16813        synchronized (this) {
16814            if (uss.mState == UserStartedState.STATE_BOOTING
16815                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16816                uss.mState = UserStartedState.STATE_RUNNING;
16817                final int userId = uss.mHandle.getIdentifier();
16818                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16819                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16820                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16821                broadcastIntentLocked(null, null, intent,
16822                        null, null, 0, null, null,
16823                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16824                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16825            }
16826        }
16827    }
16828
16829    void finishUserSwitch(UserStartedState uss) {
16830        synchronized (this) {
16831            finishUserBoot(uss);
16832
16833            startProfilesLocked();
16834
16835            int num = mUserLru.size();
16836            int i = 0;
16837            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16838                Integer oldUserId = mUserLru.get(i);
16839                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16840                if (oldUss == null) {
16841                    // Shouldn't happen, but be sane if it does.
16842                    mUserLru.remove(i);
16843                    num--;
16844                    continue;
16845                }
16846                if (oldUss.mState == UserStartedState.STATE_STOPPING
16847                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16848                    // This user is already stopping, doesn't count.
16849                    num--;
16850                    i++;
16851                    continue;
16852                }
16853                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16854                    // Owner and current can't be stopped, but count as running.
16855                    i++;
16856                    continue;
16857                }
16858                // This is a user to be stopped.
16859                stopUserLocked(oldUserId, null);
16860                num--;
16861                i++;
16862            }
16863        }
16864    }
16865
16866    @Override
16867    public int stopUser(final int userId, final IStopUserCallback callback) {
16868        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16869                != PackageManager.PERMISSION_GRANTED) {
16870            String msg = "Permission Denial: switchUser() from pid="
16871                    + Binder.getCallingPid()
16872                    + ", uid=" + Binder.getCallingUid()
16873                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16874            Slog.w(TAG, msg);
16875            throw new SecurityException(msg);
16876        }
16877        if (userId <= 0) {
16878            throw new IllegalArgumentException("Can't stop primary user " + userId);
16879        }
16880        synchronized (this) {
16881            return stopUserLocked(userId, callback);
16882        }
16883    }
16884
16885    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16886        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
16887        if (mCurrentUserId == userId) {
16888            return ActivityManager.USER_OP_IS_CURRENT;
16889        }
16890
16891        final UserStartedState uss = mStartedUsers.get(userId);
16892        if (uss == null) {
16893            // User is not started, nothing to do...  but we do need to
16894            // callback if requested.
16895            if (callback != null) {
16896                mHandler.post(new Runnable() {
16897                    @Override
16898                    public void run() {
16899                        try {
16900                            callback.userStopped(userId);
16901                        } catch (RemoteException e) {
16902                        }
16903                    }
16904                });
16905            }
16906            return ActivityManager.USER_OP_SUCCESS;
16907        }
16908
16909        if (callback != null) {
16910            uss.mStopCallbacks.add(callback);
16911        }
16912
16913        if (uss.mState != UserStartedState.STATE_STOPPING
16914                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16915            uss.mState = UserStartedState.STATE_STOPPING;
16916            updateStartedUserArrayLocked();
16917
16918            long ident = Binder.clearCallingIdentity();
16919            try {
16920                // We are going to broadcast ACTION_USER_STOPPING and then
16921                // once that is done send a final ACTION_SHUTDOWN and then
16922                // stop the user.
16923                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16924                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16925                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16926                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16927                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16928                // This is the result receiver for the final shutdown broadcast.
16929                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16930                    @Override
16931                    public void performReceive(Intent intent, int resultCode, String data,
16932                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16933                        finishUserStop(uss);
16934                    }
16935                };
16936                // This is the result receiver for the initial stopping broadcast.
16937                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16938                    @Override
16939                    public void performReceive(Intent intent, int resultCode, String data,
16940                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16941                        // On to the next.
16942                        synchronized (ActivityManagerService.this) {
16943                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16944                                // Whoops, we are being started back up.  Abort, abort!
16945                                return;
16946                            }
16947                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16948                        }
16949                        mSystemServiceManager.stopUser(userId);
16950                        broadcastIntentLocked(null, null, shutdownIntent,
16951                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16952                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16953                    }
16954                };
16955                // Kick things off.
16956                broadcastIntentLocked(null, null, stoppingIntent,
16957                        null, stoppingReceiver, 0, null, null,
16958                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16959                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16960            } finally {
16961                Binder.restoreCallingIdentity(ident);
16962            }
16963        }
16964
16965        return ActivityManager.USER_OP_SUCCESS;
16966    }
16967
16968    void finishUserStop(UserStartedState uss) {
16969        final int userId = uss.mHandle.getIdentifier();
16970        boolean stopped;
16971        ArrayList<IStopUserCallback> callbacks;
16972        synchronized (this) {
16973            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16974            if (mStartedUsers.get(userId) != uss) {
16975                stopped = false;
16976            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16977                stopped = false;
16978            } else {
16979                stopped = true;
16980                // User can no longer run.
16981                mStartedUsers.remove(userId);
16982                mUserLru.remove(Integer.valueOf(userId));
16983                updateStartedUserArrayLocked();
16984
16985                // Clean up all state and processes associated with the user.
16986                // Kill all the processes for the user.
16987                forceStopUserLocked(userId, "finish user");
16988            }
16989        }
16990
16991        for (int i=0; i<callbacks.size(); i++) {
16992            try {
16993                if (stopped) callbacks.get(i).userStopped(userId);
16994                else callbacks.get(i).userStopAborted(userId);
16995            } catch (RemoteException e) {
16996            }
16997        }
16998
16999        if (stopped) {
17000            mSystemServiceManager.cleanupUser(userId);
17001            synchronized (this) {
17002                mStackSupervisor.removeUserLocked(userId);
17003            }
17004        }
17005    }
17006
17007    @Override
17008    public UserInfo getCurrentUser() {
17009        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17010                != PackageManager.PERMISSION_GRANTED) && (
17011                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
17012                != PackageManager.PERMISSION_GRANTED)) {
17013            String msg = "Permission Denial: getCurrentUser() from pid="
17014                    + Binder.getCallingPid()
17015                    + ", uid=" + Binder.getCallingUid()
17016                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17017            Slog.w(TAG, msg);
17018            throw new SecurityException(msg);
17019        }
17020        synchronized (this) {
17021            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17022        }
17023    }
17024
17025    int getCurrentUserIdLocked() {
17026        return mCurrentUserId;
17027    }
17028
17029    @Override
17030    public boolean isUserRunning(int userId, boolean orStopped) {
17031        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17032                != PackageManager.PERMISSION_GRANTED) {
17033            String msg = "Permission Denial: isUserRunning() from pid="
17034                    + Binder.getCallingPid()
17035                    + ", uid=" + Binder.getCallingUid()
17036                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17037            Slog.w(TAG, msg);
17038            throw new SecurityException(msg);
17039        }
17040        synchronized (this) {
17041            return isUserRunningLocked(userId, orStopped);
17042        }
17043    }
17044
17045    boolean isUserRunningLocked(int userId, boolean orStopped) {
17046        UserStartedState state = mStartedUsers.get(userId);
17047        if (state == null) {
17048            return false;
17049        }
17050        if (orStopped) {
17051            return true;
17052        }
17053        return state.mState != UserStartedState.STATE_STOPPING
17054                && state.mState != UserStartedState.STATE_SHUTDOWN;
17055    }
17056
17057    @Override
17058    public int[] getRunningUserIds() {
17059        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17060                != PackageManager.PERMISSION_GRANTED) {
17061            String msg = "Permission Denial: isUserRunning() from pid="
17062                    + Binder.getCallingPid()
17063                    + ", uid=" + Binder.getCallingUid()
17064                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17065            Slog.w(TAG, msg);
17066            throw new SecurityException(msg);
17067        }
17068        synchronized (this) {
17069            return mStartedUserArray;
17070        }
17071    }
17072
17073    private void updateStartedUserArrayLocked() {
17074        int num = 0;
17075        for (int i=0; i<mStartedUsers.size();  i++) {
17076            UserStartedState uss = mStartedUsers.valueAt(i);
17077            // This list does not include stopping users.
17078            if (uss.mState != UserStartedState.STATE_STOPPING
17079                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17080                num++;
17081            }
17082        }
17083        mStartedUserArray = new int[num];
17084        num = 0;
17085        for (int i=0; i<mStartedUsers.size();  i++) {
17086            UserStartedState uss = mStartedUsers.valueAt(i);
17087            if (uss.mState != UserStartedState.STATE_STOPPING
17088                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17089                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17090                num++;
17091            }
17092        }
17093    }
17094
17095    @Override
17096    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17097        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
17098                != PackageManager.PERMISSION_GRANTED) {
17099            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17100                    + Binder.getCallingPid()
17101                    + ", uid=" + Binder.getCallingUid()
17102                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
17103            Slog.w(TAG, msg);
17104            throw new SecurityException(msg);
17105        }
17106
17107        mUserSwitchObservers.register(observer);
17108    }
17109
17110    @Override
17111    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17112        mUserSwitchObservers.unregister(observer);
17113    }
17114
17115    private boolean userExists(int userId) {
17116        if (userId == 0) {
17117            return true;
17118        }
17119        UserManagerService ums = getUserManagerLocked();
17120        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17121    }
17122
17123    int[] getUsersLocked() {
17124        UserManagerService ums = getUserManagerLocked();
17125        return ums != null ? ums.getUserIds() : new int[] { 0 };
17126    }
17127
17128    UserManagerService getUserManagerLocked() {
17129        if (mUserManager == null) {
17130            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17131            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17132        }
17133        return mUserManager;
17134    }
17135
17136    private int applyUserId(int uid, int userId) {
17137        return UserHandle.getUid(userId, uid);
17138    }
17139
17140    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17141        if (info == null) return null;
17142        ApplicationInfo newInfo = new ApplicationInfo(info);
17143        newInfo.uid = applyUserId(info.uid, userId);
17144        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17145                + info.packageName;
17146        return newInfo;
17147    }
17148
17149    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17150        if (aInfo == null
17151                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17152            return aInfo;
17153        }
17154
17155        ActivityInfo info = new ActivityInfo(aInfo);
17156        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17157        return info;
17158    }
17159
17160    private final class LocalService extends ActivityManagerInternal {
17161        @Override
17162        public void goingToSleep() {
17163            ActivityManagerService.this.goingToSleep();
17164        }
17165
17166        @Override
17167        public void wakingUp() {
17168            ActivityManagerService.this.wakingUp();
17169        }
17170    }
17171
17172    /**
17173     * An implementation of IAppTask, that allows an app to manage its own tasks via
17174     * {@link android.app.ActivityManager#AppTask}.  We keep track of the callingUid to ensure that
17175     * only the process that calls getAppTasks() can call the AppTask methods.
17176     */
17177    class AppTaskImpl extends IAppTask.Stub {
17178        private int mTaskId;
17179        private int mCallingUid;
17180
17181        public AppTaskImpl(int taskId, int callingUid) {
17182            mTaskId = taskId;
17183            mCallingUid = callingUid;
17184        }
17185
17186        @Override
17187        public void finishAndRemoveTask() {
17188            // Ensure that we are called from the same process that created this AppTask
17189            if (mCallingUid != Binder.getCallingUid()) {
17190                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17191                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17192                return;
17193            }
17194
17195            synchronized (ActivityManagerService.this) {
17196                long origId = Binder.clearCallingIdentity();
17197                try {
17198                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17199                    if (tr != null) {
17200                        // Only kill the process if we are not a new document
17201                        int flags = tr.getBaseIntent().getFlags();
17202                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17203                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17204                        removeTaskByIdLocked(mTaskId,
17205                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17206                    }
17207                } finally {
17208                    Binder.restoreCallingIdentity(origId);
17209                }
17210            }
17211        }
17212
17213        @Override
17214        public ActivityManager.RecentTaskInfo getTaskInfo() {
17215            // Ensure that we are called from the same process that created this AppTask
17216            if (mCallingUid != Binder.getCallingUid()) {
17217                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17218                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17219                return null;
17220            }
17221
17222            synchronized (ActivityManagerService.this) {
17223                long origId = Binder.clearCallingIdentity();
17224                try {
17225                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17226                    if (tr != null) {
17227                        return createRecentTaskInfoFromTaskRecord(tr);
17228                    }
17229                } finally {
17230                    Binder.restoreCallingIdentity(origId);
17231                }
17232                return null;
17233            }
17234        }
17235    }
17236}
17237