ActivityManagerService.java revision ef73ee1dd98acfc4a19561367cfc3e4d8bbe06ea
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    ArrayList<TaskRecord> mRecentTasks;
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     * Save recent tasks information across reboots.
825     */
826    final TaskPersister mTaskPersister;
827
828    /**
829     * Current configuration information.  HistoryRecord objects are given
830     * a reference to this object to indicate which configuration they are
831     * currently running in, so this object must be kept immutable.
832     */
833    Configuration mConfiguration = new Configuration();
834
835    /**
836     * Current sequencing integer of the configuration, for skipping old
837     * configurations.
838     */
839    int mConfigurationSeq = 0;
840
841    /**
842     * Hardware-reported OpenGLES version.
843     */
844    final int GL_ES_VERSION;
845
846    /**
847     * List of initialization arguments to pass to all processes when binding applications to them.
848     * For example, references to the commonly used services.
849     */
850    HashMap<String, IBinder> mAppBindArgs;
851
852    /**
853     * Temporary to avoid allocations.  Protected by main lock.
854     */
855    final StringBuilder mStringBuilder = new StringBuilder(256);
856
857    /**
858     * Used to control how we initialize the service.
859     */
860    ComponentName mTopComponent;
861    String mTopAction = Intent.ACTION_MAIN;
862    String mTopData;
863    boolean mProcessesReady = false;
864    boolean mSystemReady = false;
865    boolean mBooting = false;
866    boolean mWaitingUpdate = false;
867    boolean mDidUpdate = false;
868    boolean mOnBattery = false;
869    boolean mLaunchWarningShown = false;
870
871    Context mContext;
872
873    int mFactoryTest;
874
875    boolean mCheckedForSetup;
876
877    /**
878     * The time at which we will allow normal application switches again,
879     * after a call to {@link #stopAppSwitches()}.
880     */
881    long mAppSwitchesAllowedTime;
882
883    /**
884     * This is set to true after the first switch after mAppSwitchesAllowedTime
885     * is set; any switches after that will clear the time.
886     */
887    boolean mDidAppSwitch;
888
889    /**
890     * Last time (in realtime) at which we checked for power usage.
891     */
892    long mLastPowerCheckRealtime;
893
894    /**
895     * Last time (in uptime) at which we checked for power usage.
896     */
897    long mLastPowerCheckUptime;
898
899    /**
900     * Set while we are wanting to sleep, to prevent any
901     * activities from being started/resumed.
902     */
903    private boolean mSleeping = false;
904
905    /**
906     * Set while we are running a voice interaction.  This overrides
907     * sleeping while it is active.
908     */
909    private boolean mRunningVoice = false;
910
911    /**
912     * State of external calls telling us if the device is asleep.
913     */
914    private boolean mWentToSleep = false;
915
916    /**
917     * State of external call telling us if the lock screen is shown.
918     */
919    private boolean mLockScreenShown = false;
920
921    /**
922     * Set if we are shutting down the system, similar to sleeping.
923     */
924    boolean mShuttingDown = false;
925
926    /**
927     * Current sequence id for oom_adj computation traversal.
928     */
929    int mAdjSeq = 0;
930
931    /**
932     * Current sequence id for process LRU updating.
933     */
934    int mLruSeq = 0;
935
936    /**
937     * Keep track of the non-cached/empty process we last found, to help
938     * determine how to distribute cached/empty processes next time.
939     */
940    int mNumNonCachedProcs = 0;
941
942    /**
943     * Keep track of the number of cached hidden procs, to balance oom adj
944     * distribution between those and empty procs.
945     */
946    int mNumCachedHiddenProcs = 0;
947
948    /**
949     * Keep track of the number of service processes we last found, to
950     * determine on the next iteration which should be B services.
951     */
952    int mNumServiceProcs = 0;
953    int mNewNumAServiceProcs = 0;
954    int mNewNumServiceProcs = 0;
955
956    /**
957     * Allow the current computed overall memory level of the system to go down?
958     * This is set to false when we are killing processes for reasons other than
959     * memory management, so that the now smaller process list will not be taken as
960     * an indication that memory is tighter.
961     */
962    boolean mAllowLowerMemLevel = false;
963
964    /**
965     * The last computed memory level, for holding when we are in a state that
966     * processes are going away for other reasons.
967     */
968    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
969
970    /**
971     * The last total number of process we have, to determine if changes actually look
972     * like a shrinking number of process due to lower RAM.
973     */
974    int mLastNumProcesses;
975
976    /**
977     * The uptime of the last time we performed idle maintenance.
978     */
979    long mLastIdleTime = SystemClock.uptimeMillis();
980
981    /**
982     * Total time spent with RAM that has been added in the past since the last idle time.
983     */
984    long mLowRamTimeSinceLastIdle = 0;
985
986    /**
987     * If RAM is currently low, when that horrible situation started.
988     */
989    long mLowRamStartTime = 0;
990
991    /**
992     * For reporting to battery stats the current top application.
993     */
994    private String mCurResumedPackage = null;
995    private int mCurResumedUid = -1;
996
997    /**
998     * For reporting to battery stats the apps currently running foreground
999     * service.  The ProcessMap is package/uid tuples; each of these contain
1000     * an array of the currently foreground processes.
1001     */
1002    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1003            = new ProcessMap<ArrayList<ProcessRecord>>();
1004
1005    /**
1006     * This is set if we had to do a delayed dexopt of an app before launching
1007     * it, to increase the ANR timeouts in that case.
1008     */
1009    boolean mDidDexOpt;
1010
1011    /**
1012     * Set if the systemServer made a call to enterSafeMode.
1013     */
1014    boolean mSafeMode;
1015
1016    String mDebugApp = null;
1017    boolean mWaitForDebugger = false;
1018    boolean mDebugTransient = false;
1019    String mOrigDebugApp = null;
1020    boolean mOrigWaitForDebugger = false;
1021    boolean mAlwaysFinishActivities = false;
1022    IActivityController mController = null;
1023    String mProfileApp = null;
1024    ProcessRecord mProfileProc = null;
1025    String mProfileFile;
1026    ParcelFileDescriptor mProfileFd;
1027    int mProfileType = 0;
1028    boolean mAutoStopProfiler = false;
1029    String mOpenGlTraceApp = null;
1030
1031    static class ProcessChangeItem {
1032        static final int CHANGE_ACTIVITIES = 1<<0;
1033        static final int CHANGE_PROCESS_STATE = 1<<1;
1034        int changes;
1035        int uid;
1036        int pid;
1037        int processState;
1038        boolean foregroundActivities;
1039    }
1040
1041    final RemoteCallbackList<IProcessObserver> mProcessObservers
1042            = new RemoteCallbackList<IProcessObserver>();
1043    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1044
1045    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1046            = new ArrayList<ProcessChangeItem>();
1047    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1048            = new ArrayList<ProcessChangeItem>();
1049
1050    /**
1051     * Runtime CPU use collection thread.  This object's lock is used to
1052     * protect all related state.
1053     */
1054    final Thread mProcessCpuThread;
1055
1056    /**
1057     * Used to collect process stats when showing not responding dialog.
1058     * Protected by mProcessCpuThread.
1059     */
1060    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1061            MONITOR_THREAD_CPU_USAGE);
1062    final AtomicLong mLastCpuTime = new AtomicLong(0);
1063    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1064
1065    long mLastWriteTime = 0;
1066
1067    /**
1068     * Used to retain an update lock when the foreground activity is in
1069     * immersive mode.
1070     */
1071    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1072
1073    /**
1074     * Set to true after the system has finished booting.
1075     */
1076    boolean mBooted = false;
1077
1078    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1079    int mProcessLimitOverride = -1;
1080
1081    WindowManagerService mWindowManager;
1082
1083    final ActivityThread mSystemThread;
1084
1085    int mCurrentUserId = 0;
1086    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1087    private UserManagerService mUserManager;
1088
1089    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1090        final ProcessRecord mApp;
1091        final int mPid;
1092        final IApplicationThread mAppThread;
1093
1094        AppDeathRecipient(ProcessRecord app, int pid,
1095                IApplicationThread thread) {
1096            if (localLOGV) Slog.v(
1097                TAG, "New death recipient " + this
1098                + " for thread " + thread.asBinder());
1099            mApp = app;
1100            mPid = pid;
1101            mAppThread = thread;
1102        }
1103
1104        @Override
1105        public void binderDied() {
1106            if (localLOGV) Slog.v(
1107                TAG, "Death received in " + this
1108                + " for thread " + mAppThread.asBinder());
1109            synchronized(ActivityManagerService.this) {
1110                appDiedLocked(mApp, mPid, mAppThread);
1111            }
1112        }
1113    }
1114
1115    static final int SHOW_ERROR_MSG = 1;
1116    static final int SHOW_NOT_RESPONDING_MSG = 2;
1117    static final int SHOW_FACTORY_ERROR_MSG = 3;
1118    static final int UPDATE_CONFIGURATION_MSG = 4;
1119    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1120    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1121    static final int SERVICE_TIMEOUT_MSG = 12;
1122    static final int UPDATE_TIME_ZONE = 13;
1123    static final int SHOW_UID_ERROR_MSG = 14;
1124    static final int IM_FEELING_LUCKY_MSG = 15;
1125    static final int PROC_START_TIMEOUT_MSG = 20;
1126    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1127    static final int KILL_APPLICATION_MSG = 22;
1128    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1129    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1130    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1131    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1132    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1133    static final int CLEAR_DNS_CACHE_MSG = 28;
1134    static final int UPDATE_HTTP_PROXY_MSG = 29;
1135    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1136    static final int DISPATCH_PROCESSES_CHANGED = 31;
1137    static final int DISPATCH_PROCESS_DIED = 32;
1138    static final int REPORT_MEM_USAGE_MSG = 33;
1139    static final int REPORT_USER_SWITCH_MSG = 34;
1140    static final int CONTINUE_USER_SWITCH_MSG = 35;
1141    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1142    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1143    static final int PERSIST_URI_GRANTS_MSG = 38;
1144    static final int REQUEST_ALL_PSS_MSG = 39;
1145    static final int START_PROFILES_MSG = 40;
1146    static final int UPDATE_TIME = 41;
1147    static final int SYSTEM_USER_START_MSG = 42;
1148    static final int SYSTEM_USER_CURRENT_MSG = 43;
1149
1150    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1151    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1152    static final int FIRST_COMPAT_MODE_MSG = 300;
1153    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1154
1155    AlertDialog mUidAlert;
1156    CompatModeDialog mCompatModeDialog;
1157    long mLastMemUsageReportTime = 0;
1158
1159    /**
1160     * Flag whether the current user is a "monkey", i.e. whether
1161     * the UI is driven by a UI automation tool.
1162     */
1163    private boolean mUserIsMonkey;
1164
1165    final ServiceThread mHandlerThread;
1166    final MainHandler mHandler;
1167
1168    final class MainHandler extends Handler {
1169        public MainHandler(Looper looper) {
1170            super(looper, null, true);
1171        }
1172
1173        @Override
1174        public void handleMessage(Message msg) {
1175            switch (msg.what) {
1176            case SHOW_ERROR_MSG: {
1177                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1178                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1179                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1180                synchronized (ActivityManagerService.this) {
1181                    ProcessRecord proc = (ProcessRecord)data.get("app");
1182                    AppErrorResult res = (AppErrorResult) data.get("result");
1183                    if (proc != null && proc.crashDialog != null) {
1184                        Slog.e(TAG, "App already has crash dialog: " + proc);
1185                        if (res != null) {
1186                            res.set(0);
1187                        }
1188                        return;
1189                    }
1190                    if (!showBackground && UserHandle.getAppId(proc.uid)
1191                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1192                            && proc.pid != MY_PID) {
1193                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1194                        if (res != null) {
1195                            res.set(0);
1196                        }
1197                        return;
1198                    }
1199                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1200                        Dialog d = new AppErrorDialog(mContext,
1201                                ActivityManagerService.this, res, proc);
1202                        d.show();
1203                        proc.crashDialog = d;
1204                    } else {
1205                        // The device is asleep, so just pretend that the user
1206                        // saw a crash dialog and hit "force quit".
1207                        if (res != null) {
1208                            res.set(0);
1209                        }
1210                    }
1211                }
1212
1213                ensureBootCompleted();
1214            } break;
1215            case SHOW_NOT_RESPONDING_MSG: {
1216                synchronized (ActivityManagerService.this) {
1217                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1218                    ProcessRecord proc = (ProcessRecord)data.get("app");
1219                    if (proc != null && proc.anrDialog != null) {
1220                        Slog.e(TAG, "App already has anr dialog: " + proc);
1221                        return;
1222                    }
1223
1224                    Intent intent = new Intent("android.intent.action.ANR");
1225                    if (!mProcessesReady) {
1226                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1227                                | Intent.FLAG_RECEIVER_FOREGROUND);
1228                    }
1229                    broadcastIntentLocked(null, null, intent,
1230                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1231                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1232
1233                    if (mShowDialogs) {
1234                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1235                                mContext, proc, (ActivityRecord)data.get("activity"),
1236                                msg.arg1 != 0);
1237                        d.show();
1238                        proc.anrDialog = d;
1239                    } else {
1240                        // Just kill the app if there is no dialog to be shown.
1241                        killAppAtUsersRequest(proc, null);
1242                    }
1243                }
1244
1245                ensureBootCompleted();
1246            } break;
1247            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1248                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1249                synchronized (ActivityManagerService.this) {
1250                    ProcessRecord proc = (ProcessRecord) data.get("app");
1251                    if (proc == null) {
1252                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1253                        break;
1254                    }
1255                    if (proc.crashDialog != null) {
1256                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1257                        return;
1258                    }
1259                    AppErrorResult res = (AppErrorResult) data.get("result");
1260                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1261                        Dialog d = new StrictModeViolationDialog(mContext,
1262                                ActivityManagerService.this, res, proc);
1263                        d.show();
1264                        proc.crashDialog = d;
1265                    } else {
1266                        // The device is asleep, so just pretend that the user
1267                        // saw a crash dialog and hit "force quit".
1268                        res.set(0);
1269                    }
1270                }
1271                ensureBootCompleted();
1272            } break;
1273            case SHOW_FACTORY_ERROR_MSG: {
1274                Dialog d = new FactoryErrorDialog(
1275                    mContext, msg.getData().getCharSequence("msg"));
1276                d.show();
1277                ensureBootCompleted();
1278            } break;
1279            case UPDATE_CONFIGURATION_MSG: {
1280                final ContentResolver resolver = mContext.getContentResolver();
1281                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1282            } break;
1283            case GC_BACKGROUND_PROCESSES_MSG: {
1284                synchronized (ActivityManagerService.this) {
1285                    performAppGcsIfAppropriateLocked();
1286                }
1287            } break;
1288            case WAIT_FOR_DEBUGGER_MSG: {
1289                synchronized (ActivityManagerService.this) {
1290                    ProcessRecord app = (ProcessRecord)msg.obj;
1291                    if (msg.arg1 != 0) {
1292                        if (!app.waitedForDebugger) {
1293                            Dialog d = new AppWaitingForDebuggerDialog(
1294                                    ActivityManagerService.this,
1295                                    mContext, app);
1296                            app.waitDialog = d;
1297                            app.waitedForDebugger = true;
1298                            d.show();
1299                        }
1300                    } else {
1301                        if (app.waitDialog != null) {
1302                            app.waitDialog.dismiss();
1303                            app.waitDialog = null;
1304                        }
1305                    }
1306                }
1307            } break;
1308            case SERVICE_TIMEOUT_MSG: {
1309                if (mDidDexOpt) {
1310                    mDidDexOpt = false;
1311                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1312                    nmsg.obj = msg.obj;
1313                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1314                    return;
1315                }
1316                mServices.serviceTimeout((ProcessRecord)msg.obj);
1317            } break;
1318            case UPDATE_TIME_ZONE: {
1319                synchronized (ActivityManagerService.this) {
1320                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1321                        ProcessRecord r = mLruProcesses.get(i);
1322                        if (r.thread != null) {
1323                            try {
1324                                r.thread.updateTimeZone();
1325                            } catch (RemoteException ex) {
1326                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1327                            }
1328                        }
1329                    }
1330                }
1331            } break;
1332            case CLEAR_DNS_CACHE_MSG: {
1333                synchronized (ActivityManagerService.this) {
1334                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1335                        ProcessRecord r = mLruProcesses.get(i);
1336                        if (r.thread != null) {
1337                            try {
1338                                r.thread.clearDnsCache();
1339                            } catch (RemoteException ex) {
1340                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1341                            }
1342                        }
1343                    }
1344                }
1345            } break;
1346            case UPDATE_HTTP_PROXY_MSG: {
1347                ProxyInfo proxy = (ProxyInfo)msg.obj;
1348                String host = "";
1349                String port = "";
1350                String exclList = "";
1351                Uri pacFileUrl = Uri.EMPTY;
1352                if (proxy != null) {
1353                    host = proxy.getHost();
1354                    port = Integer.toString(proxy.getPort());
1355                    exclList = proxy.getExclusionListAsString();
1356                    pacFileUrl = proxy.getPacFileUrl();
1357                }
1358                synchronized (ActivityManagerService.this) {
1359                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1360                        ProcessRecord r = mLruProcesses.get(i);
1361                        if (r.thread != null) {
1362                            try {
1363                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1364                            } catch (RemoteException ex) {
1365                                Slog.w(TAG, "Failed to update http proxy for: " +
1366                                        r.info.processName);
1367                            }
1368                        }
1369                    }
1370                }
1371            } break;
1372            case SHOW_UID_ERROR_MSG: {
1373                String title = "System UIDs Inconsistent";
1374                String text = "UIDs on the system are inconsistent, you need to wipe your"
1375                        + " data partition or your device will be unstable.";
1376                Log.e(TAG, title + ": " + text);
1377                if (mShowDialogs) {
1378                    // XXX This is a temporary dialog, no need to localize.
1379                    AlertDialog d = new BaseErrorDialog(mContext);
1380                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1381                    d.setCancelable(false);
1382                    d.setTitle(title);
1383                    d.setMessage(text);
1384                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1385                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1386                    mUidAlert = d;
1387                    d.show();
1388                }
1389            } break;
1390            case IM_FEELING_LUCKY_MSG: {
1391                if (mUidAlert != null) {
1392                    mUidAlert.dismiss();
1393                    mUidAlert = null;
1394                }
1395            } break;
1396            case PROC_START_TIMEOUT_MSG: {
1397                if (mDidDexOpt) {
1398                    mDidDexOpt = false;
1399                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1400                    nmsg.obj = msg.obj;
1401                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1402                    return;
1403                }
1404                ProcessRecord app = (ProcessRecord)msg.obj;
1405                synchronized (ActivityManagerService.this) {
1406                    processStartTimedOutLocked(app);
1407                }
1408            } break;
1409            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1410                synchronized (ActivityManagerService.this) {
1411                    doPendingActivityLaunchesLocked(true);
1412                }
1413            } break;
1414            case KILL_APPLICATION_MSG: {
1415                synchronized (ActivityManagerService.this) {
1416                    int appid = msg.arg1;
1417                    boolean restart = (msg.arg2 == 1);
1418                    Bundle bundle = (Bundle)msg.obj;
1419                    String pkg = bundle.getString("pkg");
1420                    String reason = bundle.getString("reason");
1421                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1422                            false, UserHandle.USER_ALL, reason);
1423                }
1424            } break;
1425            case FINALIZE_PENDING_INTENT_MSG: {
1426                ((PendingIntentRecord)msg.obj).completeFinalize();
1427            } break;
1428            case POST_HEAVY_NOTIFICATION_MSG: {
1429                INotificationManager inm = NotificationManager.getService();
1430                if (inm == null) {
1431                    return;
1432                }
1433
1434                ActivityRecord root = (ActivityRecord)msg.obj;
1435                ProcessRecord process = root.app;
1436                if (process == null) {
1437                    return;
1438                }
1439
1440                try {
1441                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1442                    String text = mContext.getString(R.string.heavy_weight_notification,
1443                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1444                    Notification notification = new Notification();
1445                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1446                    notification.when = 0;
1447                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1448                    notification.tickerText = text;
1449                    notification.defaults = 0; // please be quiet
1450                    notification.sound = null;
1451                    notification.vibrate = null;
1452                    notification.setLatestEventInfo(context, text,
1453                            mContext.getText(R.string.heavy_weight_notification_detail),
1454                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1455                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1456                                    new UserHandle(root.userId)));
1457
1458                    try {
1459                        int[] outId = new int[1];
1460                        inm.enqueueNotificationWithTag("android", "android", null,
1461                                R.string.heavy_weight_notification,
1462                                notification, outId, root.userId);
1463                    } catch (RuntimeException e) {
1464                        Slog.w(ActivityManagerService.TAG,
1465                                "Error showing notification for heavy-weight app", e);
1466                    } catch (RemoteException e) {
1467                    }
1468                } catch (NameNotFoundException e) {
1469                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1470                }
1471            } break;
1472            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1473                INotificationManager inm = NotificationManager.getService();
1474                if (inm == null) {
1475                    return;
1476                }
1477                try {
1478                    inm.cancelNotificationWithTag("android", null,
1479                            R.string.heavy_weight_notification,  msg.arg1);
1480                } catch (RuntimeException e) {
1481                    Slog.w(ActivityManagerService.TAG,
1482                            "Error canceling notification for service", e);
1483                } catch (RemoteException e) {
1484                }
1485            } break;
1486            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1487                synchronized (ActivityManagerService.this) {
1488                    checkExcessivePowerUsageLocked(true);
1489                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1490                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1491                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1492                }
1493            } break;
1494            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1495                synchronized (ActivityManagerService.this) {
1496                    ActivityRecord ar = (ActivityRecord)msg.obj;
1497                    if (mCompatModeDialog != null) {
1498                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1499                                ar.info.applicationInfo.packageName)) {
1500                            return;
1501                        }
1502                        mCompatModeDialog.dismiss();
1503                        mCompatModeDialog = null;
1504                    }
1505                    if (ar != null && false) {
1506                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1507                                ar.packageName)) {
1508                            int mode = mCompatModePackages.computeCompatModeLocked(
1509                                    ar.info.applicationInfo);
1510                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1511                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1512                                mCompatModeDialog = new CompatModeDialog(
1513                                        ActivityManagerService.this, mContext,
1514                                        ar.info.applicationInfo);
1515                                mCompatModeDialog.show();
1516                            }
1517                        }
1518                    }
1519                }
1520                break;
1521            }
1522            case DISPATCH_PROCESSES_CHANGED: {
1523                dispatchProcessesChanged();
1524                break;
1525            }
1526            case DISPATCH_PROCESS_DIED: {
1527                final int pid = msg.arg1;
1528                final int uid = msg.arg2;
1529                dispatchProcessDied(pid, uid);
1530                break;
1531            }
1532            case REPORT_MEM_USAGE_MSG: {
1533                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1534                Thread thread = new Thread() {
1535                    @Override public void run() {
1536                        final SparseArray<ProcessMemInfo> infoMap
1537                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1538                        for (int i=0, N=memInfos.size(); i<N; i++) {
1539                            ProcessMemInfo mi = memInfos.get(i);
1540                            infoMap.put(mi.pid, mi);
1541                        }
1542                        updateCpuStatsNow();
1543                        synchronized (mProcessCpuThread) {
1544                            final int N = mProcessCpuTracker.countStats();
1545                            for (int i=0; i<N; i++) {
1546                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1547                                if (st.vsize > 0) {
1548                                    long pss = Debug.getPss(st.pid, null);
1549                                    if (pss > 0) {
1550                                        if (infoMap.indexOfKey(st.pid) < 0) {
1551                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1552                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1553                                            mi.pss = pss;
1554                                            memInfos.add(mi);
1555                                        }
1556                                    }
1557                                }
1558                            }
1559                        }
1560
1561                        long totalPss = 0;
1562                        for (int i=0, N=memInfos.size(); i<N; i++) {
1563                            ProcessMemInfo mi = memInfos.get(i);
1564                            if (mi.pss == 0) {
1565                                mi.pss = Debug.getPss(mi.pid, null);
1566                            }
1567                            totalPss += mi.pss;
1568                        }
1569                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1570                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1571                                if (lhs.oomAdj != rhs.oomAdj) {
1572                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1573                                }
1574                                if (lhs.pss != rhs.pss) {
1575                                    return lhs.pss < rhs.pss ? 1 : -1;
1576                                }
1577                                return 0;
1578                            }
1579                        });
1580
1581                        StringBuilder tag = new StringBuilder(128);
1582                        StringBuilder stack = new StringBuilder(128);
1583                        tag.append("Low on memory -- ");
1584                        appendMemBucket(tag, totalPss, "total", false);
1585                        appendMemBucket(stack, totalPss, "total", true);
1586
1587                        StringBuilder logBuilder = new StringBuilder(1024);
1588                        logBuilder.append("Low on memory:\n");
1589
1590                        boolean firstLine = true;
1591                        int lastOomAdj = Integer.MIN_VALUE;
1592                        for (int i=0, N=memInfos.size(); i<N; i++) {
1593                            ProcessMemInfo mi = memInfos.get(i);
1594
1595                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1596                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1597                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1598                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1599                                if (lastOomAdj != mi.oomAdj) {
1600                                    lastOomAdj = mi.oomAdj;
1601                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1602                                        tag.append(" / ");
1603                                    }
1604                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1605                                        if (firstLine) {
1606                                            stack.append(":");
1607                                            firstLine = false;
1608                                        }
1609                                        stack.append("\n\t at ");
1610                                    } else {
1611                                        stack.append("$");
1612                                    }
1613                                } else {
1614                                    tag.append(" ");
1615                                    stack.append("$");
1616                                }
1617                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1618                                    appendMemBucket(tag, mi.pss, mi.name, false);
1619                                }
1620                                appendMemBucket(stack, mi.pss, mi.name, true);
1621                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1622                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1623                                    stack.append("(");
1624                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1625                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1626                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1627                                            stack.append(":");
1628                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1629                                        }
1630                                    }
1631                                    stack.append(")");
1632                                }
1633                            }
1634
1635                            logBuilder.append("  ");
1636                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1637                            logBuilder.append(' ');
1638                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1639                            logBuilder.append(' ');
1640                            ProcessList.appendRamKb(logBuilder, mi.pss);
1641                            logBuilder.append(" kB: ");
1642                            logBuilder.append(mi.name);
1643                            logBuilder.append(" (");
1644                            logBuilder.append(mi.pid);
1645                            logBuilder.append(") ");
1646                            logBuilder.append(mi.adjType);
1647                            logBuilder.append('\n');
1648                            if (mi.adjReason != null) {
1649                                logBuilder.append("                      ");
1650                                logBuilder.append(mi.adjReason);
1651                                logBuilder.append('\n');
1652                            }
1653                        }
1654
1655                        logBuilder.append("           ");
1656                        ProcessList.appendRamKb(logBuilder, totalPss);
1657                        logBuilder.append(" kB: TOTAL\n");
1658
1659                        long[] infos = new long[Debug.MEMINFO_COUNT];
1660                        Debug.getMemInfo(infos);
1661                        logBuilder.append("  MemInfo: ");
1662                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1663                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1664                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1665                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1666                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1667                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1668                            logBuilder.append("  ZRAM: ");
1669                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1670                            logBuilder.append(" kB RAM, ");
1671                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1672                            logBuilder.append(" kB swap total, ");
1673                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1674                            logBuilder.append(" kB swap free\n");
1675                        }
1676                        Slog.i(TAG, logBuilder.toString());
1677
1678                        StringBuilder dropBuilder = new StringBuilder(1024);
1679                        /*
1680                        StringWriter oomSw = new StringWriter();
1681                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1682                        StringWriter catSw = new StringWriter();
1683                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1684                        String[] emptyArgs = new String[] { };
1685                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1686                        oomPw.flush();
1687                        String oomString = oomSw.toString();
1688                        */
1689                        dropBuilder.append(stack);
1690                        dropBuilder.append('\n');
1691                        dropBuilder.append('\n');
1692                        dropBuilder.append(logBuilder);
1693                        dropBuilder.append('\n');
1694                        /*
1695                        dropBuilder.append(oomString);
1696                        dropBuilder.append('\n');
1697                        */
1698                        StringWriter catSw = new StringWriter();
1699                        synchronized (ActivityManagerService.this) {
1700                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1701                            String[] emptyArgs = new String[] { };
1702                            catPw.println();
1703                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1704                            catPw.println();
1705                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1706                                    false, false, null);
1707                            catPw.println();
1708                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1709                            catPw.flush();
1710                        }
1711                        dropBuilder.append(catSw.toString());
1712                        addErrorToDropBox("lowmem", null, "system_server", null,
1713                                null, tag.toString(), dropBuilder.toString(), null, null);
1714                        //Slog.i(TAG, "Sent to dropbox:");
1715                        //Slog.i(TAG, dropBuilder.toString());
1716                        synchronized (ActivityManagerService.this) {
1717                            long now = SystemClock.uptimeMillis();
1718                            if (mLastMemUsageReportTime < now) {
1719                                mLastMemUsageReportTime = now;
1720                            }
1721                        }
1722                    }
1723                };
1724                thread.start();
1725                break;
1726            }
1727            case REPORT_USER_SWITCH_MSG: {
1728                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1729                break;
1730            }
1731            case CONTINUE_USER_SWITCH_MSG: {
1732                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1733                break;
1734            }
1735            case USER_SWITCH_TIMEOUT_MSG: {
1736                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1737                break;
1738            }
1739            case IMMERSIVE_MODE_LOCK_MSG: {
1740                final boolean nextState = (msg.arg1 != 0);
1741                if (mUpdateLock.isHeld() != nextState) {
1742                    if (DEBUG_IMMERSIVE) {
1743                        final ActivityRecord r = (ActivityRecord) msg.obj;
1744                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1745                    }
1746                    if (nextState) {
1747                        mUpdateLock.acquire();
1748                    } else {
1749                        mUpdateLock.release();
1750                    }
1751                }
1752                break;
1753            }
1754            case PERSIST_URI_GRANTS_MSG: {
1755                writeGrantedUriPermissions();
1756                break;
1757            }
1758            case REQUEST_ALL_PSS_MSG: {
1759                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1760                break;
1761            }
1762            case START_PROFILES_MSG: {
1763                synchronized (ActivityManagerService.this) {
1764                    startProfilesLocked();
1765                }
1766                break;
1767            }
1768            case UPDATE_TIME: {
1769                synchronized (ActivityManagerService.this) {
1770                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1771                        ProcessRecord r = mLruProcesses.get(i);
1772                        if (r.thread != null) {
1773                            try {
1774                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1775                            } catch (RemoteException ex) {
1776                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1777                            }
1778                        }
1779                    }
1780                }
1781                break;
1782            }
1783            case SYSTEM_USER_START_MSG: {
1784                mSystemServiceManager.startUser(msg.arg1);
1785                break;
1786            }
1787            case SYSTEM_USER_CURRENT_MSG: {
1788                mSystemServiceManager.switchUser(msg.arg1);
1789                break;
1790            }
1791            }
1792        }
1793    };
1794
1795    static final int COLLECT_PSS_BG_MSG = 1;
1796
1797    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1798        @Override
1799        public void handleMessage(Message msg) {
1800            switch (msg.what) {
1801            case COLLECT_PSS_BG_MSG: {
1802                int i=0, num=0;
1803                long start = SystemClock.uptimeMillis();
1804                long[] tmp = new long[1];
1805                do {
1806                    ProcessRecord proc;
1807                    int procState;
1808                    int pid;
1809                    synchronized (ActivityManagerService.this) {
1810                        if (i >= mPendingPssProcesses.size()) {
1811                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1812                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1813                            mPendingPssProcesses.clear();
1814                            return;
1815                        }
1816                        proc = mPendingPssProcesses.get(i);
1817                        procState = proc.pssProcState;
1818                        if (proc.thread != null && procState == proc.setProcState) {
1819                            pid = proc.pid;
1820                        } else {
1821                            proc = null;
1822                            pid = 0;
1823                        }
1824                        i++;
1825                    }
1826                    if (proc != null) {
1827                        long pss = Debug.getPss(pid, tmp);
1828                        synchronized (ActivityManagerService.this) {
1829                            if (proc.thread != null && proc.setProcState == procState
1830                                    && proc.pid == pid) {
1831                                num++;
1832                                proc.lastPssTime = SystemClock.uptimeMillis();
1833                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1834                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1835                                        + ": " + pss + " lastPss=" + proc.lastPss
1836                                        + " state=" + ProcessList.makeProcStateString(procState));
1837                                if (proc.initialIdlePss == 0) {
1838                                    proc.initialIdlePss = pss;
1839                                }
1840                                proc.lastPss = pss;
1841                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1842                                    proc.lastCachedPss = pss;
1843                                }
1844                            }
1845                        }
1846                    }
1847                } while (true);
1848            }
1849            }
1850        }
1851    };
1852
1853    /**
1854     * Monitor for package changes and update our internal state.
1855     */
1856    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1857        @Override
1858        public void onPackageRemoved(String packageName, int uid) {
1859            // Remove all tasks with activities in the specified package from the list of recent tasks
1860            synchronized (ActivityManagerService.this) {
1861                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1862                    TaskRecord tr = mRecentTasks.get(i);
1863                    ComponentName cn = tr.intent.getComponent();
1864                    if (cn != null && cn.getPackageName().equals(packageName)) {
1865                        // If the package name matches, remove the task and kill the process
1866                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1867                    }
1868                }
1869            }
1870        }
1871
1872        @Override
1873        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1874            onPackageModified(packageName);
1875            return true;
1876        }
1877
1878        @Override
1879        public void onPackageModified(String packageName) {
1880            final PackageManager pm = mContext.getPackageManager();
1881            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1882                    new ArrayList<Pair<Intent, Integer>>();
1883            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1884            // Copy the list of recent tasks so that we don't hold onto the lock on
1885            // ActivityManagerService for long periods while checking if components exist.
1886            synchronized (ActivityManagerService.this) {
1887                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1888                    TaskRecord tr = mRecentTasks.get(i);
1889                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1890                }
1891            }
1892            // Check the recent tasks and filter out all tasks with components that no longer exist.
1893            Intent tmpI = new Intent();
1894            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1895                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1896                ComponentName cn = p.first.getComponent();
1897                if (cn != null && cn.getPackageName().equals(packageName)) {
1898                    try {
1899                        // Add the task to the list to remove if the component no longer exists
1900                        tmpI.setComponent(cn);
1901                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1902                            tasksToRemove.add(p.second);
1903                        }
1904                    } catch (Exception e) {}
1905                }
1906            }
1907            // Prune all the tasks with removed components from the list of recent tasks
1908            synchronized (ActivityManagerService.this) {
1909                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1910                    // Remove the task but don't kill the process (since other components in that
1911                    // package may still be running and in the background)
1912                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1913                }
1914            }
1915        }
1916
1917        @Override
1918        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1919            // Force stop the specified packages
1920            if (packages != null) {
1921                for (String pkg : packages) {
1922                    synchronized (ActivityManagerService.this) {
1923                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
1924                                "finished booting")) {
1925                            return true;
1926                        }
1927                    }
1928                }
1929            }
1930            return false;
1931        }
1932    };
1933
1934    public void setSystemProcess() {
1935        try {
1936            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1937            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1938            ServiceManager.addService("meminfo", new MemBinder(this));
1939            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1940            ServiceManager.addService("dbinfo", new DbBinder(this));
1941            if (MONITOR_CPU_USAGE) {
1942                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1943            }
1944            ServiceManager.addService("permission", new PermissionController(this));
1945
1946            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1947                    "android", STOCK_PM_FLAGS);
1948            mSystemThread.installSystemApplicationInfo(info);
1949
1950            synchronized (this) {
1951                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
1952                app.persistent = true;
1953                app.pid = MY_PID;
1954                app.maxAdj = ProcessList.SYSTEM_ADJ;
1955                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1956                mProcessNames.put(app.processName, app.uid, app);
1957                synchronized (mPidsSelfLocked) {
1958                    mPidsSelfLocked.put(app.pid, app);
1959                }
1960                updateLruProcessLocked(app, false, null);
1961                updateOomAdjLocked();
1962            }
1963        } catch (PackageManager.NameNotFoundException e) {
1964            throw new RuntimeException(
1965                    "Unable to find android system package", e);
1966        }
1967    }
1968
1969    public void setWindowManager(WindowManagerService wm) {
1970        mWindowManager = wm;
1971        mStackSupervisor.setWindowManager(wm);
1972    }
1973
1974    public void startObservingNativeCrashes() {
1975        final NativeCrashListener ncl = new NativeCrashListener(this);
1976        ncl.start();
1977    }
1978
1979    public IAppOpsService getAppOpsService() {
1980        return mAppOpsService;
1981    }
1982
1983    static class MemBinder extends Binder {
1984        ActivityManagerService mActivityManagerService;
1985        MemBinder(ActivityManagerService activityManagerService) {
1986            mActivityManagerService = activityManagerService;
1987        }
1988
1989        @Override
1990        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1991            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1992                    != PackageManager.PERMISSION_GRANTED) {
1993                pw.println("Permission Denial: can't dump meminfo from from pid="
1994                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1995                        + " without permission " + android.Manifest.permission.DUMP);
1996                return;
1997            }
1998
1999            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2000        }
2001    }
2002
2003    static class GraphicsBinder extends Binder {
2004        ActivityManagerService mActivityManagerService;
2005        GraphicsBinder(ActivityManagerService activityManagerService) {
2006            mActivityManagerService = activityManagerService;
2007        }
2008
2009        @Override
2010        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2011            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2012                    != PackageManager.PERMISSION_GRANTED) {
2013                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2014                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2015                        + " without permission " + android.Manifest.permission.DUMP);
2016                return;
2017            }
2018
2019            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2020        }
2021    }
2022
2023    static class DbBinder extends Binder {
2024        ActivityManagerService mActivityManagerService;
2025        DbBinder(ActivityManagerService activityManagerService) {
2026            mActivityManagerService = activityManagerService;
2027        }
2028
2029        @Override
2030        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2031            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2032                    != PackageManager.PERMISSION_GRANTED) {
2033                pw.println("Permission Denial: can't dump dbinfo from from pid="
2034                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2035                        + " without permission " + android.Manifest.permission.DUMP);
2036                return;
2037            }
2038
2039            mActivityManagerService.dumpDbInfo(fd, pw, args);
2040        }
2041    }
2042
2043    static class CpuBinder extends Binder {
2044        ActivityManagerService mActivityManagerService;
2045        CpuBinder(ActivityManagerService activityManagerService) {
2046            mActivityManagerService = activityManagerService;
2047        }
2048
2049        @Override
2050        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2051            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2052                    != PackageManager.PERMISSION_GRANTED) {
2053                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2054                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2055                        + " without permission " + android.Manifest.permission.DUMP);
2056                return;
2057            }
2058
2059            synchronized (mActivityManagerService.mProcessCpuThread) {
2060                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2061                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2062                        SystemClock.uptimeMillis()));
2063            }
2064        }
2065    }
2066
2067    public static final class Lifecycle extends SystemService {
2068        private final ActivityManagerService mService;
2069
2070        public Lifecycle(Context context) {
2071            super(context);
2072            mService = new ActivityManagerService(context);
2073        }
2074
2075        @Override
2076        public void onStart() {
2077            mService.start();
2078        }
2079
2080        public ActivityManagerService getService() {
2081            return mService;
2082        }
2083    }
2084
2085    // Note: This method is invoked on the main thread but may need to attach various
2086    // handlers to other threads.  So take care to be explicit about the looper.
2087    public ActivityManagerService(Context systemContext) {
2088        mContext = systemContext;
2089        mFactoryTest = FactoryTest.getMode();
2090        mSystemThread = ActivityThread.currentActivityThread();
2091
2092        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2093
2094        mHandlerThread = new ServiceThread(TAG,
2095                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2096        mHandlerThread.start();
2097        mHandler = new MainHandler(mHandlerThread.getLooper());
2098
2099        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2100                "foreground", BROADCAST_FG_TIMEOUT, false);
2101        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2102                "background", BROADCAST_BG_TIMEOUT, true);
2103        mBroadcastQueues[0] = mFgBroadcastQueue;
2104        mBroadcastQueues[1] = mBgBroadcastQueue;
2105
2106        mServices = new ActiveServices(this);
2107        mProviderMap = new ProviderMap(this);
2108
2109        // TODO: Move creation of battery stats service outside of activity manager service.
2110        File dataDir = Environment.getDataDirectory();
2111        File systemDir = new File(dataDir, "system");
2112        systemDir.mkdirs();
2113        mBatteryStatsService = new BatteryStatsService(new File(
2114                systemDir, "batterystats.bin").toString(), mHandler);
2115        mBatteryStatsService.getActiveStatistics().readLocked();
2116        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2117        mOnBattery = DEBUG_POWER ? true
2118                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2119        mBatteryStatsService.getActiveStatistics().setCallback(this);
2120
2121        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2122
2123        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
2124        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2125
2126        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2127
2128        // User 0 is the first and only user that runs at boot.
2129        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2130        mUserLru.add(Integer.valueOf(0));
2131        updateStartedUserArrayLocked();
2132
2133        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2134            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2135
2136        mConfiguration.setToDefaults();
2137        mConfiguration.setLocale(Locale.getDefault());
2138
2139        mConfigurationSeq = mConfiguration.seq = 1;
2140        mProcessCpuTracker.init();
2141
2142        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2143        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2144        mStackSupervisor = new ActivityStackSupervisor(this);
2145        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2146
2147        mProcessCpuThread = new Thread("CpuTracker") {
2148            @Override
2149            public void run() {
2150                while (true) {
2151                    try {
2152                        try {
2153                            synchronized(this) {
2154                                final long now = SystemClock.uptimeMillis();
2155                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2156                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2157                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2158                                //        + ", write delay=" + nextWriteDelay);
2159                                if (nextWriteDelay < nextCpuDelay) {
2160                                    nextCpuDelay = nextWriteDelay;
2161                                }
2162                                if (nextCpuDelay > 0) {
2163                                    mProcessCpuMutexFree.set(true);
2164                                    this.wait(nextCpuDelay);
2165                                }
2166                            }
2167                        } catch (InterruptedException e) {
2168                        }
2169                        updateCpuStatsNow();
2170                    } catch (Exception e) {
2171                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2172                    }
2173                }
2174            }
2175        };
2176
2177        Watchdog.getInstance().addMonitor(this);
2178        Watchdog.getInstance().addThread(mHandler);
2179    }
2180
2181    public void setSystemServiceManager(SystemServiceManager mgr) {
2182        mSystemServiceManager = mgr;
2183    }
2184
2185    private void start() {
2186        mProcessCpuThread.start();
2187
2188        mBatteryStatsService.publish(mContext);
2189        mUsageStatsService.publish(mContext);
2190        mAppOpsService.publish(mContext);
2191
2192        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2193    }
2194
2195    @Override
2196    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2197            throws RemoteException {
2198        if (code == SYSPROPS_TRANSACTION) {
2199            // We need to tell all apps about the system property change.
2200            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2201            synchronized(this) {
2202                final int NP = mProcessNames.getMap().size();
2203                for (int ip=0; ip<NP; ip++) {
2204                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2205                    final int NA = apps.size();
2206                    for (int ia=0; ia<NA; ia++) {
2207                        ProcessRecord app = apps.valueAt(ia);
2208                        if (app.thread != null) {
2209                            procs.add(app.thread.asBinder());
2210                        }
2211                    }
2212                }
2213            }
2214
2215            int N = procs.size();
2216            for (int i=0; i<N; i++) {
2217                Parcel data2 = Parcel.obtain();
2218                try {
2219                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2220                } catch (RemoteException e) {
2221                }
2222                data2.recycle();
2223            }
2224        }
2225        try {
2226            return super.onTransact(code, data, reply, flags);
2227        } catch (RuntimeException e) {
2228            // The activity manager only throws security exceptions, so let's
2229            // log all others.
2230            if (!(e instanceof SecurityException)) {
2231                Slog.wtf(TAG, "Activity Manager Crash", e);
2232            }
2233            throw e;
2234        }
2235    }
2236
2237    void updateCpuStats() {
2238        final long now = SystemClock.uptimeMillis();
2239        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2240            return;
2241        }
2242        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2243            synchronized (mProcessCpuThread) {
2244                mProcessCpuThread.notify();
2245            }
2246        }
2247    }
2248
2249    void updateCpuStatsNow() {
2250        synchronized (mProcessCpuThread) {
2251            mProcessCpuMutexFree.set(false);
2252            final long now = SystemClock.uptimeMillis();
2253            boolean haveNewCpuStats = false;
2254
2255            if (MONITOR_CPU_USAGE &&
2256                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2257                mLastCpuTime.set(now);
2258                haveNewCpuStats = true;
2259                mProcessCpuTracker.update();
2260                //Slog.i(TAG, mProcessCpu.printCurrentState());
2261                //Slog.i(TAG, "Total CPU usage: "
2262                //        + mProcessCpu.getTotalCpuPercent() + "%");
2263
2264                // Slog the cpu usage if the property is set.
2265                if ("true".equals(SystemProperties.get("events.cpu"))) {
2266                    int user = mProcessCpuTracker.getLastUserTime();
2267                    int system = mProcessCpuTracker.getLastSystemTime();
2268                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2269                    int irq = mProcessCpuTracker.getLastIrqTime();
2270                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2271                    int idle = mProcessCpuTracker.getLastIdleTime();
2272
2273                    int total = user + system + iowait + irq + softIrq + idle;
2274                    if (total == 0) total = 1;
2275
2276                    EventLog.writeEvent(EventLogTags.CPU,
2277                            ((user+system+iowait+irq+softIrq) * 100) / total,
2278                            (user * 100) / total,
2279                            (system * 100) / total,
2280                            (iowait * 100) / total,
2281                            (irq * 100) / total,
2282                            (softIrq * 100) / total);
2283                }
2284            }
2285
2286            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2287            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2288            synchronized(bstats) {
2289                synchronized(mPidsSelfLocked) {
2290                    if (haveNewCpuStats) {
2291                        if (mOnBattery) {
2292                            int perc = bstats.startAddingCpuLocked();
2293                            int totalUTime = 0;
2294                            int totalSTime = 0;
2295                            final int N = mProcessCpuTracker.countStats();
2296                            for (int i=0; i<N; i++) {
2297                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2298                                if (!st.working) {
2299                                    continue;
2300                                }
2301                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2302                                int otherUTime = (st.rel_utime*perc)/100;
2303                                int otherSTime = (st.rel_stime*perc)/100;
2304                                totalUTime += otherUTime;
2305                                totalSTime += otherSTime;
2306                                if (pr != null) {
2307                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2308                                    if (ps == null || !ps.isActive()) {
2309                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2310                                                pr.info.uid, pr.processName);
2311                                    }
2312                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2313                                            st.rel_stime-otherSTime);
2314                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2315                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2316                                } else {
2317                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2318                                    if (ps == null || !ps.isActive()) {
2319                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2320                                                bstats.mapUid(st.uid), st.name);
2321                                    }
2322                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2323                                            st.rel_stime-otherSTime);
2324                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2325                                }
2326                            }
2327                            bstats.finishAddingCpuLocked(perc, totalUTime,
2328                                    totalSTime, cpuSpeedTimes);
2329                        }
2330                    }
2331                }
2332
2333                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2334                    mLastWriteTime = now;
2335                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2336                }
2337            }
2338        }
2339    }
2340
2341    @Override
2342    public void batteryNeedsCpuUpdate() {
2343        updateCpuStatsNow();
2344    }
2345
2346    @Override
2347    public void batteryPowerChanged(boolean onBattery) {
2348        // When plugging in, update the CPU stats first before changing
2349        // the plug state.
2350        updateCpuStatsNow();
2351        synchronized (this) {
2352            synchronized(mPidsSelfLocked) {
2353                mOnBattery = DEBUG_POWER ? true : onBattery;
2354            }
2355        }
2356    }
2357
2358    /**
2359     * Initialize the application bind args. These are passed to each
2360     * process when the bindApplication() IPC is sent to the process. They're
2361     * lazily setup to make sure the services are running when they're asked for.
2362     */
2363    private HashMap<String, IBinder> getCommonServicesLocked() {
2364        if (mAppBindArgs == null) {
2365            mAppBindArgs = new HashMap<String, IBinder>();
2366
2367            // Setup the application init args
2368            mAppBindArgs.put("package", ServiceManager.getService("package"));
2369            mAppBindArgs.put("window", ServiceManager.getService("window"));
2370            mAppBindArgs.put(Context.ALARM_SERVICE,
2371                    ServiceManager.getService(Context.ALARM_SERVICE));
2372        }
2373        return mAppBindArgs;
2374    }
2375
2376    final void setFocusedActivityLocked(ActivityRecord r) {
2377        if (mFocusedActivity != r) {
2378            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2379            mFocusedActivity = r;
2380            if (r.task != null && r.task.voiceInteractor != null) {
2381                startRunningVoiceLocked();
2382            } else {
2383                finishRunningVoiceLocked();
2384            }
2385            mStackSupervisor.setFocusedStack(r);
2386            if (r != null) {
2387                mWindowManager.setFocusedApp(r.appToken, true);
2388            }
2389            applyUpdateLockStateLocked(r);
2390        }
2391    }
2392
2393    final void clearFocusedActivity(ActivityRecord r) {
2394        if (mFocusedActivity == r) {
2395            mFocusedActivity = null;
2396        }
2397    }
2398
2399    @Override
2400    public void setFocusedStack(int stackId) {
2401        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2402        synchronized (ActivityManagerService.this) {
2403            ActivityStack stack = mStackSupervisor.getStack(stackId);
2404            if (stack != null) {
2405                ActivityRecord r = stack.topRunningActivityLocked(null);
2406                if (r != null) {
2407                    setFocusedActivityLocked(r);
2408                }
2409            }
2410        }
2411    }
2412
2413    @Override
2414    public void notifyActivityDrawn(IBinder token) {
2415        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2416        synchronized (this) {
2417            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2418            if (r != null) {
2419                r.task.stack.notifyActivityDrawnLocked(r);
2420            }
2421        }
2422    }
2423
2424    final void applyUpdateLockStateLocked(ActivityRecord r) {
2425        // Modifications to the UpdateLock state are done on our handler, outside
2426        // the activity manager's locks.  The new state is determined based on the
2427        // state *now* of the relevant activity record.  The object is passed to
2428        // the handler solely for logging detail, not to be consulted/modified.
2429        final boolean nextState = r != null && r.immersive;
2430        mHandler.sendMessage(
2431                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2432    }
2433
2434    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2435        Message msg = Message.obtain();
2436        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2437        msg.obj = r.task.askedCompatMode ? null : r;
2438        mHandler.sendMessage(msg);
2439    }
2440
2441    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2442            String what, Object obj, ProcessRecord srcApp) {
2443        app.lastActivityTime = now;
2444
2445        if (app.activities.size() > 0) {
2446            // Don't want to touch dependent processes that are hosting activities.
2447            return index;
2448        }
2449
2450        int lrui = mLruProcesses.lastIndexOf(app);
2451        if (lrui < 0) {
2452            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2453                    + what + " " + obj + " from " + srcApp);
2454            return index;
2455        }
2456
2457        if (lrui >= index) {
2458            // Don't want to cause this to move dependent processes *back* in the
2459            // list as if they were less frequently used.
2460            return index;
2461        }
2462
2463        if (lrui >= mLruProcessActivityStart) {
2464            // Don't want to touch dependent processes that are hosting activities.
2465            return index;
2466        }
2467
2468        mLruProcesses.remove(lrui);
2469        if (index > 0) {
2470            index--;
2471        }
2472        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2473                + " in LRU list: " + app);
2474        mLruProcesses.add(index, app);
2475        return index;
2476    }
2477
2478    final void removeLruProcessLocked(ProcessRecord app) {
2479        int lrui = mLruProcesses.lastIndexOf(app);
2480        if (lrui >= 0) {
2481            if (lrui <= mLruProcessActivityStart) {
2482                mLruProcessActivityStart--;
2483            }
2484            if (lrui <= mLruProcessServiceStart) {
2485                mLruProcessServiceStart--;
2486            }
2487            mLruProcesses.remove(lrui);
2488        }
2489    }
2490
2491    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2492            ProcessRecord client) {
2493        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2494                || app.treatLikeActivity;
2495        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2496        if (!activityChange && hasActivity) {
2497            // The process has activities, so we are only allowing activity-based adjustments
2498            // to move it.  It should be kept in the front of the list with other
2499            // processes that have activities, and we don't want those to change their
2500            // order except due to activity operations.
2501            return;
2502        }
2503
2504        mLruSeq++;
2505        final long now = SystemClock.uptimeMillis();
2506        app.lastActivityTime = now;
2507
2508        // First a quick reject: if the app is already at the position we will
2509        // put it, then there is nothing to do.
2510        if (hasActivity) {
2511            final int N = mLruProcesses.size();
2512            if (N > 0 && mLruProcesses.get(N-1) == app) {
2513                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2514                return;
2515            }
2516        } else {
2517            if (mLruProcessServiceStart > 0
2518                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2519                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2520                return;
2521            }
2522        }
2523
2524        int lrui = mLruProcesses.lastIndexOf(app);
2525
2526        if (app.persistent && lrui >= 0) {
2527            // We don't care about the position of persistent processes, as long as
2528            // they are in the list.
2529            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2530            return;
2531        }
2532
2533        /* In progress: compute new position first, so we can avoid doing work
2534           if the process is not actually going to move.  Not yet working.
2535        int addIndex;
2536        int nextIndex;
2537        boolean inActivity = false, inService = false;
2538        if (hasActivity) {
2539            // Process has activities, put it at the very tipsy-top.
2540            addIndex = mLruProcesses.size();
2541            nextIndex = mLruProcessServiceStart;
2542            inActivity = true;
2543        } else if (hasService) {
2544            // Process has services, put it at the top of the service list.
2545            addIndex = mLruProcessActivityStart;
2546            nextIndex = mLruProcessServiceStart;
2547            inActivity = true;
2548            inService = true;
2549        } else  {
2550            // Process not otherwise of interest, it goes to the top of the non-service area.
2551            addIndex = mLruProcessServiceStart;
2552            if (client != null) {
2553                int clientIndex = mLruProcesses.lastIndexOf(client);
2554                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2555                        + app);
2556                if (clientIndex >= 0 && addIndex > clientIndex) {
2557                    addIndex = clientIndex;
2558                }
2559            }
2560            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2561        }
2562
2563        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2564                + mLruProcessActivityStart + "): " + app);
2565        */
2566
2567        if (lrui >= 0) {
2568            if (lrui < mLruProcessActivityStart) {
2569                mLruProcessActivityStart--;
2570            }
2571            if (lrui < mLruProcessServiceStart) {
2572                mLruProcessServiceStart--;
2573            }
2574            /*
2575            if (addIndex > lrui) {
2576                addIndex--;
2577            }
2578            if (nextIndex > lrui) {
2579                nextIndex--;
2580            }
2581            */
2582            mLruProcesses.remove(lrui);
2583        }
2584
2585        /*
2586        mLruProcesses.add(addIndex, app);
2587        if (inActivity) {
2588            mLruProcessActivityStart++;
2589        }
2590        if (inService) {
2591            mLruProcessActivityStart++;
2592        }
2593        */
2594
2595        int nextIndex;
2596        if (hasActivity) {
2597            final int N = mLruProcesses.size();
2598            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2599                // Process doesn't have activities, but has clients with
2600                // activities...  move it up, but one below the top (the top
2601                // should always have a real activity).
2602                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2603                mLruProcesses.add(N-1, app);
2604                // To keep it from spamming the LRU list (by making a bunch of clients),
2605                // we will push down any other entries owned by the app.
2606                final int uid = app.info.uid;
2607                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2608                    ProcessRecord subProc = mLruProcesses.get(i);
2609                    if (subProc.info.uid == uid) {
2610                        // We want to push this one down the list.  If the process after
2611                        // it is for the same uid, however, don't do so, because we don't
2612                        // want them internally to be re-ordered.
2613                        if (mLruProcesses.get(i-1).info.uid != uid) {
2614                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2615                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2616                            ProcessRecord tmp = mLruProcesses.get(i);
2617                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2618                            mLruProcesses.set(i-1, tmp);
2619                            i--;
2620                        }
2621                    } else {
2622                        // A gap, we can stop here.
2623                        break;
2624                    }
2625                }
2626            } else {
2627                // Process has activities, put it at the very tipsy-top.
2628                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2629                mLruProcesses.add(app);
2630            }
2631            nextIndex = mLruProcessServiceStart;
2632        } else if (hasService) {
2633            // Process has services, put it at the top of the service list.
2634            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2635            mLruProcesses.add(mLruProcessActivityStart, app);
2636            nextIndex = mLruProcessServiceStart;
2637            mLruProcessActivityStart++;
2638        } else  {
2639            // Process not otherwise of interest, it goes to the top of the non-service area.
2640            int index = mLruProcessServiceStart;
2641            if (client != null) {
2642                // If there is a client, don't allow the process to be moved up higher
2643                // in the list than that client.
2644                int clientIndex = mLruProcesses.lastIndexOf(client);
2645                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2646                        + " when updating " + app);
2647                if (clientIndex <= lrui) {
2648                    // Don't allow the client index restriction to push it down farther in the
2649                    // list than it already is.
2650                    clientIndex = lrui;
2651                }
2652                if (clientIndex >= 0 && index > clientIndex) {
2653                    index = clientIndex;
2654                }
2655            }
2656            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2657            mLruProcesses.add(index, app);
2658            nextIndex = index-1;
2659            mLruProcessActivityStart++;
2660            mLruProcessServiceStart++;
2661        }
2662
2663        // If the app is currently using a content provider or service,
2664        // bump those processes as well.
2665        for (int j=app.connections.size()-1; j>=0; j--) {
2666            ConnectionRecord cr = app.connections.valueAt(j);
2667            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2668                    && cr.binding.service.app != null
2669                    && cr.binding.service.app.lruSeq != mLruSeq
2670                    && !cr.binding.service.app.persistent) {
2671                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2672                        "service connection", cr, app);
2673            }
2674        }
2675        for (int j=app.conProviders.size()-1; j>=0; j--) {
2676            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2677            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2678                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2679                        "provider reference", cpr, app);
2680            }
2681        }
2682    }
2683
2684    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2685        if (uid == Process.SYSTEM_UID) {
2686            // The system gets to run in any process.  If there are multiple
2687            // processes with the same uid, just pick the first (this
2688            // should never happen).
2689            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2690            if (procs == null) return null;
2691            final int N = procs.size();
2692            for (int i = 0; i < N; i++) {
2693                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2694            }
2695        }
2696        ProcessRecord proc = mProcessNames.get(processName, uid);
2697        if (false && proc != null && !keepIfLarge
2698                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2699                && proc.lastCachedPss >= 4000) {
2700            // Turn this condition on to cause killing to happen regularly, for testing.
2701            if (proc.baseProcessTracker != null) {
2702                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2703            }
2704            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2705                    + "k from cached");
2706        } else if (proc != null && !keepIfLarge
2707                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2708                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2709            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2710            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2711                if (proc.baseProcessTracker != null) {
2712                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2713                }
2714                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2715                        + "k from cached");
2716            }
2717        }
2718        return proc;
2719    }
2720
2721    void ensurePackageDexOpt(String packageName) {
2722        IPackageManager pm = AppGlobals.getPackageManager();
2723        try {
2724            if (pm.performDexOpt(packageName)) {
2725                mDidDexOpt = true;
2726            }
2727        } catch (RemoteException e) {
2728        }
2729    }
2730
2731    boolean isNextTransitionForward() {
2732        int transit = mWindowManager.getPendingAppTransition();
2733        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2734                || transit == AppTransition.TRANSIT_TASK_OPEN
2735                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2736    }
2737
2738    final ProcessRecord startProcessLocked(String processName,
2739            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2740            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2741            boolean isolated, boolean keepIfLarge) {
2742        ProcessRecord app;
2743        if (!isolated) {
2744            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2745        } else {
2746            // If this is an isolated process, it can't re-use an existing process.
2747            app = null;
2748        }
2749        // We don't have to do anything more if:
2750        // (1) There is an existing application record; and
2751        // (2) The caller doesn't think it is dead, OR there is no thread
2752        //     object attached to it so we know it couldn't have crashed; and
2753        // (3) There is a pid assigned to it, so it is either starting or
2754        //     already running.
2755        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2756                + " app=" + app + " knownToBeDead=" + knownToBeDead
2757                + " thread=" + (app != null ? app.thread : null)
2758                + " pid=" + (app != null ? app.pid : -1));
2759        if (app != null && app.pid > 0) {
2760            if (!knownToBeDead || app.thread == null) {
2761                // We already have the app running, or are waiting for it to
2762                // come up (we have a pid but not yet its thread), so keep it.
2763                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2764                // If this is a new package in the process, add the package to the list
2765                app.addPackage(info.packageName, mProcessStats);
2766                return app;
2767            }
2768
2769            // An application record is attached to a previous process,
2770            // clean it up now.
2771            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2772            handleAppDiedLocked(app, true, true);
2773        }
2774
2775        String hostingNameStr = hostingName != null
2776                ? hostingName.flattenToShortString() : null;
2777
2778        if (!isolated) {
2779            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2780                // If we are in the background, then check to see if this process
2781                // is bad.  If so, we will just silently fail.
2782                if (mBadProcesses.get(info.processName, info.uid) != null) {
2783                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2784                            + "/" + info.processName);
2785                    return null;
2786                }
2787            } else {
2788                // When the user is explicitly starting a process, then clear its
2789                // crash count so that we won't make it bad until they see at
2790                // least one crash dialog again, and make the process good again
2791                // if it had been bad.
2792                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2793                        + "/" + info.processName);
2794                mProcessCrashTimes.remove(info.processName, info.uid);
2795                if (mBadProcesses.get(info.processName, info.uid) != null) {
2796                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2797                            UserHandle.getUserId(info.uid), info.uid,
2798                            info.processName);
2799                    mBadProcesses.remove(info.processName, info.uid);
2800                    if (app != null) {
2801                        app.bad = false;
2802                    }
2803                }
2804            }
2805        }
2806
2807        if (app == null) {
2808            app = newProcessRecordLocked(info, processName, isolated);
2809            if (app == null) {
2810                Slog.w(TAG, "Failed making new process record for "
2811                        + processName + "/" + info.uid + " isolated=" + isolated);
2812                return null;
2813            }
2814            mProcessNames.put(processName, app.uid, app);
2815            if (isolated) {
2816                mIsolatedProcesses.put(app.uid, app);
2817            }
2818        } else {
2819            // If this is a new package in the process, add the package to the list
2820            app.addPackage(info.packageName, mProcessStats);
2821        }
2822
2823        // If the system is not ready yet, then hold off on starting this
2824        // process until it is.
2825        if (!mProcessesReady
2826                && !isAllowedWhileBooting(info)
2827                && !allowWhileBooting) {
2828            if (!mProcessesOnHold.contains(app)) {
2829                mProcessesOnHold.add(app);
2830            }
2831            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2832            return app;
2833        }
2834
2835        startProcessLocked(app, hostingType, hostingNameStr);
2836        return (app.pid != 0) ? app : null;
2837    }
2838
2839    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2840        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2841    }
2842
2843    private final void startProcessLocked(ProcessRecord app,
2844            String hostingType, String hostingNameStr) {
2845        if (app.pid > 0 && app.pid != MY_PID) {
2846            synchronized (mPidsSelfLocked) {
2847                mPidsSelfLocked.remove(app.pid);
2848                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2849            }
2850            app.setPid(0);
2851        }
2852
2853        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2854                "startProcessLocked removing on hold: " + app);
2855        mProcessesOnHold.remove(app);
2856
2857        updateCpuStats();
2858
2859        try {
2860            int uid = app.uid;
2861
2862            int[] gids = null;
2863            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2864            if (!app.isolated) {
2865                int[] permGids = null;
2866                try {
2867                    final PackageManager pm = mContext.getPackageManager();
2868                    permGids = pm.getPackageGids(app.info.packageName);
2869
2870                    if (Environment.isExternalStorageEmulated()) {
2871                        if (pm.checkPermission(
2872                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2873                                app.info.packageName) == PERMISSION_GRANTED) {
2874                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2875                        } else {
2876                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2877                        }
2878                    }
2879                } catch (PackageManager.NameNotFoundException e) {
2880                    Slog.w(TAG, "Unable to retrieve gids", e);
2881                }
2882
2883                /*
2884                 * Add shared application GID so applications can share some
2885                 * resources like shared libraries
2886                 */
2887                if (permGids == null) {
2888                    gids = new int[1];
2889                } else {
2890                    gids = new int[permGids.length + 1];
2891                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2892                }
2893                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2894            }
2895            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2896                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2897                        && mTopComponent != null
2898                        && app.processName.equals(mTopComponent.getPackageName())) {
2899                    uid = 0;
2900                }
2901                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2902                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2903                    uid = 0;
2904                }
2905            }
2906            int debugFlags = 0;
2907            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2908                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2909                // Also turn on CheckJNI for debuggable apps. It's quite
2910                // awkward to turn on otherwise.
2911                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2912            }
2913            // Run the app in safe mode if its manifest requests so or the
2914            // system is booted in safe mode.
2915            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2916                mSafeMode == true) {
2917                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2918            }
2919            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2920                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2921            }
2922            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2923                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2924            }
2925            if ("1".equals(SystemProperties.get("debug.assert"))) {
2926                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2927            }
2928
2929            String requiredAbi = app.info.cpuAbi;
2930            if (requiredAbi == null) {
2931                requiredAbi = Build.SUPPORTED_ABIS[0];
2932            }
2933
2934            // Start the process.  It will either succeed and return a result containing
2935            // the PID of the new process, or else throw a RuntimeException.
2936            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2937                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2938                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
2939
2940            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2941            synchronized (bs) {
2942                if (bs.isOnBattery()) {
2943                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2944                }
2945            }
2946
2947            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2948                    UserHandle.getUserId(uid), startResult.pid, uid,
2949                    app.processName, hostingType,
2950                    hostingNameStr != null ? hostingNameStr : "");
2951
2952            if (app.persistent) {
2953                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2954            }
2955
2956            StringBuilder buf = mStringBuilder;
2957            buf.setLength(0);
2958            buf.append("Start proc ");
2959            buf.append(app.processName);
2960            buf.append(" for ");
2961            buf.append(hostingType);
2962            if (hostingNameStr != null) {
2963                buf.append(" ");
2964                buf.append(hostingNameStr);
2965            }
2966            buf.append(": pid=");
2967            buf.append(startResult.pid);
2968            buf.append(" uid=");
2969            buf.append(uid);
2970            buf.append(" gids={");
2971            if (gids != null) {
2972                for (int gi=0; gi<gids.length; gi++) {
2973                    if (gi != 0) buf.append(", ");
2974                    buf.append(gids[gi]);
2975
2976                }
2977            }
2978            buf.append("}");
2979            Slog.i(TAG, buf.toString());
2980            app.setPid(startResult.pid);
2981            app.usingWrapper = startResult.usingWrapper;
2982            app.removed = false;
2983            synchronized (mPidsSelfLocked) {
2984                this.mPidsSelfLocked.put(startResult.pid, app);
2985                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2986                msg.obj = app;
2987                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2988                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2989            }
2990            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
2991                    app.processName, app.info.uid);
2992            if (app.isolated) {
2993                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2994            }
2995        } catch (RuntimeException e) {
2996            // XXX do better error recovery.
2997            app.setPid(0);
2998            Slog.e(TAG, "Failure starting process " + app.processName, e);
2999        }
3000    }
3001
3002    void updateUsageStats(ActivityRecord component, boolean resumed) {
3003        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3004        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3005        if (resumed) {
3006            mUsageStatsService.noteResumeComponent(component.realActivity);
3007            synchronized (stats) {
3008                stats.noteActivityResumedLocked(component.app.uid);
3009            }
3010        } else {
3011            mUsageStatsService.notePauseComponent(component.realActivity);
3012            synchronized (stats) {
3013                stats.noteActivityPausedLocked(component.app.uid);
3014            }
3015        }
3016    }
3017
3018    Intent getHomeIntent() {
3019        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3020        intent.setComponent(mTopComponent);
3021        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3022            intent.addCategory(Intent.CATEGORY_HOME);
3023        }
3024        return intent;
3025    }
3026
3027    boolean startHomeActivityLocked(int userId) {
3028        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3029                && mTopAction == null) {
3030            // We are running in factory test mode, but unable to find
3031            // the factory test app, so just sit around displaying the
3032            // error message and don't try to start anything.
3033            return false;
3034        }
3035        Intent intent = getHomeIntent();
3036        ActivityInfo aInfo =
3037            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3038        if (aInfo != null) {
3039            intent.setComponent(new ComponentName(
3040                    aInfo.applicationInfo.packageName, aInfo.name));
3041            // Don't do this if the home app is currently being
3042            // instrumented.
3043            aInfo = new ActivityInfo(aInfo);
3044            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3045            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3046                    aInfo.applicationInfo.uid, true);
3047            if (app == null || app.instrumentationClass == null) {
3048                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3049                mStackSupervisor.startHomeActivity(intent, aInfo);
3050            }
3051        }
3052
3053        return true;
3054    }
3055
3056    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3057        ActivityInfo ai = null;
3058        ComponentName comp = intent.getComponent();
3059        try {
3060            if (comp != null) {
3061                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3062            } else {
3063                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3064                        intent,
3065                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3066                            flags, userId);
3067
3068                if (info != null) {
3069                    ai = info.activityInfo;
3070                }
3071            }
3072        } catch (RemoteException e) {
3073            // ignore
3074        }
3075
3076        return ai;
3077    }
3078
3079    /**
3080     * Starts the "new version setup screen" if appropriate.
3081     */
3082    void startSetupActivityLocked() {
3083        // Only do this once per boot.
3084        if (mCheckedForSetup) {
3085            return;
3086        }
3087
3088        // We will show this screen if the current one is a different
3089        // version than the last one shown, and we are not running in
3090        // low-level factory test mode.
3091        final ContentResolver resolver = mContext.getContentResolver();
3092        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3093                Settings.Global.getInt(resolver,
3094                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3095            mCheckedForSetup = true;
3096
3097            // See if we should be showing the platform update setup UI.
3098            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3099            List<ResolveInfo> ris = mContext.getPackageManager()
3100                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3101
3102            // We don't allow third party apps to replace this.
3103            ResolveInfo ri = null;
3104            for (int i=0; ris != null && i<ris.size(); i++) {
3105                if ((ris.get(i).activityInfo.applicationInfo.flags
3106                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3107                    ri = ris.get(i);
3108                    break;
3109                }
3110            }
3111
3112            if (ri != null) {
3113                String vers = ri.activityInfo.metaData != null
3114                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3115                        : null;
3116                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3117                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3118                            Intent.METADATA_SETUP_VERSION);
3119                }
3120                String lastVers = Settings.Secure.getString(
3121                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3122                if (vers != null && !vers.equals(lastVers)) {
3123                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3124                    intent.setComponent(new ComponentName(
3125                            ri.activityInfo.packageName, ri.activityInfo.name));
3126                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3127                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3128                }
3129            }
3130        }
3131    }
3132
3133    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3134        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3135    }
3136
3137    void enforceNotIsolatedCaller(String caller) {
3138        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3139            throw new SecurityException("Isolated process not allowed to call " + caller);
3140        }
3141    }
3142
3143    @Override
3144    public int getFrontActivityScreenCompatMode() {
3145        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3146        synchronized (this) {
3147            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3148        }
3149    }
3150
3151    @Override
3152    public void setFrontActivityScreenCompatMode(int mode) {
3153        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3154                "setFrontActivityScreenCompatMode");
3155        synchronized (this) {
3156            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3157        }
3158    }
3159
3160    @Override
3161    public int getPackageScreenCompatMode(String packageName) {
3162        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3163        synchronized (this) {
3164            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3165        }
3166    }
3167
3168    @Override
3169    public void setPackageScreenCompatMode(String packageName, int mode) {
3170        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3171                "setPackageScreenCompatMode");
3172        synchronized (this) {
3173            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3174        }
3175    }
3176
3177    @Override
3178    public boolean getPackageAskScreenCompat(String packageName) {
3179        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3180        synchronized (this) {
3181            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3182        }
3183    }
3184
3185    @Override
3186    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3187        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3188                "setPackageAskScreenCompat");
3189        synchronized (this) {
3190            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3191        }
3192    }
3193
3194    private void dispatchProcessesChanged() {
3195        int N;
3196        synchronized (this) {
3197            N = mPendingProcessChanges.size();
3198            if (mActiveProcessChanges.length < N) {
3199                mActiveProcessChanges = new ProcessChangeItem[N];
3200            }
3201            mPendingProcessChanges.toArray(mActiveProcessChanges);
3202            mAvailProcessChanges.addAll(mPendingProcessChanges);
3203            mPendingProcessChanges.clear();
3204            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3205        }
3206
3207        int i = mProcessObservers.beginBroadcast();
3208        while (i > 0) {
3209            i--;
3210            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3211            if (observer != null) {
3212                try {
3213                    for (int j=0; j<N; j++) {
3214                        ProcessChangeItem item = mActiveProcessChanges[j];
3215                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3216                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3217                                    + item.pid + " uid=" + item.uid + ": "
3218                                    + item.foregroundActivities);
3219                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3220                                    item.foregroundActivities);
3221                        }
3222                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3223                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3224                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3225                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3226                        }
3227                    }
3228                } catch (RemoteException e) {
3229                }
3230            }
3231        }
3232        mProcessObservers.finishBroadcast();
3233    }
3234
3235    private void dispatchProcessDied(int pid, int uid) {
3236        int i = mProcessObservers.beginBroadcast();
3237        while (i > 0) {
3238            i--;
3239            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3240            if (observer != null) {
3241                try {
3242                    observer.onProcessDied(pid, uid);
3243                } catch (RemoteException e) {
3244                }
3245            }
3246        }
3247        mProcessObservers.finishBroadcast();
3248    }
3249
3250    final void doPendingActivityLaunchesLocked(boolean doResume) {
3251        final int N = mPendingActivityLaunches.size();
3252        if (N <= 0) {
3253            return;
3254        }
3255        for (int i=0; i<N; i++) {
3256            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3257            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
3258                    doResume && i == (N-1), null);
3259        }
3260        mPendingActivityLaunches.clear();
3261    }
3262
3263    @Override
3264    public final int startActivity(IApplicationThread caller, String callingPackage,
3265            Intent intent, String resolvedType, IBinder resultTo,
3266            String resultWho, int requestCode, int startFlags,
3267            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3268        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3269                resultWho, requestCode,
3270                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3271    }
3272
3273    @Override
3274    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3275            Intent intent, String resolvedType, IBinder resultTo,
3276            String resultWho, int requestCode, int startFlags,
3277            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3278        enforceNotIsolatedCaller("startActivity");
3279        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3280                false, true, "startActivity", null);
3281        // TODO: Switch to user app stacks here.
3282        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3283                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3284                null, null, options, userId, null);
3285    }
3286
3287    @Override
3288    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3289            Intent intent, String resolvedType, IBinder resultTo,
3290            String resultWho, int requestCode, int startFlags, String profileFile,
3291            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3292        enforceNotIsolatedCaller("startActivityAndWait");
3293        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3294                false, true, "startActivityAndWait", null);
3295        WaitResult res = new WaitResult();
3296        // TODO: Switch to user app stacks here.
3297        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3298                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3299                res, null, options, UserHandle.getCallingUserId(), null);
3300        return res;
3301    }
3302
3303    @Override
3304    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3305            Intent intent, String resolvedType, IBinder resultTo,
3306            String resultWho, int requestCode, int startFlags, Configuration config,
3307            Bundle options, int userId) {
3308        enforceNotIsolatedCaller("startActivityWithConfig");
3309        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3310                false, true, "startActivityWithConfig", null);
3311        // TODO: Switch to user app stacks here.
3312        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3313                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3314                null, null, null, config, options, userId, null);
3315        return ret;
3316    }
3317
3318    @Override
3319    public int startActivityIntentSender(IApplicationThread caller,
3320            IntentSender intent, Intent fillInIntent, String resolvedType,
3321            IBinder resultTo, String resultWho, int requestCode,
3322            int flagsMask, int flagsValues, Bundle options) {
3323        enforceNotIsolatedCaller("startActivityIntentSender");
3324        // Refuse possible leaked file descriptors
3325        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3326            throw new IllegalArgumentException("File descriptors passed in Intent");
3327        }
3328
3329        IIntentSender sender = intent.getTarget();
3330        if (!(sender instanceof PendingIntentRecord)) {
3331            throw new IllegalArgumentException("Bad PendingIntent object");
3332        }
3333
3334        PendingIntentRecord pir = (PendingIntentRecord)sender;
3335
3336        synchronized (this) {
3337            // If this is coming from the currently resumed activity, it is
3338            // effectively saying that app switches are allowed at this point.
3339            final ActivityStack stack = getFocusedStack();
3340            if (stack.mResumedActivity != null &&
3341                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3342                mAppSwitchesAllowedTime = 0;
3343            }
3344        }
3345        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3346                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3347        return ret;
3348    }
3349
3350    @Override
3351    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3352            Intent intent, String resolvedType, IVoiceInteractionSession session,
3353            IVoiceInteractor interactor, int startFlags, String profileFile,
3354            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3355        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3356                != PackageManager.PERMISSION_GRANTED) {
3357            String msg = "Permission Denial: startVoiceActivity() from pid="
3358                    + Binder.getCallingPid()
3359                    + ", uid=" + Binder.getCallingUid()
3360                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3361            Slog.w(TAG, msg);
3362            throw new SecurityException(msg);
3363        }
3364        if (session == null || interactor == null) {
3365            throw new NullPointerException("null session or interactor");
3366        }
3367        userId = handleIncomingUser(callingPid, callingUid, userId,
3368                false, true, "startVoiceActivity", null);
3369        // TODO: Switch to user app stacks here.
3370        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3371                resolvedType, session, interactor, null, null, 0, startFlags,
3372                profileFile, profileFd, null, null, options, userId, null);
3373    }
3374
3375    @Override
3376    public boolean startNextMatchingActivity(IBinder callingActivity,
3377            Intent intent, Bundle options) {
3378        // Refuse possible leaked file descriptors
3379        if (intent != null && intent.hasFileDescriptors() == true) {
3380            throw new IllegalArgumentException("File descriptors passed in Intent");
3381        }
3382
3383        synchronized (this) {
3384            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3385            if (r == null) {
3386                ActivityOptions.abort(options);
3387                return false;
3388            }
3389            if (r.app == null || r.app.thread == null) {
3390                // The caller is not running...  d'oh!
3391                ActivityOptions.abort(options);
3392                return false;
3393            }
3394            intent = new Intent(intent);
3395            // The caller is not allowed to change the data.
3396            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3397            // And we are resetting to find the next component...
3398            intent.setComponent(null);
3399
3400            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3401
3402            ActivityInfo aInfo = null;
3403            try {
3404                List<ResolveInfo> resolves =
3405                    AppGlobals.getPackageManager().queryIntentActivities(
3406                            intent, r.resolvedType,
3407                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3408                            UserHandle.getCallingUserId());
3409
3410                // Look for the original activity in the list...
3411                final int N = resolves != null ? resolves.size() : 0;
3412                for (int i=0; i<N; i++) {
3413                    ResolveInfo rInfo = resolves.get(i);
3414                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3415                            && rInfo.activityInfo.name.equals(r.info.name)) {
3416                        // We found the current one...  the next matching is
3417                        // after it.
3418                        i++;
3419                        if (i<N) {
3420                            aInfo = resolves.get(i).activityInfo;
3421                        }
3422                        if (debug) {
3423                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3424                                    + "/" + r.info.name);
3425                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3426                                    + "/" + aInfo.name);
3427                        }
3428                        break;
3429                    }
3430                }
3431            } catch (RemoteException e) {
3432            }
3433
3434            if (aInfo == null) {
3435                // Nobody who is next!
3436                ActivityOptions.abort(options);
3437                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3438                return false;
3439            }
3440
3441            intent.setComponent(new ComponentName(
3442                    aInfo.applicationInfo.packageName, aInfo.name));
3443            intent.setFlags(intent.getFlags()&~(
3444                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3445                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3446                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3447                    Intent.FLAG_ACTIVITY_NEW_TASK));
3448
3449            // Okay now we need to start the new activity, replacing the
3450            // currently running activity.  This is a little tricky because
3451            // we want to start the new one as if the current one is finished,
3452            // but not finish the current one first so that there is no flicker.
3453            // And thus...
3454            final boolean wasFinishing = r.finishing;
3455            r.finishing = true;
3456
3457            // Propagate reply information over to the new activity.
3458            final ActivityRecord resultTo = r.resultTo;
3459            final String resultWho = r.resultWho;
3460            final int requestCode = r.requestCode;
3461            r.resultTo = null;
3462            if (resultTo != null) {
3463                resultTo.removeResultsLocked(r, resultWho, requestCode);
3464            }
3465
3466            final long origId = Binder.clearCallingIdentity();
3467            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3468                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3469                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3470                    options, false, null, null);
3471            Binder.restoreCallingIdentity(origId);
3472
3473            r.finishing = wasFinishing;
3474            if (res != ActivityManager.START_SUCCESS) {
3475                return false;
3476            }
3477            return true;
3478        }
3479    }
3480
3481    final int startActivityInPackage(int uid, String callingPackage,
3482            Intent intent, String resolvedType, IBinder resultTo,
3483            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3484                    IActivityContainer container) {
3485
3486        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3487                false, true, "startActivityInPackage", null);
3488
3489        // TODO: Switch to user app stacks here.
3490        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3491                null, null, resultTo, resultWho, requestCode, startFlags,
3492                null, null, null, null, options, userId, container);
3493        return ret;
3494    }
3495
3496    @Override
3497    public final int startActivities(IApplicationThread caller, String callingPackage,
3498            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3499            int userId) {
3500        enforceNotIsolatedCaller("startActivities");
3501        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3502                false, true, "startActivity", null);
3503        // TODO: Switch to user app stacks here.
3504        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3505                resolvedTypes, resultTo, options, userId);
3506        return ret;
3507    }
3508
3509    final int startActivitiesInPackage(int uid, String callingPackage,
3510            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3511            Bundle options, int userId) {
3512
3513        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3514                false, true, "startActivityInPackage", null);
3515        // TODO: Switch to user app stacks here.
3516        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3517                resultTo, options, userId);
3518        return ret;
3519    }
3520
3521    final void addRecentTaskLocked(TaskRecord task) {
3522        int N = mRecentTasks.size();
3523        // Quick case: check if the top-most recent task is the same.
3524        if (N > 0 && mRecentTasks.get(0) == task) {
3525            return;
3526        }
3527        // Another quick case: never add voice sessions.
3528        if (task.voiceSession != null) {
3529            return;
3530        }
3531        // Remove any existing entries that are the same kind of task.
3532        final Intent intent = task.intent;
3533        final boolean document = intent != null && intent.isDocument();
3534        for (int i=0; i<N; i++) {
3535            TaskRecord tr = mRecentTasks.get(i);
3536            if (task != tr) {
3537                if (task.userId != tr.userId) {
3538                    continue;
3539                }
3540                final Intent trIntent = tr.intent;
3541                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3542                    (intent == null || !intent.filterEquals(trIntent))) {
3543                    continue;
3544                }
3545                if (document || trIntent != null && trIntent.isDocument()) {
3546                    // Document tasks do not match other tasks.
3547                    continue;
3548                }
3549            }
3550
3551            // Either task and tr are the same or, their affinities match or their intents match
3552            // and neither of them is a document.
3553            tr.disposeThumbnail();
3554            mRecentTasks.remove(i);
3555            i--;
3556            N--;
3557            if (task.intent == null) {
3558                // If the new recent task we are adding is not fully
3559                // specified, then replace it with the existing recent task.
3560                task = tr;
3561            }
3562        }
3563        if (N >= MAX_RECENT_TASKS) {
3564            mRecentTasks.remove(N-1).disposeThumbnail();
3565        }
3566        mRecentTasks.add(0, task);
3567    }
3568
3569    @Override
3570    public void reportActivityFullyDrawn(IBinder token) {
3571        synchronized (this) {
3572            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3573            if (r == null) {
3574                return;
3575            }
3576            r.reportFullyDrawnLocked();
3577        }
3578    }
3579
3580    @Override
3581    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3582        synchronized (this) {
3583            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3584            if (r == null) {
3585                return;
3586            }
3587            final long origId = Binder.clearCallingIdentity();
3588            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3589            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3590                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3591            if (config != null) {
3592                r.frozenBeforeDestroy = true;
3593                if (!updateConfigurationLocked(config, r, false, false)) {
3594                    mStackSupervisor.resumeTopActivitiesLocked();
3595                }
3596            }
3597            Binder.restoreCallingIdentity(origId);
3598        }
3599    }
3600
3601    @Override
3602    public int getRequestedOrientation(IBinder token) {
3603        synchronized (this) {
3604            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3605            if (r == null) {
3606                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3607            }
3608            return mWindowManager.getAppOrientation(r.appToken);
3609        }
3610    }
3611
3612    /**
3613     * This is the internal entry point for handling Activity.finish().
3614     *
3615     * @param token The Binder token referencing the Activity we want to finish.
3616     * @param resultCode Result code, if any, from this Activity.
3617     * @param resultData Result data (Intent), if any, from this Activity.
3618     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3619     *            the root Activity in the task.
3620     *
3621     * @return Returns true if the activity successfully finished, or false if it is still running.
3622     */
3623    @Override
3624    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3625            boolean finishTask) {
3626        // Refuse possible leaked file descriptors
3627        if (resultData != null && resultData.hasFileDescriptors() == true) {
3628            throw new IllegalArgumentException("File descriptors passed in Intent");
3629        }
3630
3631        synchronized(this) {
3632            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3633            if (r == null) {
3634                return true;
3635            }
3636            // Keep track of the root activity of the task before we finish it
3637            TaskRecord tr = r.task;
3638            ActivityRecord rootR = tr.getRootActivity();
3639            if (mController != null) {
3640                // Find the first activity that is not finishing.
3641                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3642                if (next != null) {
3643                    // ask watcher if this is allowed
3644                    boolean resumeOK = true;
3645                    try {
3646                        resumeOK = mController.activityResuming(next.packageName);
3647                    } catch (RemoteException e) {
3648                        mController = null;
3649                        Watchdog.getInstance().setActivityController(null);
3650                    }
3651
3652                    if (!resumeOK) {
3653                        return false;
3654                    }
3655                }
3656            }
3657            final long origId = Binder.clearCallingIdentity();
3658            try {
3659                boolean res;
3660                if (finishTask && r == rootR) {
3661                    // If requested, remove the task that is associated to this activity only if it
3662                    // was the root activity in the task.  The result code and data is ignored because
3663                    // we don't support returning them across task boundaries.
3664                    res = removeTaskByIdLocked(tr.taskId, 0);
3665                } else {
3666                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3667                            resultData, "app-request", true);
3668                }
3669                return res;
3670            } finally {
3671                Binder.restoreCallingIdentity(origId);
3672            }
3673        }
3674    }
3675
3676    @Override
3677    public final void finishHeavyWeightApp() {
3678        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3679                != PackageManager.PERMISSION_GRANTED) {
3680            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3681                    + Binder.getCallingPid()
3682                    + ", uid=" + Binder.getCallingUid()
3683                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3684            Slog.w(TAG, msg);
3685            throw new SecurityException(msg);
3686        }
3687
3688        synchronized(this) {
3689            if (mHeavyWeightProcess == null) {
3690                return;
3691            }
3692
3693            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3694                    mHeavyWeightProcess.activities);
3695            for (int i=0; i<activities.size(); i++) {
3696                ActivityRecord r = activities.get(i);
3697                if (!r.finishing) {
3698                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3699                            null, "finish-heavy", true);
3700                }
3701            }
3702
3703            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3704                    mHeavyWeightProcess.userId, 0));
3705            mHeavyWeightProcess = null;
3706        }
3707    }
3708
3709    @Override
3710    public void crashApplication(int uid, int initialPid, String packageName,
3711            String message) {
3712        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3713                != PackageManager.PERMISSION_GRANTED) {
3714            String msg = "Permission Denial: crashApplication() from pid="
3715                    + Binder.getCallingPid()
3716                    + ", uid=" + Binder.getCallingUid()
3717                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3718            Slog.w(TAG, msg);
3719            throw new SecurityException(msg);
3720        }
3721
3722        synchronized(this) {
3723            ProcessRecord proc = null;
3724
3725            // Figure out which process to kill.  We don't trust that initialPid
3726            // still has any relation to current pids, so must scan through the
3727            // list.
3728            synchronized (mPidsSelfLocked) {
3729                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3730                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3731                    if (p.uid != uid) {
3732                        continue;
3733                    }
3734                    if (p.pid == initialPid) {
3735                        proc = p;
3736                        break;
3737                    }
3738                    if (p.pkgList.containsKey(packageName)) {
3739                        proc = p;
3740                    }
3741                }
3742            }
3743
3744            if (proc == null) {
3745                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3746                        + " initialPid=" + initialPid
3747                        + " packageName=" + packageName);
3748                return;
3749            }
3750
3751            if (proc.thread != null) {
3752                if (proc.pid == Process.myPid()) {
3753                    Log.w(TAG, "crashApplication: trying to crash self!");
3754                    return;
3755                }
3756                long ident = Binder.clearCallingIdentity();
3757                try {
3758                    proc.thread.scheduleCrash(message);
3759                } catch (RemoteException e) {
3760                }
3761                Binder.restoreCallingIdentity(ident);
3762            }
3763        }
3764    }
3765
3766    @Override
3767    public final void finishSubActivity(IBinder token, String resultWho,
3768            int requestCode) {
3769        synchronized(this) {
3770            final long origId = Binder.clearCallingIdentity();
3771            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3772            if (r != null) {
3773                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3774            }
3775            Binder.restoreCallingIdentity(origId);
3776        }
3777    }
3778
3779    @Override
3780    public boolean finishActivityAffinity(IBinder token) {
3781        synchronized(this) {
3782            final long origId = Binder.clearCallingIdentity();
3783            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3784            boolean res = false;
3785            if (r != null) {
3786                res = r.task.stack.finishActivityAffinityLocked(r);
3787            }
3788            Binder.restoreCallingIdentity(origId);
3789            return res;
3790        }
3791    }
3792
3793    @Override
3794    public boolean willActivityBeVisible(IBinder token) {
3795        synchronized(this) {
3796            ActivityStack stack = ActivityRecord.getStackLocked(token);
3797            if (stack != null) {
3798                return stack.willActivityBeVisibleLocked(token);
3799            }
3800            return false;
3801        }
3802    }
3803
3804    @Override
3805    public void overridePendingTransition(IBinder token, String packageName,
3806            int enterAnim, int exitAnim) {
3807        synchronized(this) {
3808            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3809            if (self == null) {
3810                return;
3811            }
3812
3813            final long origId = Binder.clearCallingIdentity();
3814
3815            if (self.state == ActivityState.RESUMED
3816                    || self.state == ActivityState.PAUSING) {
3817                mWindowManager.overridePendingAppTransition(packageName,
3818                        enterAnim, exitAnim, null);
3819            }
3820
3821            Binder.restoreCallingIdentity(origId);
3822        }
3823    }
3824
3825    /**
3826     * Main function for removing an existing process from the activity manager
3827     * as a result of that process going away.  Clears out all connections
3828     * to the process.
3829     */
3830    private final void handleAppDiedLocked(ProcessRecord app,
3831            boolean restarting, boolean allowRestart) {
3832        int pid = app.pid;
3833        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3834        if (!restarting) {
3835            removeLruProcessLocked(app);
3836            if (pid > 0) {
3837                ProcessList.remove(pid);
3838            }
3839        }
3840
3841        if (mProfileProc == app) {
3842            clearProfilerLocked();
3843        }
3844
3845        // Remove this application's activities from active lists.
3846        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3847
3848        app.activities.clear();
3849
3850        if (app.instrumentationClass != null) {
3851            Slog.w(TAG, "Crash of app " + app.processName
3852                  + " running instrumentation " + app.instrumentationClass);
3853            Bundle info = new Bundle();
3854            info.putString("shortMsg", "Process crashed.");
3855            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3856        }
3857
3858        if (!restarting) {
3859            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3860                // If there was nothing to resume, and we are not already
3861                // restarting this process, but there is a visible activity that
3862                // is hosted by the process...  then make sure all visible
3863                // activities are running, taking care of restarting this
3864                // process.
3865                if (hasVisibleActivities) {
3866                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3867                }
3868            }
3869        }
3870    }
3871
3872    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3873        IBinder threadBinder = thread.asBinder();
3874        // Find the application record.
3875        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3876            ProcessRecord rec = mLruProcesses.get(i);
3877            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3878                return i;
3879            }
3880        }
3881        return -1;
3882    }
3883
3884    final ProcessRecord getRecordForAppLocked(
3885            IApplicationThread thread) {
3886        if (thread == null) {
3887            return null;
3888        }
3889
3890        int appIndex = getLRURecordIndexForAppLocked(thread);
3891        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3892    }
3893
3894    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3895        // If there are no longer any background processes running,
3896        // and the app that died was not running instrumentation,
3897        // then tell everyone we are now low on memory.
3898        boolean haveBg = false;
3899        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3900            ProcessRecord rec = mLruProcesses.get(i);
3901            if (rec.thread != null
3902                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3903                haveBg = true;
3904                break;
3905            }
3906        }
3907
3908        if (!haveBg) {
3909            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3910            if (doReport) {
3911                long now = SystemClock.uptimeMillis();
3912                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3913                    doReport = false;
3914                } else {
3915                    mLastMemUsageReportTime = now;
3916                }
3917            }
3918            final ArrayList<ProcessMemInfo> memInfos
3919                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3920            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3921            long now = SystemClock.uptimeMillis();
3922            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3923                ProcessRecord rec = mLruProcesses.get(i);
3924                if (rec == dyingProc || rec.thread == null) {
3925                    continue;
3926                }
3927                if (doReport) {
3928                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3929                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3930                }
3931                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3932                    // The low memory report is overriding any current
3933                    // state for a GC request.  Make sure to do
3934                    // heavy/important/visible/foreground processes first.
3935                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3936                        rec.lastRequestedGc = 0;
3937                    } else {
3938                        rec.lastRequestedGc = rec.lastLowMemory;
3939                    }
3940                    rec.reportLowMemory = true;
3941                    rec.lastLowMemory = now;
3942                    mProcessesToGc.remove(rec);
3943                    addProcessToGcListLocked(rec);
3944                }
3945            }
3946            if (doReport) {
3947                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3948                mHandler.sendMessage(msg);
3949            }
3950            scheduleAppGcsLocked();
3951        }
3952    }
3953
3954    final void appDiedLocked(ProcessRecord app, int pid,
3955            IApplicationThread thread) {
3956
3957        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3958        synchronized (stats) {
3959            stats.noteProcessDiedLocked(app.info.uid, pid);
3960        }
3961
3962        // Clean up already done if the process has been re-started.
3963        if (app.pid == pid && app.thread != null &&
3964                app.thread.asBinder() == thread.asBinder()) {
3965            boolean doLowMem = app.instrumentationClass == null;
3966            boolean doOomAdj = doLowMem;
3967            if (!app.killedByAm) {
3968                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3969                        + ") has died.");
3970                mAllowLowerMemLevel = true;
3971            } else {
3972                // Note that we always want to do oom adj to update our state with the
3973                // new number of procs.
3974                mAllowLowerMemLevel = false;
3975                doLowMem = false;
3976            }
3977            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3978            if (DEBUG_CLEANUP) Slog.v(
3979                TAG, "Dying app: " + app + ", pid: " + pid
3980                + ", thread: " + thread.asBinder());
3981            handleAppDiedLocked(app, false, true);
3982
3983            if (doOomAdj) {
3984                updateOomAdjLocked();
3985            }
3986            if (doLowMem) {
3987                doLowMemReportIfNeededLocked(app);
3988            }
3989        } else if (app.pid != pid) {
3990            // A new process has already been started.
3991            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3992                    + ") has died and restarted (pid " + app.pid + ").");
3993            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3994        } else if (DEBUG_PROCESSES) {
3995            Slog.d(TAG, "Received spurious death notification for thread "
3996                    + thread.asBinder());
3997        }
3998    }
3999
4000    /**
4001     * If a stack trace dump file is configured, dump process stack traces.
4002     * @param clearTraces causes the dump file to be erased prior to the new
4003     *    traces being written, if true; when false, the new traces will be
4004     *    appended to any existing file content.
4005     * @param firstPids of dalvik VM processes to dump stack traces for first
4006     * @param lastPids of dalvik VM processes to dump stack traces for last
4007     * @param nativeProcs optional list of native process names to dump stack crawls
4008     * @return file containing stack traces, or null if no dump file is configured
4009     */
4010    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4011            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4012        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4013        if (tracesPath == null || tracesPath.length() == 0) {
4014            return null;
4015        }
4016
4017        File tracesFile = new File(tracesPath);
4018        try {
4019            File tracesDir = tracesFile.getParentFile();
4020            if (!tracesDir.exists()) {
4021                tracesFile.mkdirs();
4022                if (!SELinux.restorecon(tracesDir)) {
4023                    return null;
4024                }
4025            }
4026            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4027
4028            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4029            tracesFile.createNewFile();
4030            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4031        } catch (IOException e) {
4032            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4033            return null;
4034        }
4035
4036        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4037        return tracesFile;
4038    }
4039
4040    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4041            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4042        // Use a FileObserver to detect when traces finish writing.
4043        // The order of traces is considered important to maintain for legibility.
4044        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4045            @Override
4046            public synchronized void onEvent(int event, String path) { notify(); }
4047        };
4048
4049        try {
4050            observer.startWatching();
4051
4052            // First collect all of the stacks of the most important pids.
4053            if (firstPids != null) {
4054                try {
4055                    int num = firstPids.size();
4056                    for (int i = 0; i < num; i++) {
4057                        synchronized (observer) {
4058                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4059                            observer.wait(200);  // Wait for write-close, give up after 200msec
4060                        }
4061                    }
4062                } catch (InterruptedException e) {
4063                    Log.wtf(TAG, e);
4064                }
4065            }
4066
4067            // Next collect the stacks of the native pids
4068            if (nativeProcs != null) {
4069                int[] pids = Process.getPidsForCommands(nativeProcs);
4070                if (pids != null) {
4071                    for (int pid : pids) {
4072                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4073                    }
4074                }
4075            }
4076
4077            // Lastly, measure CPU usage.
4078            if (processCpuTracker != null) {
4079                processCpuTracker.init();
4080                System.gc();
4081                processCpuTracker.update();
4082                try {
4083                    synchronized (processCpuTracker) {
4084                        processCpuTracker.wait(500); // measure over 1/2 second.
4085                    }
4086                } catch (InterruptedException e) {
4087                }
4088                processCpuTracker.update();
4089
4090                // We'll take the stack crawls of just the top apps using CPU.
4091                final int N = processCpuTracker.countWorkingStats();
4092                int numProcs = 0;
4093                for (int i=0; i<N && numProcs<5; i++) {
4094                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4095                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4096                        numProcs++;
4097                        try {
4098                            synchronized (observer) {
4099                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4100                                observer.wait(200);  // Wait for write-close, give up after 200msec
4101                            }
4102                        } catch (InterruptedException e) {
4103                            Log.wtf(TAG, e);
4104                        }
4105
4106                    }
4107                }
4108            }
4109        } finally {
4110            observer.stopWatching();
4111        }
4112    }
4113
4114    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4115        if (true || IS_USER_BUILD) {
4116            return;
4117        }
4118        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4119        if (tracesPath == null || tracesPath.length() == 0) {
4120            return;
4121        }
4122
4123        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4124        StrictMode.allowThreadDiskWrites();
4125        try {
4126            final File tracesFile = new File(tracesPath);
4127            final File tracesDir = tracesFile.getParentFile();
4128            final File tracesTmp = new File(tracesDir, "__tmp__");
4129            try {
4130                if (!tracesDir.exists()) {
4131                    tracesFile.mkdirs();
4132                    if (!SELinux.restorecon(tracesDir.getPath())) {
4133                        return;
4134                    }
4135                }
4136                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4137
4138                if (tracesFile.exists()) {
4139                    tracesTmp.delete();
4140                    tracesFile.renameTo(tracesTmp);
4141                }
4142                StringBuilder sb = new StringBuilder();
4143                Time tobj = new Time();
4144                tobj.set(System.currentTimeMillis());
4145                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4146                sb.append(": ");
4147                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4148                sb.append(" since ");
4149                sb.append(msg);
4150                FileOutputStream fos = new FileOutputStream(tracesFile);
4151                fos.write(sb.toString().getBytes());
4152                if (app == null) {
4153                    fos.write("\n*** No application process!".getBytes());
4154                }
4155                fos.close();
4156                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4157            } catch (IOException e) {
4158                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4159                return;
4160            }
4161
4162            if (app != null) {
4163                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4164                firstPids.add(app.pid);
4165                dumpStackTraces(tracesPath, firstPids, null, null, null);
4166            }
4167
4168            File lastTracesFile = null;
4169            File curTracesFile = null;
4170            for (int i=9; i>=0; i--) {
4171                String name = String.format(Locale.US, "slow%02d.txt", i);
4172                curTracesFile = new File(tracesDir, name);
4173                if (curTracesFile.exists()) {
4174                    if (lastTracesFile != null) {
4175                        curTracesFile.renameTo(lastTracesFile);
4176                    } else {
4177                        curTracesFile.delete();
4178                    }
4179                }
4180                lastTracesFile = curTracesFile;
4181            }
4182            tracesFile.renameTo(curTracesFile);
4183            if (tracesTmp.exists()) {
4184                tracesTmp.renameTo(tracesFile);
4185            }
4186        } finally {
4187            StrictMode.setThreadPolicy(oldPolicy);
4188        }
4189    }
4190
4191    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4192            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4193        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4194        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4195
4196        if (mController != null) {
4197            try {
4198                // 0 == continue, -1 = kill process immediately
4199                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4200                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
4201            } catch (RemoteException e) {
4202                mController = null;
4203                Watchdog.getInstance().setActivityController(null);
4204            }
4205        }
4206
4207        long anrTime = SystemClock.uptimeMillis();
4208        if (MONITOR_CPU_USAGE) {
4209            updateCpuStatsNow();
4210        }
4211
4212        synchronized (this) {
4213            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4214            if (mShuttingDown) {
4215                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4216                return;
4217            } else if (app.notResponding) {
4218                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4219                return;
4220            } else if (app.crashing) {
4221                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4222                return;
4223            }
4224
4225            // In case we come through here for the same app before completing
4226            // this one, mark as anring now so we will bail out.
4227            app.notResponding = true;
4228
4229            // Log the ANR to the event log.
4230            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4231                    app.processName, app.info.flags, annotation);
4232
4233            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4234            firstPids.add(app.pid);
4235
4236            int parentPid = app.pid;
4237            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4238            if (parentPid != app.pid) firstPids.add(parentPid);
4239
4240            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4241
4242            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4243                ProcessRecord r = mLruProcesses.get(i);
4244                if (r != null && r.thread != null) {
4245                    int pid = r.pid;
4246                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4247                        if (r.persistent) {
4248                            firstPids.add(pid);
4249                        } else {
4250                            lastPids.put(pid, Boolean.TRUE);
4251                        }
4252                    }
4253                }
4254            }
4255        }
4256
4257        // Log the ANR to the main log.
4258        StringBuilder info = new StringBuilder();
4259        info.setLength(0);
4260        info.append("ANR in ").append(app.processName);
4261        if (activity != null && activity.shortComponentName != null) {
4262            info.append(" (").append(activity.shortComponentName).append(")");
4263        }
4264        info.append("\n");
4265        info.append("PID: ").append(app.pid).append("\n");
4266        if (annotation != null) {
4267            info.append("Reason: ").append(annotation).append("\n");
4268        }
4269        if (parent != null && parent != activity) {
4270            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4271        }
4272
4273        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4274
4275        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4276                NATIVE_STACKS_OF_INTEREST);
4277
4278        String cpuInfo = null;
4279        if (MONITOR_CPU_USAGE) {
4280            updateCpuStatsNow();
4281            synchronized (mProcessCpuThread) {
4282                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4283            }
4284            info.append(processCpuTracker.printCurrentLoad());
4285            info.append(cpuInfo);
4286        }
4287
4288        info.append(processCpuTracker.printCurrentState(anrTime));
4289
4290        Slog.e(TAG, info.toString());
4291        if (tracesFile == null) {
4292            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4293            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4294        }
4295
4296        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4297                cpuInfo, tracesFile, null);
4298
4299        if (mController != null) {
4300            try {
4301                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4302                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4303                if (res != 0) {
4304                    if (res < 0 && app.pid != MY_PID) {
4305                        Process.killProcess(app.pid);
4306                    } else {
4307                        synchronized (this) {
4308                            mServices.scheduleServiceTimeoutLocked(app);
4309                        }
4310                    }
4311                    return;
4312                }
4313            } catch (RemoteException e) {
4314                mController = null;
4315                Watchdog.getInstance().setActivityController(null);
4316            }
4317        }
4318
4319        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4320        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4321                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4322
4323        synchronized (this) {
4324            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4325                killUnneededProcessLocked(app, "background ANR");
4326                return;
4327            }
4328
4329            // Set the app's notResponding state, and look up the errorReportReceiver
4330            makeAppNotRespondingLocked(app,
4331                    activity != null ? activity.shortComponentName : null,
4332                    annotation != null ? "ANR " + annotation : "ANR",
4333                    info.toString());
4334
4335            // Bring up the infamous App Not Responding dialog
4336            Message msg = Message.obtain();
4337            HashMap<String, Object> map = new HashMap<String, Object>();
4338            msg.what = SHOW_NOT_RESPONDING_MSG;
4339            msg.obj = map;
4340            msg.arg1 = aboveSystem ? 1 : 0;
4341            map.put("app", app);
4342            if (activity != null) {
4343                map.put("activity", activity);
4344            }
4345
4346            mHandler.sendMessage(msg);
4347        }
4348    }
4349
4350    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4351        if (!mLaunchWarningShown) {
4352            mLaunchWarningShown = true;
4353            mHandler.post(new Runnable() {
4354                @Override
4355                public void run() {
4356                    synchronized (ActivityManagerService.this) {
4357                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4358                        d.show();
4359                        mHandler.postDelayed(new Runnable() {
4360                            @Override
4361                            public void run() {
4362                                synchronized (ActivityManagerService.this) {
4363                                    d.dismiss();
4364                                    mLaunchWarningShown = false;
4365                                }
4366                            }
4367                        }, 4000);
4368                    }
4369                }
4370            });
4371        }
4372    }
4373
4374    @Override
4375    public boolean clearApplicationUserData(final String packageName,
4376            final IPackageDataObserver observer, int userId) {
4377        enforceNotIsolatedCaller("clearApplicationUserData");
4378        int uid = Binder.getCallingUid();
4379        int pid = Binder.getCallingPid();
4380        userId = handleIncomingUser(pid, uid,
4381                userId, false, true, "clearApplicationUserData", null);
4382        long callingId = Binder.clearCallingIdentity();
4383        try {
4384            IPackageManager pm = AppGlobals.getPackageManager();
4385            int pkgUid = -1;
4386            synchronized(this) {
4387                try {
4388                    pkgUid = pm.getPackageUid(packageName, userId);
4389                } catch (RemoteException e) {
4390                }
4391                if (pkgUid == -1) {
4392                    Slog.w(TAG, "Invalid packageName: " + packageName);
4393                    if (observer != null) {
4394                        try {
4395                            observer.onRemoveCompleted(packageName, false);
4396                        } catch (RemoteException e) {
4397                            Slog.i(TAG, "Observer no longer exists.");
4398                        }
4399                    }
4400                    return false;
4401                }
4402                if (uid == pkgUid || checkComponentPermission(
4403                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4404                        pid, uid, -1, true)
4405                        == PackageManager.PERMISSION_GRANTED) {
4406                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4407                } else {
4408                    throw new SecurityException("PID " + pid + " does not have permission "
4409                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4410                                    + " of package " + packageName);
4411                }
4412            }
4413
4414            try {
4415                // Clear application user data
4416                pm.clearApplicationUserData(packageName, observer, userId);
4417
4418                // Remove all permissions granted from/to this package
4419                removeUriPermissionsForPackageLocked(packageName, userId, true);
4420
4421                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4422                        Uri.fromParts("package", packageName, null));
4423                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4424                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4425                        null, null, 0, null, null, null, false, false, userId);
4426            } catch (RemoteException e) {
4427            }
4428        } finally {
4429            Binder.restoreCallingIdentity(callingId);
4430        }
4431        return true;
4432    }
4433
4434    @Override
4435    public void killBackgroundProcesses(final String packageName, int userId) {
4436        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4437                != PackageManager.PERMISSION_GRANTED &&
4438                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4439                        != PackageManager.PERMISSION_GRANTED) {
4440            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4441                    + Binder.getCallingPid()
4442                    + ", uid=" + Binder.getCallingUid()
4443                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4444            Slog.w(TAG, msg);
4445            throw new SecurityException(msg);
4446        }
4447
4448        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4449                userId, true, true, "killBackgroundProcesses", null);
4450        long callingId = Binder.clearCallingIdentity();
4451        try {
4452            IPackageManager pm = AppGlobals.getPackageManager();
4453            synchronized(this) {
4454                int appId = -1;
4455                try {
4456                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4457                } catch (RemoteException e) {
4458                }
4459                if (appId == -1) {
4460                    Slog.w(TAG, "Invalid packageName: " + packageName);
4461                    return;
4462                }
4463                killPackageProcessesLocked(packageName, appId, userId,
4464                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4465            }
4466        } finally {
4467            Binder.restoreCallingIdentity(callingId);
4468        }
4469    }
4470
4471    @Override
4472    public void killAllBackgroundProcesses() {
4473        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4474                != PackageManager.PERMISSION_GRANTED) {
4475            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4476                    + Binder.getCallingPid()
4477                    + ", uid=" + Binder.getCallingUid()
4478                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4479            Slog.w(TAG, msg);
4480            throw new SecurityException(msg);
4481        }
4482
4483        long callingId = Binder.clearCallingIdentity();
4484        try {
4485            synchronized(this) {
4486                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4487                final int NP = mProcessNames.getMap().size();
4488                for (int ip=0; ip<NP; ip++) {
4489                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4490                    final int NA = apps.size();
4491                    for (int ia=0; ia<NA; ia++) {
4492                        ProcessRecord app = apps.valueAt(ia);
4493                        if (app.persistent) {
4494                            // we don't kill persistent processes
4495                            continue;
4496                        }
4497                        if (app.removed) {
4498                            procs.add(app);
4499                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4500                            app.removed = true;
4501                            procs.add(app);
4502                        }
4503                    }
4504                }
4505
4506                int N = procs.size();
4507                for (int i=0; i<N; i++) {
4508                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4509                }
4510                mAllowLowerMemLevel = true;
4511                updateOomAdjLocked();
4512                doLowMemReportIfNeededLocked(null);
4513            }
4514        } finally {
4515            Binder.restoreCallingIdentity(callingId);
4516        }
4517    }
4518
4519    @Override
4520    public void forceStopPackage(final String packageName, int userId) {
4521        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4522                != PackageManager.PERMISSION_GRANTED) {
4523            String msg = "Permission Denial: forceStopPackage() from pid="
4524                    + Binder.getCallingPid()
4525                    + ", uid=" + Binder.getCallingUid()
4526                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4527            Slog.w(TAG, msg);
4528            throw new SecurityException(msg);
4529        }
4530        final int callingPid = Binder.getCallingPid();
4531        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4532                userId, true, true, "forceStopPackage", null);
4533        long callingId = Binder.clearCallingIdentity();
4534        try {
4535            IPackageManager pm = AppGlobals.getPackageManager();
4536            synchronized(this) {
4537                int[] users = userId == UserHandle.USER_ALL
4538                        ? getUsersLocked() : new int[] { userId };
4539                for (int user : users) {
4540                    int pkgUid = -1;
4541                    try {
4542                        pkgUid = pm.getPackageUid(packageName, user);
4543                    } catch (RemoteException e) {
4544                    }
4545                    if (pkgUid == -1) {
4546                        Slog.w(TAG, "Invalid packageName: " + packageName);
4547                        continue;
4548                    }
4549                    try {
4550                        pm.setPackageStoppedState(packageName, true, user);
4551                    } catch (RemoteException e) {
4552                    } catch (IllegalArgumentException e) {
4553                        Slog.w(TAG, "Failed trying to unstop package "
4554                                + packageName + ": " + e);
4555                    }
4556                    if (isUserRunningLocked(user, false)) {
4557                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4558                    }
4559                }
4560            }
4561        } finally {
4562            Binder.restoreCallingIdentity(callingId);
4563        }
4564    }
4565
4566    /*
4567     * The pkg name and app id have to be specified.
4568     */
4569    @Override
4570    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4571        if (pkg == null) {
4572            return;
4573        }
4574        // Make sure the uid is valid.
4575        if (appid < 0) {
4576            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4577            return;
4578        }
4579        int callerUid = Binder.getCallingUid();
4580        // Only the system server can kill an application
4581        if (callerUid == Process.SYSTEM_UID) {
4582            // Post an aysnc message to kill the application
4583            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4584            msg.arg1 = appid;
4585            msg.arg2 = 0;
4586            Bundle bundle = new Bundle();
4587            bundle.putString("pkg", pkg);
4588            bundle.putString("reason", reason);
4589            msg.obj = bundle;
4590            mHandler.sendMessage(msg);
4591        } else {
4592            throw new SecurityException(callerUid + " cannot kill pkg: " +
4593                    pkg);
4594        }
4595    }
4596
4597    @Override
4598    public void closeSystemDialogs(String reason) {
4599        enforceNotIsolatedCaller("closeSystemDialogs");
4600
4601        final int pid = Binder.getCallingPid();
4602        final int uid = Binder.getCallingUid();
4603        final long origId = Binder.clearCallingIdentity();
4604        try {
4605            synchronized (this) {
4606                // Only allow this from foreground processes, so that background
4607                // applications can't abuse it to prevent system UI from being shown.
4608                if (uid >= Process.FIRST_APPLICATION_UID) {
4609                    ProcessRecord proc;
4610                    synchronized (mPidsSelfLocked) {
4611                        proc = mPidsSelfLocked.get(pid);
4612                    }
4613                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4614                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4615                                + " from background process " + proc);
4616                        return;
4617                    }
4618                }
4619                closeSystemDialogsLocked(reason);
4620            }
4621        } finally {
4622            Binder.restoreCallingIdentity(origId);
4623        }
4624    }
4625
4626    void closeSystemDialogsLocked(String reason) {
4627        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4628        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4629                | Intent.FLAG_RECEIVER_FOREGROUND);
4630        if (reason != null) {
4631            intent.putExtra("reason", reason);
4632        }
4633        mWindowManager.closeSystemDialogs(reason);
4634
4635        mStackSupervisor.closeSystemDialogsLocked();
4636
4637        broadcastIntentLocked(null, null, intent, null,
4638                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4639                Process.SYSTEM_UID, UserHandle.USER_ALL);
4640    }
4641
4642    @Override
4643    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4644        enforceNotIsolatedCaller("getProcessMemoryInfo");
4645        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4646        for (int i=pids.length-1; i>=0; i--) {
4647            ProcessRecord proc;
4648            int oomAdj;
4649            synchronized (this) {
4650                synchronized (mPidsSelfLocked) {
4651                    proc = mPidsSelfLocked.get(pids[i]);
4652                    oomAdj = proc != null ? proc.setAdj : 0;
4653                }
4654            }
4655            infos[i] = new Debug.MemoryInfo();
4656            Debug.getMemoryInfo(pids[i], infos[i]);
4657            if (proc != null) {
4658                synchronized (this) {
4659                    if (proc.thread != null && proc.setAdj == oomAdj) {
4660                        // Record this for posterity if the process has been stable.
4661                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4662                                infos[i].getTotalUss(), false, proc.pkgList);
4663                    }
4664                }
4665            }
4666        }
4667        return infos;
4668    }
4669
4670    @Override
4671    public long[] getProcessPss(int[] pids) {
4672        enforceNotIsolatedCaller("getProcessPss");
4673        long[] pss = new long[pids.length];
4674        for (int i=pids.length-1; i>=0; i--) {
4675            ProcessRecord proc;
4676            int oomAdj;
4677            synchronized (this) {
4678                synchronized (mPidsSelfLocked) {
4679                    proc = mPidsSelfLocked.get(pids[i]);
4680                    oomAdj = proc != null ? proc.setAdj : 0;
4681                }
4682            }
4683            long[] tmpUss = new long[1];
4684            pss[i] = Debug.getPss(pids[i], tmpUss);
4685            if (proc != null) {
4686                synchronized (this) {
4687                    if (proc.thread != null && proc.setAdj == oomAdj) {
4688                        // Record this for posterity if the process has been stable.
4689                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4690                    }
4691                }
4692            }
4693        }
4694        return pss;
4695    }
4696
4697    @Override
4698    public void killApplicationProcess(String processName, int uid) {
4699        if (processName == null) {
4700            return;
4701        }
4702
4703        int callerUid = Binder.getCallingUid();
4704        // Only the system server can kill an application
4705        if (callerUid == Process.SYSTEM_UID) {
4706            synchronized (this) {
4707                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4708                if (app != null && app.thread != null) {
4709                    try {
4710                        app.thread.scheduleSuicide();
4711                    } catch (RemoteException e) {
4712                        // If the other end already died, then our work here is done.
4713                    }
4714                } else {
4715                    Slog.w(TAG, "Process/uid not found attempting kill of "
4716                            + processName + " / " + uid);
4717                }
4718            }
4719        } else {
4720            throw new SecurityException(callerUid + " cannot kill app process: " +
4721                    processName);
4722        }
4723    }
4724
4725    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4726        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4727                false, true, false, false, UserHandle.getUserId(uid), reason);
4728        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4729                Uri.fromParts("package", packageName, null));
4730        if (!mProcessesReady) {
4731            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4732                    | Intent.FLAG_RECEIVER_FOREGROUND);
4733        }
4734        intent.putExtra(Intent.EXTRA_UID, uid);
4735        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4736        broadcastIntentLocked(null, null, intent,
4737                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4738                false, false,
4739                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4740    }
4741
4742    private void forceStopUserLocked(int userId, String reason) {
4743        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4744        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4745        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4746                | Intent.FLAG_RECEIVER_FOREGROUND);
4747        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4748        broadcastIntentLocked(null, null, intent,
4749                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4750                false, false,
4751                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4752    }
4753
4754    private final boolean killPackageProcessesLocked(String packageName, int appId,
4755            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4756            boolean doit, boolean evenPersistent, String reason) {
4757        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4758
4759        // Remove all processes this package may have touched: all with the
4760        // same UID (except for the system or root user), and all whose name
4761        // matches the package name.
4762        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4763        final int NP = mProcessNames.getMap().size();
4764        for (int ip=0; ip<NP; ip++) {
4765            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4766            final int NA = apps.size();
4767            for (int ia=0; ia<NA; ia++) {
4768                ProcessRecord app = apps.valueAt(ia);
4769                if (app.persistent && !evenPersistent) {
4770                    // we don't kill persistent processes
4771                    continue;
4772                }
4773                if (app.removed) {
4774                    if (doit) {
4775                        procs.add(app);
4776                    }
4777                    continue;
4778                }
4779
4780                // Skip process if it doesn't meet our oom adj requirement.
4781                if (app.setAdj < minOomAdj) {
4782                    continue;
4783                }
4784
4785                // If no package is specified, we call all processes under the
4786                // give user id.
4787                if (packageName == null) {
4788                    if (app.userId != userId) {
4789                        continue;
4790                    }
4791                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4792                        continue;
4793                    }
4794                // Package has been specified, we want to hit all processes
4795                // that match it.  We need to qualify this by the processes
4796                // that are running under the specified app and user ID.
4797                } else {
4798                    if (UserHandle.getAppId(app.uid) != appId) {
4799                        continue;
4800                    }
4801                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4802                        continue;
4803                    }
4804                    if (!app.pkgList.containsKey(packageName)) {
4805                        continue;
4806                    }
4807                }
4808
4809                // Process has passed all conditions, kill it!
4810                if (!doit) {
4811                    return true;
4812                }
4813                app.removed = true;
4814                procs.add(app);
4815            }
4816        }
4817
4818        int N = procs.size();
4819        for (int i=0; i<N; i++) {
4820            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4821        }
4822        updateOomAdjLocked();
4823        return N > 0;
4824    }
4825
4826    private final boolean forceStopPackageLocked(String name, int appId,
4827            boolean callerWillRestart, boolean purgeCache, boolean doit,
4828            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4829        int i;
4830        int N;
4831
4832        if (userId == UserHandle.USER_ALL && name == null) {
4833            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4834        }
4835
4836        if (appId < 0 && name != null) {
4837            try {
4838                appId = UserHandle.getAppId(
4839                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4840            } catch (RemoteException e) {
4841            }
4842        }
4843
4844        if (doit) {
4845            if (name != null) {
4846                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4847                        + " user=" + userId + ": " + reason);
4848            } else {
4849                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4850            }
4851
4852            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4853            for (int ip=pmap.size()-1; ip>=0; ip--) {
4854                SparseArray<Long> ba = pmap.valueAt(ip);
4855                for (i=ba.size()-1; i>=0; i--) {
4856                    boolean remove = false;
4857                    final int entUid = ba.keyAt(i);
4858                    if (name != null) {
4859                        if (userId == UserHandle.USER_ALL) {
4860                            if (UserHandle.getAppId(entUid) == appId) {
4861                                remove = true;
4862                            }
4863                        } else {
4864                            if (entUid == UserHandle.getUid(userId, appId)) {
4865                                remove = true;
4866                            }
4867                        }
4868                    } else if (UserHandle.getUserId(entUid) == userId) {
4869                        remove = true;
4870                    }
4871                    if (remove) {
4872                        ba.removeAt(i);
4873                    }
4874                }
4875                if (ba.size() == 0) {
4876                    pmap.removeAt(ip);
4877                }
4878            }
4879        }
4880
4881        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4882                -100, callerWillRestart, true, doit, evenPersistent,
4883                name == null ? ("stop user " + userId) : ("stop " + name));
4884
4885        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4886            if (!doit) {
4887                return true;
4888            }
4889            didSomething = true;
4890        }
4891
4892        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4893            if (!doit) {
4894                return true;
4895            }
4896            didSomething = true;
4897        }
4898
4899        if (name == null) {
4900            // Remove all sticky broadcasts from this user.
4901            mStickyBroadcasts.remove(userId);
4902        }
4903
4904        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4905        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4906                userId, providers)) {
4907            if (!doit) {
4908                return true;
4909            }
4910            didSomething = true;
4911        }
4912        N = providers.size();
4913        for (i=0; i<N; i++) {
4914            removeDyingProviderLocked(null, providers.get(i), true);
4915        }
4916
4917        // Remove transient permissions granted from/to this package/user
4918        removeUriPermissionsForPackageLocked(name, userId, false);
4919
4920        if (name == null || uninstalling) {
4921            // Remove pending intents.  For now we only do this when force
4922            // stopping users, because we have some problems when doing this
4923            // for packages -- app widgets are not currently cleaned up for
4924            // such packages, so they can be left with bad pending intents.
4925            if (mIntentSenderRecords.size() > 0) {
4926                Iterator<WeakReference<PendingIntentRecord>> it
4927                        = mIntentSenderRecords.values().iterator();
4928                while (it.hasNext()) {
4929                    WeakReference<PendingIntentRecord> wpir = it.next();
4930                    if (wpir == null) {
4931                        it.remove();
4932                        continue;
4933                    }
4934                    PendingIntentRecord pir = wpir.get();
4935                    if (pir == null) {
4936                        it.remove();
4937                        continue;
4938                    }
4939                    if (name == null) {
4940                        // Stopping user, remove all objects for the user.
4941                        if (pir.key.userId != userId) {
4942                            // Not the same user, skip it.
4943                            continue;
4944                        }
4945                    } else {
4946                        if (UserHandle.getAppId(pir.uid) != appId) {
4947                            // Different app id, skip it.
4948                            continue;
4949                        }
4950                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4951                            // Different user, skip it.
4952                            continue;
4953                        }
4954                        if (!pir.key.packageName.equals(name)) {
4955                            // Different package, skip it.
4956                            continue;
4957                        }
4958                    }
4959                    if (!doit) {
4960                        return true;
4961                    }
4962                    didSomething = true;
4963                    it.remove();
4964                    pir.canceled = true;
4965                    if (pir.key.activity != null) {
4966                        pir.key.activity.pendingResults.remove(pir.ref);
4967                    }
4968                }
4969            }
4970        }
4971
4972        if (doit) {
4973            if (purgeCache && name != null) {
4974                AttributeCache ac = AttributeCache.instance();
4975                if (ac != null) {
4976                    ac.removePackage(name);
4977                }
4978            }
4979            if (mBooted) {
4980                mStackSupervisor.resumeTopActivitiesLocked();
4981                mStackSupervisor.scheduleIdleLocked();
4982            }
4983        }
4984
4985        return didSomething;
4986    }
4987
4988    private final boolean removeProcessLocked(ProcessRecord app,
4989            boolean callerWillRestart, boolean allowRestart, String reason) {
4990        final String name = app.processName;
4991        final int uid = app.uid;
4992        if (DEBUG_PROCESSES) Slog.d(
4993            TAG, "Force removing proc " + app.toShortString() + " (" + name
4994            + "/" + uid + ")");
4995
4996        mProcessNames.remove(name, uid);
4997        mIsolatedProcesses.remove(app.uid);
4998        if (mHeavyWeightProcess == app) {
4999            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5000                    mHeavyWeightProcess.userId, 0));
5001            mHeavyWeightProcess = null;
5002        }
5003        boolean needRestart = false;
5004        if (app.pid > 0 && app.pid != MY_PID) {
5005            int pid = app.pid;
5006            synchronized (mPidsSelfLocked) {
5007                mPidsSelfLocked.remove(pid);
5008                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5009            }
5010            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5011                    app.processName, app.info.uid);
5012            if (app.isolated) {
5013                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5014            }
5015            killUnneededProcessLocked(app, reason);
5016            handleAppDiedLocked(app, true, allowRestart);
5017            removeLruProcessLocked(app);
5018
5019            if (app.persistent && !app.isolated) {
5020                if (!callerWillRestart) {
5021                    addAppLocked(app.info, false);
5022                } else {
5023                    needRestart = true;
5024                }
5025            }
5026        } else {
5027            mRemovedProcesses.add(app);
5028        }
5029
5030        return needRestart;
5031    }
5032
5033    private final void processStartTimedOutLocked(ProcessRecord app) {
5034        final int pid = app.pid;
5035        boolean gone = false;
5036        synchronized (mPidsSelfLocked) {
5037            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5038            if (knownApp != null && knownApp.thread == null) {
5039                mPidsSelfLocked.remove(pid);
5040                gone = true;
5041            }
5042        }
5043
5044        if (gone) {
5045            Slog.w(TAG, "Process " + app + " failed to attach");
5046            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5047                    pid, app.uid, app.processName);
5048            mProcessNames.remove(app.processName, app.uid);
5049            mIsolatedProcesses.remove(app.uid);
5050            if (mHeavyWeightProcess == app) {
5051                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5052                        mHeavyWeightProcess.userId, 0));
5053                mHeavyWeightProcess = null;
5054            }
5055            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5056                    app.processName, app.info.uid);
5057            if (app.isolated) {
5058                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5059            }
5060            // Take care of any launching providers waiting for this process.
5061            checkAppInLaunchingProvidersLocked(app, true);
5062            // Take care of any services that are waiting for the process.
5063            mServices.processStartTimedOutLocked(app);
5064            killUnneededProcessLocked(app, "start timeout");
5065            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5066                Slog.w(TAG, "Unattached app died before backup, skipping");
5067                try {
5068                    IBackupManager bm = IBackupManager.Stub.asInterface(
5069                            ServiceManager.getService(Context.BACKUP_SERVICE));
5070                    bm.agentDisconnected(app.info.packageName);
5071                } catch (RemoteException e) {
5072                    // Can't happen; the backup manager is local
5073                }
5074            }
5075            if (isPendingBroadcastProcessLocked(pid)) {
5076                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5077                skipPendingBroadcastLocked(pid);
5078            }
5079        } else {
5080            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5081        }
5082    }
5083
5084    private final boolean attachApplicationLocked(IApplicationThread thread,
5085            int pid) {
5086
5087        // Find the application record that is being attached...  either via
5088        // the pid if we are running in multiple processes, or just pull the
5089        // next app record if we are emulating process with anonymous threads.
5090        ProcessRecord app;
5091        if (pid != MY_PID && pid >= 0) {
5092            synchronized (mPidsSelfLocked) {
5093                app = mPidsSelfLocked.get(pid);
5094            }
5095        } else {
5096            app = null;
5097        }
5098
5099        if (app == null) {
5100            Slog.w(TAG, "No pending application record for pid " + pid
5101                    + " (IApplicationThread " + thread + "); dropping process");
5102            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5103            if (pid > 0 && pid != MY_PID) {
5104                Process.killProcessQuiet(pid);
5105            } else {
5106                try {
5107                    thread.scheduleExit();
5108                } catch (Exception e) {
5109                    // Ignore exceptions.
5110                }
5111            }
5112            return false;
5113        }
5114
5115        // If this application record is still attached to a previous
5116        // process, clean it up now.
5117        if (app.thread != null) {
5118            handleAppDiedLocked(app, true, true);
5119        }
5120
5121        // Tell the process all about itself.
5122
5123        if (localLOGV) Slog.v(
5124                TAG, "Binding process pid " + pid + " to record " + app);
5125
5126        final String processName = app.processName;
5127        try {
5128            AppDeathRecipient adr = new AppDeathRecipient(
5129                    app, pid, thread);
5130            thread.asBinder().linkToDeath(adr, 0);
5131            app.deathRecipient = adr;
5132        } catch (RemoteException e) {
5133            app.resetPackageList(mProcessStats);
5134            startProcessLocked(app, "link fail", processName);
5135            return false;
5136        }
5137
5138        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5139
5140        app.makeActive(thread, mProcessStats);
5141        app.curAdj = app.setAdj = -100;
5142        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5143        app.forcingToForeground = null;
5144        updateProcessForegroundLocked(app, false, false);
5145        app.hasShownUi = false;
5146        app.debugging = false;
5147        app.cached = false;
5148
5149        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5150
5151        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5152        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5153
5154        if (!normalMode) {
5155            Slog.i(TAG, "Launching preboot mode app: " + app);
5156        }
5157
5158        if (localLOGV) Slog.v(
5159            TAG, "New app record " + app
5160            + " thread=" + thread.asBinder() + " pid=" + pid);
5161        try {
5162            int testMode = IApplicationThread.DEBUG_OFF;
5163            if (mDebugApp != null && mDebugApp.equals(processName)) {
5164                testMode = mWaitForDebugger
5165                    ? IApplicationThread.DEBUG_WAIT
5166                    : IApplicationThread.DEBUG_ON;
5167                app.debugging = true;
5168                if (mDebugTransient) {
5169                    mDebugApp = mOrigDebugApp;
5170                    mWaitForDebugger = mOrigWaitForDebugger;
5171                }
5172            }
5173            String profileFile = app.instrumentationProfileFile;
5174            ParcelFileDescriptor profileFd = null;
5175            boolean profileAutoStop = false;
5176            if (mProfileApp != null && mProfileApp.equals(processName)) {
5177                mProfileProc = app;
5178                profileFile = mProfileFile;
5179                profileFd = mProfileFd;
5180                profileAutoStop = mAutoStopProfiler;
5181            }
5182            boolean enableOpenGlTrace = false;
5183            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5184                enableOpenGlTrace = true;
5185                mOpenGlTraceApp = null;
5186            }
5187
5188            // If the app is being launched for restore or full backup, set it up specially
5189            boolean isRestrictedBackupMode = false;
5190            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5191                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5192                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5193                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5194            }
5195
5196            ensurePackageDexOpt(app.instrumentationInfo != null
5197                    ? app.instrumentationInfo.packageName
5198                    : app.info.packageName);
5199            if (app.instrumentationClass != null) {
5200                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5201            }
5202            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5203                    + processName + " with config " + mConfiguration);
5204            ApplicationInfo appInfo = app.instrumentationInfo != null
5205                    ? app.instrumentationInfo : app.info;
5206            app.compat = compatibilityInfoForPackageLocked(appInfo);
5207            if (profileFd != null) {
5208                profileFd = profileFd.dup();
5209            }
5210            thread.bindApplication(processName, appInfo, providers,
5211                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5212                    app.instrumentationArguments, app.instrumentationWatcher,
5213                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5214                    isRestrictedBackupMode || !normalMode, app.persistent,
5215                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5216                    mCoreSettingsObserver.getCoreSettingsLocked());
5217            updateLruProcessLocked(app, false, null);
5218            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5219        } catch (Exception e) {
5220            // todo: Yikes!  What should we do?  For now we will try to
5221            // start another process, but that could easily get us in
5222            // an infinite loop of restarting processes...
5223            Slog.w(TAG, "Exception thrown during bind!", e);
5224
5225            app.resetPackageList(mProcessStats);
5226            app.unlinkDeathRecipient();
5227            startProcessLocked(app, "bind fail", processName);
5228            return false;
5229        }
5230
5231        // Remove this record from the list of starting applications.
5232        mPersistentStartingProcesses.remove(app);
5233        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5234                "Attach application locked removing on hold: " + app);
5235        mProcessesOnHold.remove(app);
5236
5237        boolean badApp = false;
5238        boolean didSomething = false;
5239
5240        // See if the top visible activity is waiting to run in this process...
5241        if (normalMode) {
5242            try {
5243                if (mStackSupervisor.attachApplicationLocked(app)) {
5244                    didSomething = true;
5245                }
5246            } catch (Exception e) {
5247                badApp = true;
5248            }
5249        }
5250
5251        // Find any services that should be running in this process...
5252        if (!badApp) {
5253            try {
5254                didSomething |= mServices.attachApplicationLocked(app, processName);
5255            } catch (Exception e) {
5256                badApp = true;
5257            }
5258        }
5259
5260        // Check if a next-broadcast receiver is in this process...
5261        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5262            try {
5263                didSomething |= sendPendingBroadcastsLocked(app);
5264            } catch (Exception e) {
5265                // If the app died trying to launch the receiver we declare it 'bad'
5266                badApp = true;
5267            }
5268        }
5269
5270        // Check whether the next backup agent is in this process...
5271        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5272            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5273            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5274            try {
5275                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5276                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5277                        mBackupTarget.backupMode);
5278            } catch (Exception e) {
5279                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5280                e.printStackTrace();
5281            }
5282        }
5283
5284        if (badApp) {
5285            // todo: Also need to kill application to deal with all
5286            // kinds of exceptions.
5287            handleAppDiedLocked(app, false, true);
5288            return false;
5289        }
5290
5291        if (!didSomething) {
5292            updateOomAdjLocked();
5293        }
5294
5295        return true;
5296    }
5297
5298    @Override
5299    public final void attachApplication(IApplicationThread thread) {
5300        synchronized (this) {
5301            int callingPid = Binder.getCallingPid();
5302            final long origId = Binder.clearCallingIdentity();
5303            attachApplicationLocked(thread, callingPid);
5304            Binder.restoreCallingIdentity(origId);
5305        }
5306    }
5307
5308    @Override
5309    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5310        final long origId = Binder.clearCallingIdentity();
5311        synchronized (this) {
5312            ActivityStack stack = ActivityRecord.getStackLocked(token);
5313            if (stack != null) {
5314                ActivityRecord r =
5315                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5316                if (stopProfiling) {
5317                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5318                        try {
5319                            mProfileFd.close();
5320                        } catch (IOException e) {
5321                        }
5322                        clearProfilerLocked();
5323                    }
5324                }
5325            }
5326        }
5327        Binder.restoreCallingIdentity(origId);
5328    }
5329
5330    void enableScreenAfterBoot() {
5331        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5332                SystemClock.uptimeMillis());
5333        mWindowManager.enableScreenAfterBoot();
5334
5335        synchronized (this) {
5336            updateEventDispatchingLocked();
5337        }
5338    }
5339
5340    @Override
5341    public void showBootMessage(final CharSequence msg, final boolean always) {
5342        enforceNotIsolatedCaller("showBootMessage");
5343        mWindowManager.showBootMessage(msg, always);
5344    }
5345
5346    @Override
5347    public void dismissKeyguardOnNextActivity() {
5348        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5349        final long token = Binder.clearCallingIdentity();
5350        try {
5351            synchronized (this) {
5352                if (DEBUG_LOCKSCREEN) logLockScreen("");
5353                if (mLockScreenShown) {
5354                    mLockScreenShown = false;
5355                    comeOutOfSleepIfNeededLocked();
5356                }
5357                mStackSupervisor.setDismissKeyguard(true);
5358            }
5359        } finally {
5360            Binder.restoreCallingIdentity(token);
5361        }
5362    }
5363
5364    final void finishBooting() {
5365        // Register receivers to handle package update events
5366        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5367
5368        synchronized (this) {
5369            // Ensure that any processes we had put on hold are now started
5370            // up.
5371            final int NP = mProcessesOnHold.size();
5372            if (NP > 0) {
5373                ArrayList<ProcessRecord> procs =
5374                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5375                for (int ip=0; ip<NP; ip++) {
5376                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5377                            + procs.get(ip));
5378                    startProcessLocked(procs.get(ip), "on-hold", null);
5379                }
5380            }
5381
5382            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5383                // Start looking for apps that are abusing wake locks.
5384                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5385                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5386                // Tell anyone interested that we are done booting!
5387                SystemProperties.set("sys.boot_completed", "1");
5388                SystemProperties.set("dev.bootcomplete", "1");
5389                for (int i=0; i<mStartedUsers.size(); i++) {
5390                    UserStartedState uss = mStartedUsers.valueAt(i);
5391                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5392                        uss.mState = UserStartedState.STATE_RUNNING;
5393                        final int userId = mStartedUsers.keyAt(i);
5394                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5395                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5396                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5397                        broadcastIntentLocked(null, null, intent, null,
5398                                new IIntentReceiver.Stub() {
5399                                    @Override
5400                                    public void performReceive(Intent intent, int resultCode,
5401                                            String data, Bundle extras, boolean ordered,
5402                                            boolean sticky, int sendingUser) {
5403                                        synchronized (ActivityManagerService.this) {
5404                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5405                                                    true, false);
5406                                        }
5407                                    }
5408                                },
5409                                0, null, null,
5410                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5411                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5412                                userId);
5413                    }
5414                }
5415                scheduleStartProfilesLocked();
5416            }
5417        }
5418    }
5419
5420    final void ensureBootCompleted() {
5421        boolean booting;
5422        boolean enableScreen;
5423        synchronized (this) {
5424            booting = mBooting;
5425            mBooting = false;
5426            enableScreen = !mBooted;
5427            mBooted = true;
5428        }
5429
5430        if (booting) {
5431            finishBooting();
5432        }
5433
5434        if (enableScreen) {
5435            enableScreenAfterBoot();
5436        }
5437    }
5438
5439    @Override
5440    public final void activityResumed(IBinder token) {
5441        final long origId = Binder.clearCallingIdentity();
5442        synchronized(this) {
5443            ActivityStack stack = ActivityRecord.getStackLocked(token);
5444            if (stack != null) {
5445                ActivityRecord.activityResumedLocked(token);
5446            }
5447        }
5448        Binder.restoreCallingIdentity(origId);
5449    }
5450
5451    @Override
5452    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5453        final long origId = Binder.clearCallingIdentity();
5454        synchronized(this) {
5455            ActivityStack stack = ActivityRecord.getStackLocked(token);
5456            if (stack != null) {
5457                stack.activityPausedLocked(token, false, persistentState);
5458            }
5459        }
5460        Binder.restoreCallingIdentity(origId);
5461    }
5462
5463    @Override
5464    public final void activityStopped(IBinder token, Bundle icicle,
5465            PersistableBundle persistentState, CharSequence description) {
5466        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5467
5468        // Refuse possible leaked file descriptors
5469        if (icicle != null && icicle.hasFileDescriptors()) {
5470            throw new IllegalArgumentException("File descriptors passed in Bundle");
5471        }
5472
5473        final long origId = Binder.clearCallingIdentity();
5474
5475        synchronized (this) {
5476            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5477            if (r != null) {
5478                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5479            }
5480        }
5481
5482        trimApplications();
5483
5484        Binder.restoreCallingIdentity(origId);
5485    }
5486
5487    @Override
5488    public final void activityDestroyed(IBinder token) {
5489        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5490        synchronized (this) {
5491            ActivityStack stack = ActivityRecord.getStackLocked(token);
5492            if (stack != null) {
5493                stack.activityDestroyedLocked(token);
5494            }
5495        }
5496    }
5497
5498    @Override
5499    public String getCallingPackage(IBinder token) {
5500        synchronized (this) {
5501            ActivityRecord r = getCallingRecordLocked(token);
5502            return r != null ? r.info.packageName : null;
5503        }
5504    }
5505
5506    @Override
5507    public ComponentName getCallingActivity(IBinder token) {
5508        synchronized (this) {
5509            ActivityRecord r = getCallingRecordLocked(token);
5510            return r != null ? r.intent.getComponent() : null;
5511        }
5512    }
5513
5514    private ActivityRecord getCallingRecordLocked(IBinder token) {
5515        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5516        if (r == null) {
5517            return null;
5518        }
5519        return r.resultTo;
5520    }
5521
5522    @Override
5523    public ComponentName getActivityClassForToken(IBinder token) {
5524        synchronized(this) {
5525            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5526            if (r == null) {
5527                return null;
5528            }
5529            return r.intent.getComponent();
5530        }
5531    }
5532
5533    @Override
5534    public String getPackageForToken(IBinder token) {
5535        synchronized(this) {
5536            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5537            if (r == null) {
5538                return null;
5539            }
5540            return r.packageName;
5541        }
5542    }
5543
5544    @Override
5545    public IIntentSender getIntentSender(int type,
5546            String packageName, IBinder token, String resultWho,
5547            int requestCode, Intent[] intents, String[] resolvedTypes,
5548            int flags, Bundle options, int userId) {
5549        enforceNotIsolatedCaller("getIntentSender");
5550        // Refuse possible leaked file descriptors
5551        if (intents != null) {
5552            if (intents.length < 1) {
5553                throw new IllegalArgumentException("Intents array length must be >= 1");
5554            }
5555            for (int i=0; i<intents.length; i++) {
5556                Intent intent = intents[i];
5557                if (intent != null) {
5558                    if (intent.hasFileDescriptors()) {
5559                        throw new IllegalArgumentException("File descriptors passed in Intent");
5560                    }
5561                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5562                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5563                        throw new IllegalArgumentException(
5564                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5565                    }
5566                    intents[i] = new Intent(intent);
5567                }
5568            }
5569            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5570                throw new IllegalArgumentException(
5571                        "Intent array length does not match resolvedTypes length");
5572            }
5573        }
5574        if (options != null) {
5575            if (options.hasFileDescriptors()) {
5576                throw new IllegalArgumentException("File descriptors passed in options");
5577            }
5578        }
5579
5580        synchronized(this) {
5581            int callingUid = Binder.getCallingUid();
5582            int origUserId = userId;
5583            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5584                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5585                    "getIntentSender", null);
5586            if (origUserId == UserHandle.USER_CURRENT) {
5587                // We don't want to evaluate this until the pending intent is
5588                // actually executed.  However, we do want to always do the
5589                // security checking for it above.
5590                userId = UserHandle.USER_CURRENT;
5591            }
5592            try {
5593                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5594                    int uid = AppGlobals.getPackageManager()
5595                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5596                    if (!UserHandle.isSameApp(callingUid, uid)) {
5597                        String msg = "Permission Denial: getIntentSender() from pid="
5598                            + Binder.getCallingPid()
5599                            + ", uid=" + Binder.getCallingUid()
5600                            + ", (need uid=" + uid + ")"
5601                            + " is not allowed to send as package " + packageName;
5602                        Slog.w(TAG, msg);
5603                        throw new SecurityException(msg);
5604                    }
5605                }
5606
5607                return getIntentSenderLocked(type, packageName, callingUid, userId,
5608                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5609
5610            } catch (RemoteException e) {
5611                throw new SecurityException(e);
5612            }
5613        }
5614    }
5615
5616    IIntentSender getIntentSenderLocked(int type, String packageName,
5617            int callingUid, int userId, IBinder token, String resultWho,
5618            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5619            Bundle options) {
5620        if (DEBUG_MU)
5621            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5622        ActivityRecord activity = null;
5623        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5624            activity = ActivityRecord.isInStackLocked(token);
5625            if (activity == null) {
5626                return null;
5627            }
5628            if (activity.finishing) {
5629                return null;
5630            }
5631        }
5632
5633        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5634        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5635        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5636        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5637                |PendingIntent.FLAG_UPDATE_CURRENT);
5638
5639        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5640                type, packageName, activity, resultWho,
5641                requestCode, intents, resolvedTypes, flags, options, userId);
5642        WeakReference<PendingIntentRecord> ref;
5643        ref = mIntentSenderRecords.get(key);
5644        PendingIntentRecord rec = ref != null ? ref.get() : null;
5645        if (rec != null) {
5646            if (!cancelCurrent) {
5647                if (updateCurrent) {
5648                    if (rec.key.requestIntent != null) {
5649                        rec.key.requestIntent.replaceExtras(intents != null ?
5650                                intents[intents.length - 1] : null);
5651                    }
5652                    if (intents != null) {
5653                        intents[intents.length-1] = rec.key.requestIntent;
5654                        rec.key.allIntents = intents;
5655                        rec.key.allResolvedTypes = resolvedTypes;
5656                    } else {
5657                        rec.key.allIntents = null;
5658                        rec.key.allResolvedTypes = null;
5659                    }
5660                }
5661                return rec;
5662            }
5663            rec.canceled = true;
5664            mIntentSenderRecords.remove(key);
5665        }
5666        if (noCreate) {
5667            return rec;
5668        }
5669        rec = new PendingIntentRecord(this, key, callingUid);
5670        mIntentSenderRecords.put(key, rec.ref);
5671        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5672            if (activity.pendingResults == null) {
5673                activity.pendingResults
5674                        = new HashSet<WeakReference<PendingIntentRecord>>();
5675            }
5676            activity.pendingResults.add(rec.ref);
5677        }
5678        return rec;
5679    }
5680
5681    @Override
5682    public void cancelIntentSender(IIntentSender sender) {
5683        if (!(sender instanceof PendingIntentRecord)) {
5684            return;
5685        }
5686        synchronized(this) {
5687            PendingIntentRecord rec = (PendingIntentRecord)sender;
5688            try {
5689                int uid = AppGlobals.getPackageManager()
5690                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5691                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5692                    String msg = "Permission Denial: cancelIntentSender() from pid="
5693                        + Binder.getCallingPid()
5694                        + ", uid=" + Binder.getCallingUid()
5695                        + " is not allowed to cancel packges "
5696                        + rec.key.packageName;
5697                    Slog.w(TAG, msg);
5698                    throw new SecurityException(msg);
5699                }
5700            } catch (RemoteException e) {
5701                throw new SecurityException(e);
5702            }
5703            cancelIntentSenderLocked(rec, true);
5704        }
5705    }
5706
5707    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5708        rec.canceled = true;
5709        mIntentSenderRecords.remove(rec.key);
5710        if (cleanActivity && rec.key.activity != null) {
5711            rec.key.activity.pendingResults.remove(rec.ref);
5712        }
5713    }
5714
5715    @Override
5716    public String getPackageForIntentSender(IIntentSender pendingResult) {
5717        if (!(pendingResult instanceof PendingIntentRecord)) {
5718            return null;
5719        }
5720        try {
5721            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5722            return res.key.packageName;
5723        } catch (ClassCastException e) {
5724        }
5725        return null;
5726    }
5727
5728    @Override
5729    public int getUidForIntentSender(IIntentSender sender) {
5730        if (sender instanceof PendingIntentRecord) {
5731            try {
5732                PendingIntentRecord res = (PendingIntentRecord)sender;
5733                return res.uid;
5734            } catch (ClassCastException e) {
5735            }
5736        }
5737        return -1;
5738    }
5739
5740    @Override
5741    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5742        if (!(pendingResult instanceof PendingIntentRecord)) {
5743            return false;
5744        }
5745        try {
5746            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5747            if (res.key.allIntents == null) {
5748                return false;
5749            }
5750            for (int i=0; i<res.key.allIntents.length; i++) {
5751                Intent intent = res.key.allIntents[i];
5752                if (intent.getPackage() != null && intent.getComponent() != null) {
5753                    return false;
5754                }
5755            }
5756            return true;
5757        } catch (ClassCastException e) {
5758        }
5759        return false;
5760    }
5761
5762    @Override
5763    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5764        if (!(pendingResult instanceof PendingIntentRecord)) {
5765            return false;
5766        }
5767        try {
5768            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5769            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5770                return true;
5771            }
5772            return false;
5773        } catch (ClassCastException e) {
5774        }
5775        return false;
5776    }
5777
5778    @Override
5779    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5780        if (!(pendingResult instanceof PendingIntentRecord)) {
5781            return null;
5782        }
5783        try {
5784            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5785            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5786        } catch (ClassCastException e) {
5787        }
5788        return null;
5789    }
5790
5791    @Override
5792    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5793        if (!(pendingResult instanceof PendingIntentRecord)) {
5794            return null;
5795        }
5796        try {
5797            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5798            Intent intent = res.key.requestIntent;
5799            if (intent != null) {
5800                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5801                        || res.lastTagPrefix.equals(prefix))) {
5802                    return res.lastTag;
5803                }
5804                res.lastTagPrefix = prefix;
5805                StringBuilder sb = new StringBuilder(128);
5806                if (prefix != null) {
5807                    sb.append(prefix);
5808                }
5809                if (intent.getAction() != null) {
5810                    sb.append(intent.getAction());
5811                } else if (intent.getComponent() != null) {
5812                    intent.getComponent().appendShortString(sb);
5813                } else {
5814                    sb.append("?");
5815                }
5816                return res.lastTag = sb.toString();
5817            }
5818        } catch (ClassCastException e) {
5819        }
5820        return null;
5821    }
5822
5823    @Override
5824    public void setProcessLimit(int max) {
5825        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5826                "setProcessLimit()");
5827        synchronized (this) {
5828            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5829            mProcessLimitOverride = max;
5830        }
5831        trimApplications();
5832    }
5833
5834    @Override
5835    public int getProcessLimit() {
5836        synchronized (this) {
5837            return mProcessLimitOverride;
5838        }
5839    }
5840
5841    void foregroundTokenDied(ForegroundToken token) {
5842        synchronized (ActivityManagerService.this) {
5843            synchronized (mPidsSelfLocked) {
5844                ForegroundToken cur
5845                    = mForegroundProcesses.get(token.pid);
5846                if (cur != token) {
5847                    return;
5848                }
5849                mForegroundProcesses.remove(token.pid);
5850                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5851                if (pr == null) {
5852                    return;
5853                }
5854                pr.forcingToForeground = null;
5855                updateProcessForegroundLocked(pr, false, false);
5856            }
5857            updateOomAdjLocked();
5858        }
5859    }
5860
5861    @Override
5862    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5863        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5864                "setProcessForeground()");
5865        synchronized(this) {
5866            boolean changed = false;
5867
5868            synchronized (mPidsSelfLocked) {
5869                ProcessRecord pr = mPidsSelfLocked.get(pid);
5870                if (pr == null && isForeground) {
5871                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5872                    return;
5873                }
5874                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5875                if (oldToken != null) {
5876                    oldToken.token.unlinkToDeath(oldToken, 0);
5877                    mForegroundProcesses.remove(pid);
5878                    if (pr != null) {
5879                        pr.forcingToForeground = null;
5880                    }
5881                    changed = true;
5882                }
5883                if (isForeground && token != null) {
5884                    ForegroundToken newToken = new ForegroundToken() {
5885                        @Override
5886                        public void binderDied() {
5887                            foregroundTokenDied(this);
5888                        }
5889                    };
5890                    newToken.pid = pid;
5891                    newToken.token = token;
5892                    try {
5893                        token.linkToDeath(newToken, 0);
5894                        mForegroundProcesses.put(pid, newToken);
5895                        pr.forcingToForeground = token;
5896                        changed = true;
5897                    } catch (RemoteException e) {
5898                        // If the process died while doing this, we will later
5899                        // do the cleanup with the process death link.
5900                    }
5901                }
5902            }
5903
5904            if (changed) {
5905                updateOomAdjLocked();
5906            }
5907        }
5908    }
5909
5910    // =========================================================
5911    // PERMISSIONS
5912    // =========================================================
5913
5914    static class PermissionController extends IPermissionController.Stub {
5915        ActivityManagerService mActivityManagerService;
5916        PermissionController(ActivityManagerService activityManagerService) {
5917            mActivityManagerService = activityManagerService;
5918        }
5919
5920        @Override
5921        public boolean checkPermission(String permission, int pid, int uid) {
5922            return mActivityManagerService.checkPermission(permission, pid,
5923                    uid) == PackageManager.PERMISSION_GRANTED;
5924        }
5925    }
5926
5927    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5928        @Override
5929        public int checkComponentPermission(String permission, int pid, int uid,
5930                int owningUid, boolean exported) {
5931            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5932                    owningUid, exported);
5933        }
5934
5935        @Override
5936        public Object getAMSLock() {
5937            return ActivityManagerService.this;
5938        }
5939    }
5940
5941    /**
5942     * This can be called with or without the global lock held.
5943     */
5944    int checkComponentPermission(String permission, int pid, int uid,
5945            int owningUid, boolean exported) {
5946        // We might be performing an operation on behalf of an indirect binder
5947        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5948        // client identity accordingly before proceeding.
5949        Identity tlsIdentity = sCallerIdentity.get();
5950        if (tlsIdentity != null) {
5951            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5952                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5953            uid = tlsIdentity.uid;
5954            pid = tlsIdentity.pid;
5955        }
5956
5957        if (pid == MY_PID) {
5958            return PackageManager.PERMISSION_GRANTED;
5959        }
5960
5961        return ActivityManager.checkComponentPermission(permission, uid,
5962                owningUid, exported);
5963    }
5964
5965    /**
5966     * As the only public entry point for permissions checking, this method
5967     * can enforce the semantic that requesting a check on a null global
5968     * permission is automatically denied.  (Internally a null permission
5969     * string is used when calling {@link #checkComponentPermission} in cases
5970     * when only uid-based security is needed.)
5971     *
5972     * This can be called with or without the global lock held.
5973     */
5974    @Override
5975    public int checkPermission(String permission, int pid, int uid) {
5976        if (permission == null) {
5977            return PackageManager.PERMISSION_DENIED;
5978        }
5979        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5980    }
5981
5982    /**
5983     * Binder IPC calls go through the public entry point.
5984     * This can be called with or without the global lock held.
5985     */
5986    int checkCallingPermission(String permission) {
5987        return checkPermission(permission,
5988                Binder.getCallingPid(),
5989                UserHandle.getAppId(Binder.getCallingUid()));
5990    }
5991
5992    /**
5993     * This can be called with or without the global lock held.
5994     */
5995    void enforceCallingPermission(String permission, String func) {
5996        if (checkCallingPermission(permission)
5997                == PackageManager.PERMISSION_GRANTED) {
5998            return;
5999        }
6000
6001        String msg = "Permission Denial: " + func + " from pid="
6002                + Binder.getCallingPid()
6003                + ", uid=" + Binder.getCallingUid()
6004                + " requires " + permission;
6005        Slog.w(TAG, msg);
6006        throw new SecurityException(msg);
6007    }
6008
6009    /**
6010     * Determine if UID is holding permissions required to access {@link Uri} in
6011     * the given {@link ProviderInfo}. Final permission checking is always done
6012     * in {@link ContentProvider}.
6013     */
6014    private final boolean checkHoldingPermissionsLocked(
6015            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6016        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6017                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6018
6019        if (pi.applicationInfo.uid == uid) {
6020            return true;
6021        } else if (!pi.exported) {
6022            return false;
6023        }
6024
6025        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6026        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6027        try {
6028            // check if target holds top-level <provider> permissions
6029            if (!readMet && pi.readPermission != null
6030                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6031                readMet = true;
6032            }
6033            if (!writeMet && pi.writePermission != null
6034                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6035                writeMet = true;
6036            }
6037
6038            // track if unprotected read/write is allowed; any denied
6039            // <path-permission> below removes this ability
6040            boolean allowDefaultRead = pi.readPermission == null;
6041            boolean allowDefaultWrite = pi.writePermission == null;
6042
6043            // check if target holds any <path-permission> that match uri
6044            final PathPermission[] pps = pi.pathPermissions;
6045            if (pps != null) {
6046                final String path = grantUri.uri.getPath();
6047                int i = pps.length;
6048                while (i > 0 && (!readMet || !writeMet)) {
6049                    i--;
6050                    PathPermission pp = pps[i];
6051                    if (pp.match(path)) {
6052                        if (!readMet) {
6053                            final String pprperm = pp.getReadPermission();
6054                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6055                                    + pprperm + " for " + pp.getPath()
6056                                    + ": match=" + pp.match(path)
6057                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6058                            if (pprperm != null) {
6059                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
6060                                    readMet = true;
6061                                } else {
6062                                    allowDefaultRead = false;
6063                                }
6064                            }
6065                        }
6066                        if (!writeMet) {
6067                            final String ppwperm = pp.getWritePermission();
6068                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6069                                    + ppwperm + " for " + pp.getPath()
6070                                    + ": match=" + pp.match(path)
6071                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6072                            if (ppwperm != null) {
6073                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
6074                                    writeMet = true;
6075                                } else {
6076                                    allowDefaultWrite = false;
6077                                }
6078                            }
6079                        }
6080                    }
6081                }
6082            }
6083
6084            // grant unprotected <provider> read/write, if not blocked by
6085            // <path-permission> above
6086            if (allowDefaultRead) readMet = true;
6087            if (allowDefaultWrite) writeMet = true;
6088
6089        } catch (RemoteException e) {
6090            return false;
6091        }
6092
6093        return readMet && writeMet;
6094    }
6095
6096    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6097        ProviderInfo pi = null;
6098        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6099        if (cpr != null) {
6100            pi = cpr.info;
6101        } else {
6102            try {
6103                pi = AppGlobals.getPackageManager().resolveContentProvider(
6104                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6105            } catch (RemoteException ex) {
6106            }
6107        }
6108        return pi;
6109    }
6110
6111    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6112        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6113        if (targetUris != null) {
6114            return targetUris.get(grantUri);
6115        }
6116        return null;
6117    }
6118
6119    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6120            String targetPkg, int targetUid, GrantUri grantUri) {
6121        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6122        if (targetUris == null) {
6123            targetUris = Maps.newArrayMap();
6124            mGrantedUriPermissions.put(targetUid, targetUris);
6125        }
6126
6127        UriPermission perm = targetUris.get(grantUri);
6128        if (perm == null) {
6129            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6130            targetUris.put(grantUri, perm);
6131        }
6132
6133        return perm;
6134    }
6135
6136    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6137            final int modeFlags) {
6138        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6139        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6140                : UriPermission.STRENGTH_OWNED;
6141
6142        // Root gets to do everything.
6143        if (uid == 0) {
6144            return true;
6145        }
6146
6147        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6148        if (perms == null) return false;
6149
6150        // First look for exact match
6151        final UriPermission exactPerm = perms.get(grantUri);
6152        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6153            return true;
6154        }
6155
6156        // No exact match, look for prefixes
6157        final int N = perms.size();
6158        for (int i = 0; i < N; i++) {
6159            final UriPermission perm = perms.valueAt(i);
6160            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6161                    && perm.getStrength(modeFlags) >= minStrength) {
6162                return true;
6163            }
6164        }
6165
6166        return false;
6167    }
6168
6169    @Override
6170    public int checkUriPermission(Uri uri, int pid, int uid,
6171            final int modeFlags, int userId) {
6172        enforceNotIsolatedCaller("checkUriPermission");
6173
6174        // Another redirected-binder-call permissions check as in
6175        // {@link checkComponentPermission}.
6176        Identity tlsIdentity = sCallerIdentity.get();
6177        if (tlsIdentity != null) {
6178            uid = tlsIdentity.uid;
6179            pid = tlsIdentity.pid;
6180        }
6181
6182        // Our own process gets to do everything.
6183        if (pid == MY_PID) {
6184            return PackageManager.PERMISSION_GRANTED;
6185        }
6186        synchronized (this) {
6187            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6188                    ? PackageManager.PERMISSION_GRANTED
6189                    : PackageManager.PERMISSION_DENIED;
6190        }
6191    }
6192
6193    /**
6194     * Check if the targetPkg can be granted permission to access uri by
6195     * the callingUid using the given modeFlags.  Throws a security exception
6196     * if callingUid is not allowed to do this.  Returns the uid of the target
6197     * if the URI permission grant should be performed; returns -1 if it is not
6198     * needed (for example targetPkg already has permission to access the URI).
6199     * If you already know the uid of the target, you can supply it in
6200     * lastTargetUid else set that to -1.
6201     */
6202    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6203            final int modeFlags, int lastTargetUid) {
6204        if (!Intent.isAccessUriMode(modeFlags)) {
6205            return -1;
6206        }
6207
6208        if (targetPkg != null) {
6209            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6210                    "Checking grant " + targetPkg + " permission to " + grantUri);
6211        }
6212
6213        final IPackageManager pm = AppGlobals.getPackageManager();
6214
6215        // If this is not a content: uri, we can't do anything with it.
6216        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6217            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6218                    "Can't grant URI permission for non-content URI: " + grantUri);
6219            return -1;
6220        }
6221
6222        final String authority = grantUri.uri.getAuthority();
6223        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6224        if (pi == null) {
6225            Slog.w(TAG, "No content provider found for permission check: " +
6226                    grantUri.uri.toSafeString());
6227            return -1;
6228        }
6229
6230        int targetUid = lastTargetUid;
6231        if (targetUid < 0 && targetPkg != null) {
6232            try {
6233                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6234                if (targetUid < 0) {
6235                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6236                            "Can't grant URI permission no uid for: " + targetPkg);
6237                    return -1;
6238                }
6239            } catch (RemoteException ex) {
6240                return -1;
6241            }
6242        }
6243
6244        if (targetUid >= 0) {
6245            // First...  does the target actually need this permission?
6246            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6247                // No need to grant the target this permission.
6248                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6249                        "Target " + targetPkg + " already has full permission to " + grantUri);
6250                return -1;
6251            }
6252        } else {
6253            // First...  there is no target package, so can anyone access it?
6254            boolean allowed = pi.exported;
6255            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6256                if (pi.readPermission != null) {
6257                    allowed = false;
6258                }
6259            }
6260            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6261                if (pi.writePermission != null) {
6262                    allowed = false;
6263                }
6264            }
6265            if (allowed) {
6266                return -1;
6267            }
6268        }
6269
6270        // Second...  is the provider allowing granting of URI permissions?
6271        if (!pi.grantUriPermissions) {
6272            throw new SecurityException("Provider " + pi.packageName
6273                    + "/" + pi.name
6274                    + " does not allow granting of Uri permissions (uri "
6275                    + grantUri + ")");
6276        }
6277        if (pi.uriPermissionPatterns != null) {
6278            final int N = pi.uriPermissionPatterns.length;
6279            boolean allowed = false;
6280            for (int i=0; i<N; i++) {
6281                if (pi.uriPermissionPatterns[i] != null
6282                        && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6283                    allowed = true;
6284                    break;
6285                }
6286            }
6287            if (!allowed) {
6288                throw new SecurityException("Provider " + pi.packageName
6289                        + "/" + pi.name
6290                        + " does not allow granting of permission to path of Uri "
6291                        + grantUri);
6292            }
6293        }
6294
6295        // Third...  does the caller itself have permission to access
6296        // this uri?
6297        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6298            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6299                // Require they hold a strong enough Uri permission
6300                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6301                    throw new SecurityException("Uid " + callingUid
6302                            + " does not have permission to uri " + grantUri);
6303                }
6304            }
6305        }
6306        return targetUid;
6307    }
6308
6309    @Override
6310    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6311            final int modeFlags, int userId) {
6312        enforceNotIsolatedCaller("checkGrantUriPermission");
6313        synchronized(this) {
6314            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6315                    new GrantUri(userId, uri, false), modeFlags, -1);
6316        }
6317    }
6318
6319    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6320            final int modeFlags, UriPermissionOwner owner) {
6321        if (!Intent.isAccessUriMode(modeFlags)) {
6322            return;
6323        }
6324
6325        // So here we are: the caller has the assumed permission
6326        // to the uri, and the target doesn't.  Let's now give this to
6327        // the target.
6328
6329        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6330                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6331
6332        final String authority = grantUri.uri.getAuthority();
6333        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6334        if (pi == null) {
6335            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6336            return;
6337        }
6338
6339        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6340            grantUri.prefix = true;
6341        }
6342        final UriPermission perm = findOrCreateUriPermissionLocked(
6343                pi.packageName, targetPkg, targetUid, grantUri);
6344        perm.grantModes(modeFlags, owner);
6345    }
6346
6347    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6348            final int modeFlags, UriPermissionOwner owner) {
6349        if (targetPkg == null) {
6350            throw new NullPointerException("targetPkg");
6351        }
6352
6353        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6354                -1);
6355        if (targetUid < 0) {
6356            return;
6357        }
6358
6359        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6360                owner);
6361    }
6362
6363    static class NeededUriGrants extends ArrayList<GrantUri> {
6364        final String targetPkg;
6365        final int targetUid;
6366        final int flags;
6367
6368        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6369            this.targetPkg = targetPkg;
6370            this.targetUid = targetUid;
6371            this.flags = flags;
6372        }
6373    }
6374
6375    /**
6376     * Like checkGrantUriPermissionLocked, but takes an Intent.
6377     */
6378    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6379            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6380        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6381                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6382                + " clip=" + (intent != null ? intent.getClipData() : null)
6383                + " from " + intent + "; flags=0x"
6384                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6385
6386        if (targetPkg == null) {
6387            throw new NullPointerException("targetPkg");
6388        }
6389
6390        if (intent == null) {
6391            return null;
6392        }
6393        Uri data = intent.getData();
6394        ClipData clip = intent.getClipData();
6395        if (data == null && clip == null) {
6396            return null;
6397        }
6398
6399        if (data != null) {
6400            GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data);
6401            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6402                    needed != null ? needed.targetUid : -1);
6403            if (targetUid > 0) {
6404                if (needed == null) {
6405                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6406                }
6407                needed.add(grantUri);
6408            }
6409        }
6410        if (clip != null) {
6411            for (int i=0; i<clip.getItemCount(); i++) {
6412                Uri uri = clip.getItemAt(i).getUri();
6413                if (uri != null) {
6414                    int targetUid = -1;
6415                    GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri);
6416                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6417                            needed != null ? needed.targetUid : -1);
6418                    if (targetUid > 0) {
6419                        if (needed == null) {
6420                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6421                        }
6422                        needed.add(grantUri);
6423                    }
6424                } else {
6425                    Intent clipIntent = clip.getItemAt(i).getIntent();
6426                    if (clipIntent != null) {
6427                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6428                                callingUid, targetPkg, clipIntent, mode, needed);
6429                        if (newNeeded != null) {
6430                            needed = newNeeded;
6431                        }
6432                    }
6433                }
6434            }
6435        }
6436
6437        return needed;
6438    }
6439
6440    /**
6441     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6442     */
6443    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6444            UriPermissionOwner owner) {
6445        if (needed != null) {
6446            for (int i=0; i<needed.size(); i++) {
6447                GrantUri grantUri = needed.get(i);
6448                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6449                        grantUri, needed.flags, owner);
6450            }
6451        }
6452    }
6453
6454    void grantUriPermissionFromIntentLocked(int callingUid,
6455            String targetPkg, Intent intent, UriPermissionOwner owner) {
6456        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6457                intent, intent != null ? intent.getFlags() : 0, null);
6458        if (needed == null) {
6459            return;
6460        }
6461
6462        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6463    }
6464
6465    @Override
6466    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6467            final int modeFlags, int userId) {
6468        enforceNotIsolatedCaller("grantUriPermission");
6469        GrantUri grantUri = new GrantUri(userId, uri, false);
6470        synchronized(this) {
6471            final ProcessRecord r = getRecordForAppLocked(caller);
6472            if (r == null) {
6473                throw new SecurityException("Unable to find app for caller "
6474                        + caller
6475                        + " when granting permission to uri " + grantUri);
6476            }
6477            if (targetPkg == null) {
6478                throw new IllegalArgumentException("null target");
6479            }
6480            if (grantUri == null) {
6481                throw new IllegalArgumentException("null uri");
6482            }
6483
6484            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6485                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6486                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6487                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6488
6489            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null);
6490        }
6491    }
6492
6493    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6494        if (perm.modeFlags == 0) {
6495            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6496                    perm.targetUid);
6497            if (perms != null) {
6498                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6499                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6500
6501                perms.remove(perm.uri);
6502                if (perms.isEmpty()) {
6503                    mGrantedUriPermissions.remove(perm.targetUid);
6504                }
6505            }
6506        }
6507    }
6508
6509    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6510        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6511
6512        final IPackageManager pm = AppGlobals.getPackageManager();
6513        final String authority = grantUri.uri.getAuthority();
6514        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6515        if (pi == null) {
6516            Slog.w(TAG, "No content provider found for permission revoke: "
6517                    + grantUri.toSafeString());
6518            return;
6519        }
6520
6521        // Does the caller have this permission on the URI?
6522        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6523            // Right now, if you are not the original owner of the permission,
6524            // you are not allowed to revoke it.
6525            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6526                throw new SecurityException("Uid " + callingUid
6527                        + " does not have permission to uri " + grantUri);
6528            //}
6529        }
6530
6531        boolean persistChanged = false;
6532
6533        // Go through all of the permissions and remove any that match.
6534        int N = mGrantedUriPermissions.size();
6535        for (int i = 0; i < N; i++) {
6536            final int targetUid = mGrantedUriPermissions.keyAt(i);
6537            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6538
6539            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6540                final UriPermission perm = it.next();
6541                if (perm.uri.sourceUserId == grantUri.sourceUserId
6542                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6543                    if (DEBUG_URI_PERMISSION)
6544                        Slog.v(TAG,
6545                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6546                    persistChanged |= perm.revokeModes(
6547                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6548                    if (perm.modeFlags == 0) {
6549                        it.remove();
6550                    }
6551                }
6552            }
6553
6554            if (perms.isEmpty()) {
6555                mGrantedUriPermissions.remove(targetUid);
6556                N--;
6557                i--;
6558            }
6559        }
6560
6561        if (persistChanged) {
6562            schedulePersistUriGrants();
6563        }
6564    }
6565
6566    @Override
6567    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6568            int userId) {
6569        enforceNotIsolatedCaller("revokeUriPermission");
6570        synchronized(this) {
6571            final ProcessRecord r = getRecordForAppLocked(caller);
6572            if (r == null) {
6573                throw new SecurityException("Unable to find app for caller "
6574                        + caller
6575                        + " when revoking permission to uri " + uri);
6576            }
6577            if (uri == null) {
6578                Slog.w(TAG, "revokeUriPermission: null uri");
6579                return;
6580            }
6581
6582            if (!Intent.isAccessUriMode(modeFlags)) {
6583                return;
6584            }
6585
6586            final IPackageManager pm = AppGlobals.getPackageManager();
6587            final String authority = uri.getAuthority();
6588            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6589            if (pi == null) {
6590                Slog.w(TAG, "No content provider found for permission revoke: "
6591                        + uri.toSafeString());
6592                return;
6593            }
6594
6595            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6596        }
6597    }
6598
6599    /**
6600     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6601     * given package.
6602     *
6603     * @param packageName Package name to match, or {@code null} to apply to all
6604     *            packages.
6605     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6606     *            to all users.
6607     * @param persistable If persistable grants should be removed.
6608     */
6609    private void removeUriPermissionsForPackageLocked(
6610            String packageName, int userHandle, boolean persistable) {
6611        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6612            throw new IllegalArgumentException("Must narrow by either package or user");
6613        }
6614
6615        boolean persistChanged = false;
6616
6617        int N = mGrantedUriPermissions.size();
6618        for (int i = 0; i < N; i++) {
6619            final int targetUid = mGrantedUriPermissions.keyAt(i);
6620            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6621
6622            // Only inspect grants matching user
6623            if (userHandle == UserHandle.USER_ALL
6624                    || userHandle == UserHandle.getUserId(targetUid)) {
6625                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6626                    final UriPermission perm = it.next();
6627
6628                    // Only inspect grants matching package
6629                    if (packageName == null || perm.sourcePkg.equals(packageName)
6630                            || perm.targetPkg.equals(packageName)) {
6631                        persistChanged |= perm.revokeModes(
6632                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6633
6634                        // Only remove when no modes remain; any persisted grants
6635                        // will keep this alive.
6636                        if (perm.modeFlags == 0) {
6637                            it.remove();
6638                        }
6639                    }
6640                }
6641
6642                if (perms.isEmpty()) {
6643                    mGrantedUriPermissions.remove(targetUid);
6644                    N--;
6645                    i--;
6646                }
6647            }
6648        }
6649
6650        if (persistChanged) {
6651            schedulePersistUriGrants();
6652        }
6653    }
6654
6655    @Override
6656    public IBinder newUriPermissionOwner(String name) {
6657        enforceNotIsolatedCaller("newUriPermissionOwner");
6658        synchronized(this) {
6659            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6660            return owner.getExternalTokenLocked();
6661        }
6662    }
6663
6664    @Override
6665    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6666            final int modeFlags, int userId) {
6667        synchronized(this) {
6668            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6669            if (owner == null) {
6670                throw new IllegalArgumentException("Unknown owner: " + token);
6671            }
6672            if (fromUid != Binder.getCallingUid()) {
6673                if (Binder.getCallingUid() != Process.myUid()) {
6674                    // Only system code can grant URI permissions on behalf
6675                    // of other users.
6676                    throw new SecurityException("nice try");
6677                }
6678            }
6679            if (targetPkg == null) {
6680                throw new IllegalArgumentException("null target");
6681            }
6682            if (uri == null) {
6683                throw new IllegalArgumentException("null uri");
6684            }
6685
6686            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false),
6687                    modeFlags, owner);
6688        }
6689    }
6690
6691    @Override
6692    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6693        synchronized(this) {
6694            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6695            if (owner == null) {
6696                throw new IllegalArgumentException("Unknown owner: " + token);
6697            }
6698
6699            if (uri == null) {
6700                owner.removeUriPermissionsLocked(mode);
6701            } else {
6702                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
6703            }
6704        }
6705    }
6706
6707    private void schedulePersistUriGrants() {
6708        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6709            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6710                    10 * DateUtils.SECOND_IN_MILLIS);
6711        }
6712    }
6713
6714    private void writeGrantedUriPermissions() {
6715        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6716
6717        // Snapshot permissions so we can persist without lock
6718        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6719        synchronized (this) {
6720            final int size = mGrantedUriPermissions.size();
6721            for (int i = 0; i < size; i++) {
6722                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6723                for (UriPermission perm : perms.values()) {
6724                    if (perm.persistedModeFlags != 0) {
6725                        persist.add(perm.snapshot());
6726                    }
6727                }
6728            }
6729        }
6730
6731        FileOutputStream fos = null;
6732        try {
6733            fos = mGrantFile.startWrite();
6734
6735            XmlSerializer out = new FastXmlSerializer();
6736            out.setOutput(fos, "utf-8");
6737            out.startDocument(null, true);
6738            out.startTag(null, TAG_URI_GRANTS);
6739            for (UriPermission.Snapshot perm : persist) {
6740                out.startTag(null, TAG_URI_GRANT);
6741                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
6742                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
6743                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6744                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6745                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6746                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6747                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6748                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6749                out.endTag(null, TAG_URI_GRANT);
6750            }
6751            out.endTag(null, TAG_URI_GRANTS);
6752            out.endDocument();
6753
6754            mGrantFile.finishWrite(fos);
6755        } catch (IOException e) {
6756            if (fos != null) {
6757                mGrantFile.failWrite(fos);
6758            }
6759        }
6760    }
6761
6762    private void readGrantedUriPermissionsLocked() {
6763        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6764
6765        final long now = System.currentTimeMillis();
6766
6767        FileInputStream fis = null;
6768        try {
6769            fis = mGrantFile.openRead();
6770            final XmlPullParser in = Xml.newPullParser();
6771            in.setInput(fis, null);
6772
6773            int type;
6774            while ((type = in.next()) != END_DOCUMENT) {
6775                final String tag = in.getName();
6776                if (type == START_TAG) {
6777                    if (TAG_URI_GRANT.equals(tag)) {
6778                        final int sourceUserId;
6779                        final int targetUserId;
6780                        final int userHandle = readIntAttribute(in,
6781                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
6782                        if (userHandle != UserHandle.USER_NULL) {
6783                            // For backwards compatibility.
6784                            sourceUserId = userHandle;
6785                            targetUserId = userHandle;
6786                        } else {
6787                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
6788                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
6789                        }
6790                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6791                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6792                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6793                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
6794                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6795                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6796
6797                        // Sanity check that provider still belongs to source package
6798                        final ProviderInfo pi = getProviderInfoLocked(
6799                                uri.getAuthority(), sourceUserId);
6800                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6801                            int targetUid = -1;
6802                            try {
6803                                targetUid = AppGlobals.getPackageManager()
6804                                        .getPackageUid(targetPkg, targetUserId);
6805                            } catch (RemoteException e) {
6806                            }
6807                            if (targetUid != -1) {
6808                                final UriPermission perm = findOrCreateUriPermissionLocked(
6809                                        sourcePkg, targetPkg, targetUid,
6810                                        new GrantUri(sourceUserId, uri, prefix));
6811                                perm.initPersistedModes(modeFlags, createdTime);
6812                            }
6813                        } else {
6814                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6815                                    + " but instead found " + pi);
6816                        }
6817                    }
6818                }
6819            }
6820        } catch (FileNotFoundException e) {
6821            // Missing grants is okay
6822        } catch (IOException e) {
6823            Log.wtf(TAG, "Failed reading Uri grants", e);
6824        } catch (XmlPullParserException e) {
6825            Log.wtf(TAG, "Failed reading Uri grants", e);
6826        } finally {
6827            IoUtils.closeQuietly(fis);
6828        }
6829    }
6830
6831    @Override
6832    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6833        enforceNotIsolatedCaller("takePersistableUriPermission");
6834
6835        Preconditions.checkFlagsArgument(modeFlags,
6836                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6837
6838        synchronized (this) {
6839            final int callingUid = Binder.getCallingUid();
6840            boolean persistChanged = false;
6841            GrantUri grantUri = new GrantUri(userId, uri, false);
6842
6843            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6844                    new GrantUri(userId, uri, false));
6845            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6846                    new GrantUri(userId, uri, true));
6847
6848            final boolean exactValid = (exactPerm != null)
6849                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
6850            final boolean prefixValid = (prefixPerm != null)
6851                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
6852
6853            if (!(exactValid || prefixValid)) {
6854                throw new SecurityException("No persistable permission grants found for UID "
6855                        + callingUid + " and Uri " + grantUri.toSafeString());
6856            }
6857
6858            if (exactValid) {
6859                persistChanged |= exactPerm.takePersistableModes(modeFlags);
6860            }
6861            if (prefixValid) {
6862                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
6863            }
6864
6865            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6866
6867            if (persistChanged) {
6868                schedulePersistUriGrants();
6869            }
6870        }
6871    }
6872
6873    @Override
6874    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6875        enforceNotIsolatedCaller("releasePersistableUriPermission");
6876
6877        Preconditions.checkFlagsArgument(modeFlags,
6878                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6879
6880        synchronized (this) {
6881            final int callingUid = Binder.getCallingUid();
6882            boolean persistChanged = false;
6883
6884            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6885                    new GrantUri(userId, uri, false));
6886            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6887                    new GrantUri(userId, uri, true));
6888            if (exactPerm == null && prefixPerm == null) {
6889                throw new SecurityException("No permission grants found for UID " + callingUid
6890                        + " and Uri " + uri.toSafeString());
6891            }
6892
6893            if (exactPerm != null) {
6894                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
6895                removeUriPermissionIfNeededLocked(exactPerm);
6896            }
6897            if (prefixPerm != null) {
6898                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
6899                removeUriPermissionIfNeededLocked(prefixPerm);
6900            }
6901
6902            if (persistChanged) {
6903                schedulePersistUriGrants();
6904            }
6905        }
6906    }
6907
6908    /**
6909     * Prune any older {@link UriPermission} for the given UID until outstanding
6910     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6911     *
6912     * @return if any mutations occured that require persisting.
6913     */
6914    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6915        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6916        if (perms == null) return false;
6917        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6918
6919        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6920        for (UriPermission perm : perms.values()) {
6921            if (perm.persistedModeFlags != 0) {
6922                persisted.add(perm);
6923            }
6924        }
6925
6926        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6927        if (trimCount <= 0) return false;
6928
6929        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6930        for (int i = 0; i < trimCount; i++) {
6931            final UriPermission perm = persisted.get(i);
6932
6933            if (DEBUG_URI_PERMISSION) {
6934                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6935            }
6936
6937            perm.releasePersistableModes(~0);
6938            removeUriPermissionIfNeededLocked(perm);
6939        }
6940
6941        return true;
6942    }
6943
6944    @Override
6945    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6946            String packageName, boolean incoming) {
6947        enforceNotIsolatedCaller("getPersistedUriPermissions");
6948        Preconditions.checkNotNull(packageName, "packageName");
6949
6950        final int callingUid = Binder.getCallingUid();
6951        final IPackageManager pm = AppGlobals.getPackageManager();
6952        try {
6953            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6954            if (packageUid != callingUid) {
6955                throw new SecurityException(
6956                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6957            }
6958        } catch (RemoteException e) {
6959            throw new SecurityException("Failed to verify package name ownership");
6960        }
6961
6962        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6963        synchronized (this) {
6964            if (incoming) {
6965                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6966                        callingUid);
6967                if (perms == null) {
6968                    Slog.w(TAG, "No permission grants found for " + packageName);
6969                } else {
6970                    for (UriPermission perm : perms.values()) {
6971                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6972                            result.add(perm.buildPersistedPublicApiObject());
6973                        }
6974                    }
6975                }
6976            } else {
6977                final int size = mGrantedUriPermissions.size();
6978                for (int i = 0; i < size; i++) {
6979                    final ArrayMap<GrantUri, UriPermission> perms =
6980                            mGrantedUriPermissions.valueAt(i);
6981                    for (UriPermission perm : perms.values()) {
6982                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6983                            result.add(perm.buildPersistedPublicApiObject());
6984                        }
6985                    }
6986                }
6987            }
6988        }
6989        return new ParceledListSlice<android.content.UriPermission>(result);
6990    }
6991
6992    @Override
6993    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6994        synchronized (this) {
6995            ProcessRecord app =
6996                who != null ? getRecordForAppLocked(who) : null;
6997            if (app == null) return;
6998
6999            Message msg = Message.obtain();
7000            msg.what = WAIT_FOR_DEBUGGER_MSG;
7001            msg.obj = app;
7002            msg.arg1 = waiting ? 1 : 0;
7003            mHandler.sendMessage(msg);
7004        }
7005    }
7006
7007    @Override
7008    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7009        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7010        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7011        outInfo.availMem = Process.getFreeMemory();
7012        outInfo.totalMem = Process.getTotalMemory();
7013        outInfo.threshold = homeAppMem;
7014        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7015        outInfo.hiddenAppThreshold = cachedAppMem;
7016        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7017                ProcessList.SERVICE_ADJ);
7018        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7019                ProcessList.VISIBLE_APP_ADJ);
7020        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7021                ProcessList.FOREGROUND_APP_ADJ);
7022    }
7023
7024    // =========================================================
7025    // TASK MANAGEMENT
7026    // =========================================================
7027
7028    @Override
7029    public List<IAppTask> getAppTasks() {
7030        int callingUid = Binder.getCallingUid();
7031        long ident = Binder.clearCallingIdentity();
7032        synchronized(this) {
7033            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7034            try {
7035                if (localLOGV) Slog.v(TAG, "getAppTasks");
7036
7037                final int N = mRecentTasks.size();
7038                for (int i = 0; i < N; i++) {
7039                    TaskRecord tr = mRecentTasks.get(i);
7040                    // Skip tasks that are not created by the caller
7041                    if (tr.creatorUid == callingUid) {
7042                        ActivityManager.RecentTaskInfo taskInfo =
7043                                createRecentTaskInfoFromTaskRecord(tr);
7044                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7045                        list.add(taskImpl);
7046                    }
7047                }
7048            } finally {
7049                Binder.restoreCallingIdentity(ident);
7050            }
7051            return list;
7052        }
7053    }
7054
7055    @Override
7056    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7057        final int callingUid = Binder.getCallingUid();
7058        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7059
7060        synchronized(this) {
7061            if (localLOGV) Slog.v(
7062                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7063
7064            final boolean allowed = checkCallingPermission(
7065                    android.Manifest.permission.GET_TASKS)
7066                    == PackageManager.PERMISSION_GRANTED;
7067            if (!allowed) {
7068                Slog.w(TAG, "getTasks: caller " + callingUid
7069                        + " does not hold GET_TASKS; limiting output");
7070            }
7071
7072            // TODO: Improve with MRU list from all ActivityStacks.
7073            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7074        }
7075
7076        return list;
7077    }
7078
7079    TaskRecord getMostRecentTask() {
7080        return mRecentTasks.get(0);
7081    }
7082
7083    /**
7084     * Creates a new RecentTaskInfo from a TaskRecord.
7085     */
7086    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7087        ActivityManager.RecentTaskInfo rti
7088                = new ActivityManager.RecentTaskInfo();
7089        rti.id = tr.mActivities.isEmpty() ? -1 : tr.taskId;
7090        rti.persistentId = tr.taskId;
7091        rti.baseIntent = new Intent(tr.getBaseIntent());
7092        rti.origActivity = tr.origActivity;
7093        rti.description = tr.lastDescription;
7094        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7095        rti.userId = tr.userId;
7096        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7097        return rti;
7098    }
7099
7100    @Override
7101    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
7102            int flags, int userId) {
7103        final int callingUid = Binder.getCallingUid();
7104        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7105                false, true, "getRecentTasks", null);
7106
7107        synchronized (this) {
7108            final boolean allowed = checkCallingPermission(
7109                    android.Manifest.permission.GET_TASKS)
7110                    == PackageManager.PERMISSION_GRANTED;
7111            if (!allowed) {
7112                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7113                        + " does not hold GET_TASKS; limiting output");
7114            }
7115            final boolean detailed = checkCallingPermission(
7116                    android.Manifest.permission.GET_DETAILED_TASKS)
7117                    == PackageManager.PERMISSION_GRANTED;
7118
7119            IPackageManager pm = AppGlobals.getPackageManager();
7120
7121            final int N = mRecentTasks.size();
7122            ArrayList<ActivityManager.RecentTaskInfo> res
7123                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7124                            maxNum < N ? maxNum : N);
7125
7126            final Set<Integer> includedUsers;
7127            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
7128                includedUsers = getProfileIdsLocked(userId);
7129            } else {
7130                includedUsers = new HashSet<Integer>();
7131            }
7132            includedUsers.add(Integer.valueOf(userId));
7133            for (int i=0; i<N && maxNum > 0; i++) {
7134                TaskRecord tr = mRecentTasks.get(i);
7135                // Only add calling user or related users recent tasks
7136                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7137
7138                // Return the entry if desired by the caller.  We always return
7139                // the first entry, because callers always expect this to be the
7140                // foreground app.  We may filter others if the caller has
7141                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7142                // we should exclude the entry.
7143
7144                if (i == 0
7145                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
7146                        || (tr.intent == null)
7147                        || ((tr.intent.getFlags()
7148                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
7149                    if (!allowed) {
7150                        // If the caller doesn't have the GET_TASKS permission, then only
7151                        // allow them to see a small subset of tasks -- their own and home.
7152                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7153                            continue;
7154                        }
7155                    }
7156
7157                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7158                    if (!detailed) {
7159                        rti.baseIntent.replaceExtras((Bundle)null);
7160                    }
7161
7162                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7163                        // Check whether this activity is currently available.
7164                        try {
7165                            if (rti.origActivity != null) {
7166                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7167                                        == null) {
7168                                    continue;
7169                                }
7170                            } else if (rti.baseIntent != null) {
7171                                if (pm.queryIntentActivities(rti.baseIntent,
7172                                        null, 0, userId) == null) {
7173                                    continue;
7174                                }
7175                            }
7176                        } catch (RemoteException e) {
7177                            // Will never happen.
7178                        }
7179                    }
7180
7181                    res.add(rti);
7182                    maxNum--;
7183                }
7184            }
7185            return res;
7186        }
7187    }
7188
7189    private TaskRecord recentTaskForIdLocked(int id) {
7190        final int N = mRecentTasks.size();
7191            for (int i=0; i<N; i++) {
7192                TaskRecord tr = mRecentTasks.get(i);
7193                if (tr.taskId == id) {
7194                    return tr;
7195                }
7196            }
7197            return null;
7198    }
7199
7200    @Override
7201    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
7202        synchronized (this) {
7203            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7204                    "getTaskThumbnails()");
7205            TaskRecord tr = recentTaskForIdLocked(id);
7206            if (tr != null) {
7207                return tr.getTaskThumbnailsLocked();
7208            }
7209        }
7210        return null;
7211    }
7212
7213    @Override
7214    public Bitmap getTaskTopThumbnail(int id) {
7215        synchronized (this) {
7216            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7217                    "getTaskTopThumbnail()");
7218            TaskRecord tr = recentTaskForIdLocked(id);
7219            if (tr != null) {
7220                return tr.getTaskTopThumbnailLocked();
7221            }
7222        }
7223        return null;
7224    }
7225
7226    @Override
7227    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7228        synchronized (this) {
7229            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7230            if (r != null) {
7231                r.taskDescription = td;
7232                r.task.updateTaskDescription();
7233            }
7234        }
7235    }
7236
7237    @Override
7238    public boolean removeSubTask(int taskId, int subTaskIndex) {
7239        synchronized (this) {
7240            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7241                    "removeSubTask()");
7242            long ident = Binder.clearCallingIdentity();
7243            try {
7244                TaskRecord tr = recentTaskForIdLocked(taskId);
7245                if (tr != null) {
7246                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
7247                }
7248                return false;
7249            } finally {
7250                Binder.restoreCallingIdentity(ident);
7251            }
7252        }
7253    }
7254
7255    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7256        if (!pr.killedByAm) {
7257            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7258            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7259                    pr.processName, pr.setAdj, reason);
7260            pr.killedByAm = true;
7261            Process.killProcessQuiet(pr.pid);
7262        }
7263    }
7264
7265    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7266        tr.disposeThumbnail();
7267        mRecentTasks.remove(tr);
7268        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7269        Intent baseIntent = new Intent(
7270                tr.intent != null ? tr.intent : tr.affinityIntent);
7271        ComponentName component = baseIntent.getComponent();
7272        if (component == null) {
7273            Slog.w(TAG, "Now component for base intent of task: " + tr);
7274            return;
7275        }
7276
7277        // Find any running services associated with this app.
7278        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7279
7280        if (killProcesses) {
7281            // Find any running processes associated with this app.
7282            final String pkg = component.getPackageName();
7283            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7284            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7285            for (int i=0; i<pmap.size(); i++) {
7286                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7287                for (int j=0; j<uids.size(); j++) {
7288                    ProcessRecord proc = uids.valueAt(j);
7289                    if (proc.userId != tr.userId) {
7290                        continue;
7291                    }
7292                    if (!proc.pkgList.containsKey(pkg)) {
7293                        continue;
7294                    }
7295                    procs.add(proc);
7296                }
7297            }
7298
7299            // Kill the running processes.
7300            for (int i=0; i<procs.size(); i++) {
7301                ProcessRecord pr = procs.get(i);
7302                if (pr == mHomeProcess) {
7303                    // Don't kill the home process along with tasks from the same package.
7304                    continue;
7305                }
7306                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7307                    killUnneededProcessLocked(pr, "remove task");
7308                } else {
7309                    pr.waitingToKill = "remove task";
7310                }
7311            }
7312        }
7313    }
7314
7315    /**
7316     * Removes the task with the specified task id.
7317     *
7318     * @param taskId Identifier of the task to be removed.
7319     * @param flags Additional operational flags.  May be 0 or
7320     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7321     * @return Returns true if the given task was found and removed.
7322     */
7323    private boolean removeTaskByIdLocked(int taskId, int flags) {
7324        TaskRecord tr = recentTaskForIdLocked(taskId);
7325        if (tr != null) {
7326            tr.removeTaskActivitiesLocked(-1, false);
7327            cleanUpRemovedTaskLocked(tr, flags);
7328            if (tr.isPersistable) {
7329                notifyTaskPersisterLocked(tr, true);
7330            }
7331            return true;
7332        }
7333        return false;
7334    }
7335
7336    @Override
7337    public boolean removeTask(int taskId, int flags) {
7338        synchronized (this) {
7339            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7340                    "removeTask()");
7341            long ident = Binder.clearCallingIdentity();
7342            try {
7343                return removeTaskByIdLocked(taskId, flags);
7344            } finally {
7345                Binder.restoreCallingIdentity(ident);
7346            }
7347        }
7348    }
7349
7350    /**
7351     * TODO: Add mController hook
7352     */
7353    @Override
7354    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7355        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7356                "moveTaskToFront()");
7357
7358        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7359        synchronized(this) {
7360            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7361                    Binder.getCallingUid(), "Task to front")) {
7362                ActivityOptions.abort(options);
7363                return;
7364            }
7365            final long origId = Binder.clearCallingIdentity();
7366            try {
7367                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7368                if (task == null) {
7369                    return;
7370                }
7371                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7372                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7373                    return;
7374                }
7375                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7376            } finally {
7377                Binder.restoreCallingIdentity(origId);
7378            }
7379            ActivityOptions.abort(options);
7380        }
7381    }
7382
7383    @Override
7384    public void moveTaskToBack(int taskId) {
7385        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7386                "moveTaskToBack()");
7387
7388        synchronized(this) {
7389            TaskRecord tr = recentTaskForIdLocked(taskId);
7390            if (tr != null) {
7391                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7392                ActivityStack stack = tr.stack;
7393                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7394                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7395                            Binder.getCallingUid(), "Task to back")) {
7396                        return;
7397                    }
7398                }
7399                final long origId = Binder.clearCallingIdentity();
7400                try {
7401                    stack.moveTaskToBackLocked(taskId, null);
7402                } finally {
7403                    Binder.restoreCallingIdentity(origId);
7404                }
7405            }
7406        }
7407    }
7408
7409    /**
7410     * Moves an activity, and all of the other activities within the same task, to the bottom
7411     * of the history stack.  The activity's order within the task is unchanged.
7412     *
7413     * @param token A reference to the activity we wish to move
7414     * @param nonRoot If false then this only works if the activity is the root
7415     *                of a task; if true it will work for any activity in a task.
7416     * @return Returns true if the move completed, false if not.
7417     */
7418    @Override
7419    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7420        enforceNotIsolatedCaller("moveActivityTaskToBack");
7421        synchronized(this) {
7422            final long origId = Binder.clearCallingIdentity();
7423            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7424            if (taskId >= 0) {
7425                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7426            }
7427            Binder.restoreCallingIdentity(origId);
7428        }
7429        return false;
7430    }
7431
7432    @Override
7433    public void moveTaskBackwards(int task) {
7434        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7435                "moveTaskBackwards()");
7436
7437        synchronized(this) {
7438            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7439                    Binder.getCallingUid(), "Task backwards")) {
7440                return;
7441            }
7442            final long origId = Binder.clearCallingIdentity();
7443            moveTaskBackwardsLocked(task);
7444            Binder.restoreCallingIdentity(origId);
7445        }
7446    }
7447
7448    private final void moveTaskBackwardsLocked(int task) {
7449        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7450    }
7451
7452    @Override
7453    public IBinder getHomeActivityToken() throws RemoteException {
7454        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7455                "getHomeActivityToken()");
7456        synchronized (this) {
7457            return mStackSupervisor.getHomeActivityToken();
7458        }
7459    }
7460
7461    @Override
7462    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7463            IActivityContainerCallback callback) throws RemoteException {
7464        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7465                "createActivityContainer()");
7466        synchronized (this) {
7467            if (parentActivityToken == null) {
7468                throw new IllegalArgumentException("parent token must not be null");
7469            }
7470            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7471            if (r == null) {
7472                return null;
7473            }
7474            if (callback == null) {
7475                throw new IllegalArgumentException("callback must not be null");
7476            }
7477            return mStackSupervisor.createActivityContainer(r, callback);
7478        }
7479    }
7480
7481    @Override
7482    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7483        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7484                "deleteActivityContainer()");
7485        synchronized (this) {
7486            mStackSupervisor.deleteActivityContainer(container);
7487        }
7488    }
7489
7490    @Override
7491    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7492            throws RemoteException {
7493        synchronized (this) {
7494            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7495            if (stack != null) {
7496                return stack.mActivityContainer;
7497            }
7498            return null;
7499        }
7500    }
7501
7502    @Override
7503    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7504        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7505                "moveTaskToStack()");
7506        if (stackId == HOME_STACK_ID) {
7507            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7508                    new RuntimeException("here").fillInStackTrace());
7509        }
7510        synchronized (this) {
7511            long ident = Binder.clearCallingIdentity();
7512            try {
7513                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7514                        + stackId + " toTop=" + toTop);
7515                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7516            } finally {
7517                Binder.restoreCallingIdentity(ident);
7518            }
7519        }
7520    }
7521
7522    @Override
7523    public void resizeStack(int stackBoxId, Rect bounds) {
7524        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7525                "resizeStackBox()");
7526        long ident = Binder.clearCallingIdentity();
7527        try {
7528            mWindowManager.resizeStack(stackBoxId, bounds);
7529        } finally {
7530            Binder.restoreCallingIdentity(ident);
7531        }
7532    }
7533
7534    @Override
7535    public List<StackInfo> getAllStackInfos() {
7536        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7537                "getAllStackInfos()");
7538        long ident = Binder.clearCallingIdentity();
7539        try {
7540            synchronized (this) {
7541                return mStackSupervisor.getAllStackInfosLocked();
7542            }
7543        } finally {
7544            Binder.restoreCallingIdentity(ident);
7545        }
7546    }
7547
7548    @Override
7549    public StackInfo getStackInfo(int stackId) {
7550        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7551                "getStackInfo()");
7552        long ident = Binder.clearCallingIdentity();
7553        try {
7554            synchronized (this) {
7555                return mStackSupervisor.getStackInfoLocked(stackId);
7556            }
7557        } finally {
7558            Binder.restoreCallingIdentity(ident);
7559        }
7560    }
7561
7562    @Override
7563    public boolean isInHomeStack(int taskId) {
7564        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7565                "getStackInfo()");
7566        long ident = Binder.clearCallingIdentity();
7567        try {
7568            synchronized (this) {
7569                TaskRecord tr = recentTaskForIdLocked(taskId);
7570                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7571            }
7572        } finally {
7573            Binder.restoreCallingIdentity(ident);
7574        }
7575    }
7576
7577    @Override
7578    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7579        synchronized(this) {
7580            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7581        }
7582    }
7583
7584    private boolean isLockTaskAuthorized(ComponentName name) {
7585//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7586//                "startLockTaskMode()");
7587//        DevicePolicyManager dpm = (DevicePolicyManager)
7588//                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7589//        return dpm != null && dpm.isLockTaskPermitted(name);
7590        return true;
7591    }
7592
7593    private void startLockTaskMode(TaskRecord task) {
7594        if (!isLockTaskAuthorized(task.intent.getComponent())) {
7595            return;
7596        }
7597        long ident = Binder.clearCallingIdentity();
7598        try {
7599            synchronized (this) {
7600                // Since we lost lock on task, make sure it is still there.
7601                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7602                if (task != null) {
7603                    mStackSupervisor.setLockTaskModeLocked(task);
7604                }
7605            }
7606        } finally {
7607            Binder.restoreCallingIdentity(ident);
7608        }
7609    }
7610
7611    @Override
7612    public void startLockTaskMode(int taskId) {
7613        long ident = Binder.clearCallingIdentity();
7614        try {
7615            final TaskRecord task;
7616            synchronized (this) {
7617                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7618            }
7619            if (task != null) {
7620                startLockTaskMode(task);
7621            }
7622        } finally {
7623            Binder.restoreCallingIdentity(ident);
7624        }
7625    }
7626
7627    @Override
7628    public void startLockTaskMode(IBinder token) {
7629        long ident = Binder.clearCallingIdentity();
7630        try {
7631            final TaskRecord task;
7632            synchronized (this) {
7633                final ActivityRecord r = ActivityRecord.forToken(token);
7634                if (r == null) {
7635                    return;
7636                }
7637                task = r.task;
7638            }
7639            if (task != null) {
7640                startLockTaskMode(task);
7641            }
7642        } finally {
7643            Binder.restoreCallingIdentity(ident);
7644        }
7645    }
7646
7647    @Override
7648    public void stopLockTaskMode() {
7649//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7650//                "stopLockTaskMode()");
7651        synchronized (this) {
7652            mStackSupervisor.setLockTaskModeLocked(null);
7653        }
7654    }
7655
7656    @Override
7657    public boolean isInLockTaskMode() {
7658        synchronized (this) {
7659            return mStackSupervisor.isInLockTaskMode();
7660        }
7661    }
7662
7663    // =========================================================
7664    // CONTENT PROVIDERS
7665    // =========================================================
7666
7667    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7668        List<ProviderInfo> providers = null;
7669        try {
7670            providers = AppGlobals.getPackageManager().
7671                queryContentProviders(app.processName, app.uid,
7672                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7673        } catch (RemoteException ex) {
7674        }
7675        if (DEBUG_MU)
7676            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7677        int userId = app.userId;
7678        if (providers != null) {
7679            int N = providers.size();
7680            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7681            for (int i=0; i<N; i++) {
7682                ProviderInfo cpi =
7683                    (ProviderInfo)providers.get(i);
7684                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7685                        cpi.name, cpi.flags);
7686                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7687                    // This is a singleton provider, but a user besides the
7688                    // default user is asking to initialize a process it runs
7689                    // in...  well, no, it doesn't actually run in this process,
7690                    // it runs in the process of the default user.  Get rid of it.
7691                    providers.remove(i);
7692                    N--;
7693                    i--;
7694                    continue;
7695                }
7696
7697                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7698                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7699                if (cpr == null) {
7700                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7701                    mProviderMap.putProviderByClass(comp, cpr);
7702                }
7703                if (DEBUG_MU)
7704                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7705                app.pubProviders.put(cpi.name, cpr);
7706                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7707                    // Don't add this if it is a platform component that is marked
7708                    // to run in multiple processes, because this is actually
7709                    // part of the framework so doesn't make sense to track as a
7710                    // separate apk in the process.
7711                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7712                }
7713                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7714            }
7715        }
7716        return providers;
7717    }
7718
7719    /**
7720     * Check if {@link ProcessRecord} has a possible chance at accessing the
7721     * given {@link ProviderInfo}. Final permission checking is always done
7722     * in {@link ContentProvider}.
7723     */
7724    private final String checkContentProviderPermissionLocked(
7725            ProviderInfo cpi, ProcessRecord r, int userId) {
7726        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7727        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7728        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7729        // Looking for cross-user grants before to enforce the typical cross-users permissions
7730        if (userId != UserHandle.getUserId(callingUid)) {
7731            if (perms != null) {
7732                for (GrantUri grantUri : perms.keySet()) {
7733                    if (grantUri.sourceUserId == userId) {
7734                        String authority = grantUri.uri.getAuthority();
7735                        if (authority.equals(cpi.authority)) {
7736                            return null;
7737                        }
7738                    }
7739                }
7740            }
7741        }
7742        userId = handleIncomingUser(callingPid, callingUid, userId,
7743                false, true, "checkContentProviderPermissionLocked", null);
7744        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7745                cpi.applicationInfo.uid, cpi.exported)
7746                == PackageManager.PERMISSION_GRANTED) {
7747            return null;
7748        }
7749        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7750                cpi.applicationInfo.uid, cpi.exported)
7751                == PackageManager.PERMISSION_GRANTED) {
7752            return null;
7753        }
7754
7755        PathPermission[] pps = cpi.pathPermissions;
7756        if (pps != null) {
7757            int i = pps.length;
7758            while (i > 0) {
7759                i--;
7760                PathPermission pp = pps[i];
7761                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7762                        cpi.applicationInfo.uid, cpi.exported)
7763                        == PackageManager.PERMISSION_GRANTED) {
7764                    return null;
7765                }
7766                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7767                        cpi.applicationInfo.uid, cpi.exported)
7768                        == PackageManager.PERMISSION_GRANTED) {
7769                    return null;
7770                }
7771            }
7772        }
7773
7774        if (perms != null) {
7775            for (GrantUri grantUri : perms.keySet()) {
7776                if (grantUri.uri.getAuthority().equals(cpi.authority)) {
7777                    return null;
7778                }
7779            }
7780        }
7781
7782        String msg;
7783        if (!cpi.exported) {
7784            msg = "Permission Denial: opening provider " + cpi.name
7785                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7786                    + ", uid=" + callingUid + ") that is not exported from uid "
7787                    + cpi.applicationInfo.uid;
7788        } else {
7789            msg = "Permission Denial: opening provider " + cpi.name
7790                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7791                    + ", uid=" + callingUid + ") requires "
7792                    + cpi.readPermission + " or " + cpi.writePermission;
7793        }
7794        Slog.w(TAG, msg);
7795        return msg;
7796    }
7797
7798    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7799            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7800        if (r != null) {
7801            for (int i=0; i<r.conProviders.size(); i++) {
7802                ContentProviderConnection conn = r.conProviders.get(i);
7803                if (conn.provider == cpr) {
7804                    if (DEBUG_PROVIDER) Slog.v(TAG,
7805                            "Adding provider requested by "
7806                            + r.processName + " from process "
7807                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7808                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7809                    if (stable) {
7810                        conn.stableCount++;
7811                        conn.numStableIncs++;
7812                    } else {
7813                        conn.unstableCount++;
7814                        conn.numUnstableIncs++;
7815                    }
7816                    return conn;
7817                }
7818            }
7819            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7820            if (stable) {
7821                conn.stableCount = 1;
7822                conn.numStableIncs = 1;
7823            } else {
7824                conn.unstableCount = 1;
7825                conn.numUnstableIncs = 1;
7826            }
7827            cpr.connections.add(conn);
7828            r.conProviders.add(conn);
7829            return conn;
7830        }
7831        cpr.addExternalProcessHandleLocked(externalProcessToken);
7832        return null;
7833    }
7834
7835    boolean decProviderCountLocked(ContentProviderConnection conn,
7836            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7837        if (conn != null) {
7838            cpr = conn.provider;
7839            if (DEBUG_PROVIDER) Slog.v(TAG,
7840                    "Removing provider requested by "
7841                    + conn.client.processName + " from process "
7842                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7843                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7844            if (stable) {
7845                conn.stableCount--;
7846            } else {
7847                conn.unstableCount--;
7848            }
7849            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7850                cpr.connections.remove(conn);
7851                conn.client.conProviders.remove(conn);
7852                return true;
7853            }
7854            return false;
7855        }
7856        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7857        return false;
7858    }
7859
7860    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7861            String name, IBinder token, boolean stable, int userId) {
7862        ContentProviderRecord cpr;
7863        ContentProviderConnection conn = null;
7864        ProviderInfo cpi = null;
7865
7866        synchronized(this) {
7867            ProcessRecord r = null;
7868            if (caller != null) {
7869                r = getRecordForAppLocked(caller);
7870                if (r == null) {
7871                    throw new SecurityException(
7872                            "Unable to find app for caller " + caller
7873                          + " (pid=" + Binder.getCallingPid()
7874                          + ") when getting content provider " + name);
7875                }
7876            }
7877
7878            // First check if this content provider has been published...
7879            cpr = mProviderMap.getProviderByName(name, userId);
7880            boolean providerRunning = cpr != null;
7881            if (providerRunning) {
7882                cpi = cpr.info;
7883                String msg;
7884                if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) {
7885                    throw new SecurityException(msg);
7886                }
7887
7888                if (r != null && cpr.canRunHere(r)) {
7889                    // This provider has been published or is in the process
7890                    // of being published...  but it is also allowed to run
7891                    // in the caller's process, so don't make a connection
7892                    // and just let the caller instantiate its own instance.
7893                    ContentProviderHolder holder = cpr.newHolder(null);
7894                    // don't give caller the provider object, it needs
7895                    // to make its own.
7896                    holder.provider = null;
7897                    return holder;
7898                }
7899
7900                final long origId = Binder.clearCallingIdentity();
7901
7902                // In this case the provider instance already exists, so we can
7903                // return it right away.
7904                conn = incProviderCountLocked(r, cpr, token, stable);
7905                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7906                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7907                        // If this is a perceptible app accessing the provider,
7908                        // make sure to count it as being accessed and thus
7909                        // back up on the LRU list.  This is good because
7910                        // content providers are often expensive to start.
7911                        updateLruProcessLocked(cpr.proc, false, null);
7912                    }
7913                }
7914
7915                if (cpr.proc != null) {
7916                    if (false) {
7917                        if (cpr.name.flattenToShortString().equals(
7918                                "com.android.providers.calendar/.CalendarProvider2")) {
7919                            Slog.v(TAG, "****************** KILLING "
7920                                + cpr.name.flattenToShortString());
7921                            Process.killProcess(cpr.proc.pid);
7922                        }
7923                    }
7924                    boolean success = updateOomAdjLocked(cpr.proc);
7925                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7926                    // NOTE: there is still a race here where a signal could be
7927                    // pending on the process even though we managed to update its
7928                    // adj level.  Not sure what to do about this, but at least
7929                    // the race is now smaller.
7930                    if (!success) {
7931                        // Uh oh...  it looks like the provider's process
7932                        // has been killed on us.  We need to wait for a new
7933                        // process to be started, and make sure its death
7934                        // doesn't kill our process.
7935                        Slog.i(TAG,
7936                                "Existing provider " + cpr.name.flattenToShortString()
7937                                + " is crashing; detaching " + r);
7938                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7939                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7940                        if (!lastRef) {
7941                            // This wasn't the last ref our process had on
7942                            // the provider...  we have now been killed, bail.
7943                            return null;
7944                        }
7945                        providerRunning = false;
7946                        conn = null;
7947                    }
7948                }
7949
7950                Binder.restoreCallingIdentity(origId);
7951            }
7952
7953            boolean singleton;
7954            if (!providerRunning) {
7955                try {
7956                    cpi = AppGlobals.getPackageManager().
7957                        resolveContentProvider(name,
7958                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7959                } catch (RemoteException ex) {
7960                }
7961                if (cpi == null) {
7962                    return null;
7963                }
7964                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7965                        cpi.name, cpi.flags);
7966                if (singleton) {
7967                    userId = 0;
7968                }
7969                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7970
7971                String msg;
7972                if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) {
7973                    throw new SecurityException(msg);
7974                }
7975
7976                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
7977                        && !cpi.processName.equals("system")) {
7978                    // If this content provider does not run in the system
7979                    // process, and the system is not yet ready to run other
7980                    // processes, then fail fast instead of hanging.
7981                    throw new IllegalArgumentException(
7982                            "Attempt to launch content provider before system ready");
7983                }
7984
7985                // Make sure that the user who owns this provider is started.  If not,
7986                // we don't want to allow it to run.
7987                if (mStartedUsers.get(userId) == null) {
7988                    Slog.w(TAG, "Unable to launch app "
7989                            + cpi.applicationInfo.packageName + "/"
7990                            + cpi.applicationInfo.uid + " for provider "
7991                            + name + ": user " + userId + " is stopped");
7992                    return null;
7993                }
7994
7995                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7996                cpr = mProviderMap.getProviderByClass(comp, userId);
7997                final boolean firstClass = cpr == null;
7998                if (firstClass) {
7999                    try {
8000                        ApplicationInfo ai =
8001                            AppGlobals.getPackageManager().
8002                                getApplicationInfo(
8003                                        cpi.applicationInfo.packageName,
8004                                        STOCK_PM_FLAGS, userId);
8005                        if (ai == null) {
8006                            Slog.w(TAG, "No package info for content provider "
8007                                    + cpi.name);
8008                            return null;
8009                        }
8010                        ai = getAppInfoForUser(ai, userId);
8011                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8012                    } catch (RemoteException ex) {
8013                        // pm is in same process, this will never happen.
8014                    }
8015                }
8016
8017                if (r != null && cpr.canRunHere(r)) {
8018                    // If this is a multiprocess provider, then just return its
8019                    // info and allow the caller to instantiate it.  Only do
8020                    // this if the provider is the same user as the caller's
8021                    // process, or can run as root (so can be in any process).
8022                    return cpr.newHolder(null);
8023                }
8024
8025                if (DEBUG_PROVIDER) {
8026                    RuntimeException e = new RuntimeException("here");
8027                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8028                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8029                }
8030
8031                // This is single process, and our app is now connecting to it.
8032                // See if we are already in the process of launching this
8033                // provider.
8034                final int N = mLaunchingProviders.size();
8035                int i;
8036                for (i=0; i<N; i++) {
8037                    if (mLaunchingProviders.get(i) == cpr) {
8038                        break;
8039                    }
8040                }
8041
8042                // If the provider is not already being launched, then get it
8043                // started.
8044                if (i >= N) {
8045                    final long origId = Binder.clearCallingIdentity();
8046
8047                    try {
8048                        // Content provider is now in use, its package can't be stopped.
8049                        try {
8050                            AppGlobals.getPackageManager().setPackageStoppedState(
8051                                    cpr.appInfo.packageName, false, userId);
8052                        } catch (RemoteException e) {
8053                        } catch (IllegalArgumentException e) {
8054                            Slog.w(TAG, "Failed trying to unstop package "
8055                                    + cpr.appInfo.packageName + ": " + e);
8056                        }
8057
8058                        // Use existing process if already started
8059                        ProcessRecord proc = getProcessRecordLocked(
8060                                cpi.processName, cpr.appInfo.uid, false);
8061                        if (proc != null && proc.thread != null) {
8062                            if (DEBUG_PROVIDER) {
8063                                Slog.d(TAG, "Installing in existing process " + proc);
8064                            }
8065                            proc.pubProviders.put(cpi.name, cpr);
8066                            try {
8067                                proc.thread.scheduleInstallProvider(cpi);
8068                            } catch (RemoteException e) {
8069                            }
8070                        } else {
8071                            proc = startProcessLocked(cpi.processName,
8072                                    cpr.appInfo, false, 0, "content provider",
8073                                    new ComponentName(cpi.applicationInfo.packageName,
8074                                            cpi.name), false, false, false);
8075                            if (proc == null) {
8076                                Slog.w(TAG, "Unable to launch app "
8077                                        + cpi.applicationInfo.packageName + "/"
8078                                        + cpi.applicationInfo.uid + " for provider "
8079                                        + name + ": process is bad");
8080                                return null;
8081                            }
8082                        }
8083                        cpr.launchingApp = proc;
8084                        mLaunchingProviders.add(cpr);
8085                    } finally {
8086                        Binder.restoreCallingIdentity(origId);
8087                    }
8088                }
8089
8090                // Make sure the provider is published (the same provider class
8091                // may be published under multiple names).
8092                if (firstClass) {
8093                    mProviderMap.putProviderByClass(comp, cpr);
8094                }
8095
8096                mProviderMap.putProviderByName(name, cpr);
8097                conn = incProviderCountLocked(r, cpr, token, stable);
8098                if (conn != null) {
8099                    conn.waiting = true;
8100                }
8101            }
8102        }
8103
8104        // Wait for the provider to be published...
8105        synchronized (cpr) {
8106            while (cpr.provider == null) {
8107                if (cpr.launchingApp == null) {
8108                    Slog.w(TAG, "Unable to launch app "
8109                            + cpi.applicationInfo.packageName + "/"
8110                            + cpi.applicationInfo.uid + " for provider "
8111                            + name + ": launching app became null");
8112                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8113                            UserHandle.getUserId(cpi.applicationInfo.uid),
8114                            cpi.applicationInfo.packageName,
8115                            cpi.applicationInfo.uid, name);
8116                    return null;
8117                }
8118                try {
8119                    if (DEBUG_MU) {
8120                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8121                                + cpr.launchingApp);
8122                    }
8123                    if (conn != null) {
8124                        conn.waiting = true;
8125                    }
8126                    cpr.wait();
8127                } catch (InterruptedException ex) {
8128                } finally {
8129                    if (conn != null) {
8130                        conn.waiting = false;
8131                    }
8132                }
8133            }
8134        }
8135        return cpr != null ? cpr.newHolder(conn) : null;
8136    }
8137
8138    @Override
8139    public final ContentProviderHolder getContentProvider(
8140            IApplicationThread caller, String name, int userId, boolean stable) {
8141        enforceNotIsolatedCaller("getContentProvider");
8142        if (caller == null) {
8143            String msg = "null IApplicationThread when getting content provider "
8144                    + name;
8145            Slog.w(TAG, msg);
8146            throw new SecurityException(msg);
8147        }
8148        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8149        // with cross-user grant.
8150        return getContentProviderImpl(caller, name, null, stable, userId);
8151    }
8152
8153    public ContentProviderHolder getContentProviderExternal(
8154            String name, int userId, IBinder token) {
8155        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8156            "Do not have permission in call getContentProviderExternal()");
8157        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8158                false, true, "getContentProvider", null);
8159        return getContentProviderExternalUnchecked(name, token, userId);
8160    }
8161
8162    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8163            IBinder token, int userId) {
8164        return getContentProviderImpl(null, name, token, true, userId);
8165    }
8166
8167    /**
8168     * Drop a content provider from a ProcessRecord's bookkeeping
8169     */
8170    public void removeContentProvider(IBinder connection, boolean stable) {
8171        enforceNotIsolatedCaller("removeContentProvider");
8172        long ident = Binder.clearCallingIdentity();
8173        try {
8174            synchronized (this) {
8175                ContentProviderConnection conn;
8176                try {
8177                    conn = (ContentProviderConnection)connection;
8178                } catch (ClassCastException e) {
8179                    String msg ="removeContentProvider: " + connection
8180                            + " not a ContentProviderConnection";
8181                    Slog.w(TAG, msg);
8182                    throw new IllegalArgumentException(msg);
8183                }
8184                if (conn == null) {
8185                    throw new NullPointerException("connection is null");
8186                }
8187                if (decProviderCountLocked(conn, null, null, stable)) {
8188                    updateOomAdjLocked();
8189                }
8190            }
8191        } finally {
8192            Binder.restoreCallingIdentity(ident);
8193        }
8194    }
8195
8196    public void removeContentProviderExternal(String name, IBinder token) {
8197        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8198            "Do not have permission in call removeContentProviderExternal()");
8199        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8200    }
8201
8202    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8203        synchronized (this) {
8204            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8205            if(cpr == null) {
8206                //remove from mProvidersByClass
8207                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8208                return;
8209            }
8210
8211            //update content provider record entry info
8212            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8213            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8214            if (localCpr.hasExternalProcessHandles()) {
8215                if (localCpr.removeExternalProcessHandleLocked(token)) {
8216                    updateOomAdjLocked();
8217                } else {
8218                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8219                            + " with no external reference for token: "
8220                            + token + ".");
8221                }
8222            } else {
8223                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8224                        + " with no external references.");
8225            }
8226        }
8227    }
8228
8229    public final void publishContentProviders(IApplicationThread caller,
8230            List<ContentProviderHolder> providers) {
8231        if (providers == null) {
8232            return;
8233        }
8234
8235        enforceNotIsolatedCaller("publishContentProviders");
8236        synchronized (this) {
8237            final ProcessRecord r = getRecordForAppLocked(caller);
8238            if (DEBUG_MU)
8239                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8240            if (r == null) {
8241                throw new SecurityException(
8242                        "Unable to find app for caller " + caller
8243                      + " (pid=" + Binder.getCallingPid()
8244                      + ") when publishing content providers");
8245            }
8246
8247            final long origId = Binder.clearCallingIdentity();
8248
8249            final int N = providers.size();
8250            for (int i=0; i<N; i++) {
8251                ContentProviderHolder src = providers.get(i);
8252                if (src == null || src.info == null || src.provider == null) {
8253                    continue;
8254                }
8255                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8256                if (DEBUG_MU)
8257                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8258                if (dst != null) {
8259                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8260                    mProviderMap.putProviderByClass(comp, dst);
8261                    String names[] = dst.info.authority.split(";");
8262                    for (int j = 0; j < names.length; j++) {
8263                        mProviderMap.putProviderByName(names[j], dst);
8264                    }
8265
8266                    int NL = mLaunchingProviders.size();
8267                    int j;
8268                    for (j=0; j<NL; j++) {
8269                        if (mLaunchingProviders.get(j) == dst) {
8270                            mLaunchingProviders.remove(j);
8271                            j--;
8272                            NL--;
8273                        }
8274                    }
8275                    synchronized (dst) {
8276                        dst.provider = src.provider;
8277                        dst.proc = r;
8278                        dst.notifyAll();
8279                    }
8280                    updateOomAdjLocked(r);
8281                }
8282            }
8283
8284            Binder.restoreCallingIdentity(origId);
8285        }
8286    }
8287
8288    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8289        ContentProviderConnection conn;
8290        try {
8291            conn = (ContentProviderConnection)connection;
8292        } catch (ClassCastException e) {
8293            String msg ="refContentProvider: " + connection
8294                    + " not a ContentProviderConnection";
8295            Slog.w(TAG, msg);
8296            throw new IllegalArgumentException(msg);
8297        }
8298        if (conn == null) {
8299            throw new NullPointerException("connection is null");
8300        }
8301
8302        synchronized (this) {
8303            if (stable > 0) {
8304                conn.numStableIncs += stable;
8305            }
8306            stable = conn.stableCount + stable;
8307            if (stable < 0) {
8308                throw new IllegalStateException("stableCount < 0: " + stable);
8309            }
8310
8311            if (unstable > 0) {
8312                conn.numUnstableIncs += unstable;
8313            }
8314            unstable = conn.unstableCount + unstable;
8315            if (unstable < 0) {
8316                throw new IllegalStateException("unstableCount < 0: " + unstable);
8317            }
8318
8319            if ((stable+unstable) <= 0) {
8320                throw new IllegalStateException("ref counts can't go to zero here: stable="
8321                        + stable + " unstable=" + unstable);
8322            }
8323            conn.stableCount = stable;
8324            conn.unstableCount = unstable;
8325            return !conn.dead;
8326        }
8327    }
8328
8329    public void unstableProviderDied(IBinder connection) {
8330        ContentProviderConnection conn;
8331        try {
8332            conn = (ContentProviderConnection)connection;
8333        } catch (ClassCastException e) {
8334            String msg ="refContentProvider: " + connection
8335                    + " not a ContentProviderConnection";
8336            Slog.w(TAG, msg);
8337            throw new IllegalArgumentException(msg);
8338        }
8339        if (conn == null) {
8340            throw new NullPointerException("connection is null");
8341        }
8342
8343        // Safely retrieve the content provider associated with the connection.
8344        IContentProvider provider;
8345        synchronized (this) {
8346            provider = conn.provider.provider;
8347        }
8348
8349        if (provider == null) {
8350            // Um, yeah, we're way ahead of you.
8351            return;
8352        }
8353
8354        // Make sure the caller is being honest with us.
8355        if (provider.asBinder().pingBinder()) {
8356            // Er, no, still looks good to us.
8357            synchronized (this) {
8358                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8359                        + " says " + conn + " died, but we don't agree");
8360                return;
8361            }
8362        }
8363
8364        // Well look at that!  It's dead!
8365        synchronized (this) {
8366            if (conn.provider.provider != provider) {
8367                // But something changed...  good enough.
8368                return;
8369            }
8370
8371            ProcessRecord proc = conn.provider.proc;
8372            if (proc == null || proc.thread == null) {
8373                // Seems like the process is already cleaned up.
8374                return;
8375            }
8376
8377            // As far as we're concerned, this is just like receiving a
8378            // death notification...  just a bit prematurely.
8379            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8380                    + ") early provider death");
8381            final long ident = Binder.clearCallingIdentity();
8382            try {
8383                appDiedLocked(proc, proc.pid, proc.thread);
8384            } finally {
8385                Binder.restoreCallingIdentity(ident);
8386            }
8387        }
8388    }
8389
8390    @Override
8391    public void appNotRespondingViaProvider(IBinder connection) {
8392        enforceCallingPermission(
8393                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8394
8395        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8396        if (conn == null) {
8397            Slog.w(TAG, "ContentProviderConnection is null");
8398            return;
8399        }
8400
8401        final ProcessRecord host = conn.provider.proc;
8402        if (host == null) {
8403            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8404            return;
8405        }
8406
8407        final long token = Binder.clearCallingIdentity();
8408        try {
8409            appNotResponding(host, null, null, false, "ContentProvider not responding");
8410        } finally {
8411            Binder.restoreCallingIdentity(token);
8412        }
8413    }
8414
8415    public final void installSystemProviders() {
8416        List<ProviderInfo> providers;
8417        synchronized (this) {
8418            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8419            providers = generateApplicationProvidersLocked(app);
8420            if (providers != null) {
8421                for (int i=providers.size()-1; i>=0; i--) {
8422                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8423                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8424                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8425                                + ": not system .apk");
8426                        providers.remove(i);
8427                    }
8428                }
8429            }
8430        }
8431        if (providers != null) {
8432            mSystemThread.installSystemProviders(providers);
8433        }
8434
8435        mCoreSettingsObserver = new CoreSettingsObserver(this);
8436
8437        mUsageStatsService.monitorPackages();
8438    }
8439
8440    /**
8441     * Allows app to retrieve the MIME type of a URI without having permission
8442     * to access its content provider.
8443     *
8444     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8445     *
8446     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8447     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8448     */
8449    public String getProviderMimeType(Uri uri, int userId) {
8450        enforceNotIsolatedCaller("getProviderMimeType");
8451        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8452                userId, false, true, "getProviderMimeType", null);
8453        final String name = uri.getAuthority();
8454        final long ident = Binder.clearCallingIdentity();
8455        ContentProviderHolder holder = null;
8456
8457        try {
8458            holder = getContentProviderExternalUnchecked(name, null, userId);
8459            if (holder != null) {
8460                return holder.provider.getType(uri);
8461            }
8462        } catch (RemoteException e) {
8463            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8464            return null;
8465        } finally {
8466            if (holder != null) {
8467                removeContentProviderExternalUnchecked(name, null, userId);
8468            }
8469            Binder.restoreCallingIdentity(ident);
8470        }
8471
8472        return null;
8473    }
8474
8475    // =========================================================
8476    // GLOBAL MANAGEMENT
8477    // =========================================================
8478
8479    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8480            boolean isolated) {
8481        String proc = customProcess != null ? customProcess : info.processName;
8482        BatteryStatsImpl.Uid.Proc ps = null;
8483        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8484        int uid = info.uid;
8485        if (isolated) {
8486            int userId = UserHandle.getUserId(uid);
8487            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8488            while (true) {
8489                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8490                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8491                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8492                }
8493                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8494                mNextIsolatedProcessUid++;
8495                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8496                    // No process for this uid, use it.
8497                    break;
8498                }
8499                stepsLeft--;
8500                if (stepsLeft <= 0) {
8501                    return null;
8502                }
8503            }
8504        }
8505        return new ProcessRecord(stats, info, proc, uid);
8506    }
8507
8508    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8509        ProcessRecord app;
8510        if (!isolated) {
8511            app = getProcessRecordLocked(info.processName, info.uid, true);
8512        } else {
8513            app = null;
8514        }
8515
8516        if (app == null) {
8517            app = newProcessRecordLocked(info, null, isolated);
8518            mProcessNames.put(info.processName, app.uid, app);
8519            if (isolated) {
8520                mIsolatedProcesses.put(app.uid, app);
8521            }
8522            updateLruProcessLocked(app, false, null);
8523            updateOomAdjLocked();
8524        }
8525
8526        // This package really, really can not be stopped.
8527        try {
8528            AppGlobals.getPackageManager().setPackageStoppedState(
8529                    info.packageName, false, UserHandle.getUserId(app.uid));
8530        } catch (RemoteException e) {
8531        } catch (IllegalArgumentException e) {
8532            Slog.w(TAG, "Failed trying to unstop package "
8533                    + info.packageName + ": " + e);
8534        }
8535
8536        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8537                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8538            app.persistent = true;
8539            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8540        }
8541        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8542            mPersistentStartingProcesses.add(app);
8543            startProcessLocked(app, "added application", app.processName);
8544        }
8545
8546        return app;
8547    }
8548
8549    public void unhandledBack() {
8550        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8551                "unhandledBack()");
8552
8553        synchronized(this) {
8554            final long origId = Binder.clearCallingIdentity();
8555            try {
8556                getFocusedStack().unhandledBackLocked();
8557            } finally {
8558                Binder.restoreCallingIdentity(origId);
8559            }
8560        }
8561    }
8562
8563    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8564        enforceNotIsolatedCaller("openContentUri");
8565        final int userId = UserHandle.getCallingUserId();
8566        String name = uri.getAuthority();
8567        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8568        ParcelFileDescriptor pfd = null;
8569        if (cph != null) {
8570            // We record the binder invoker's uid in thread-local storage before
8571            // going to the content provider to open the file.  Later, in the code
8572            // that handles all permissions checks, we look for this uid and use
8573            // that rather than the Activity Manager's own uid.  The effect is that
8574            // we do the check against the caller's permissions even though it looks
8575            // to the content provider like the Activity Manager itself is making
8576            // the request.
8577            sCallerIdentity.set(new Identity(
8578                    Binder.getCallingPid(), Binder.getCallingUid()));
8579            try {
8580                pfd = cph.provider.openFile(null, uri, "r", null);
8581            } catch (FileNotFoundException e) {
8582                // do nothing; pfd will be returned null
8583            } finally {
8584                // Ensure that whatever happens, we clean up the identity state
8585                sCallerIdentity.remove();
8586            }
8587
8588            // We've got the fd now, so we're done with the provider.
8589            removeContentProviderExternalUnchecked(name, null, userId);
8590        } else {
8591            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8592        }
8593        return pfd;
8594    }
8595
8596    // Actually is sleeping or shutting down or whatever else in the future
8597    // is an inactive state.
8598    public boolean isSleepingOrShuttingDown() {
8599        return mSleeping || mShuttingDown;
8600    }
8601
8602    public boolean isSleeping() {
8603        return mSleeping;
8604    }
8605
8606    void goingToSleep() {
8607        synchronized(this) {
8608            mWentToSleep = true;
8609            updateEventDispatchingLocked();
8610            goToSleepIfNeededLocked();
8611        }
8612    }
8613
8614    void finishRunningVoiceLocked() {
8615        if (mRunningVoice) {
8616            mRunningVoice = false;
8617            goToSleepIfNeededLocked();
8618        }
8619    }
8620
8621    void goToSleepIfNeededLocked() {
8622        if (mWentToSleep && !mRunningVoice) {
8623            if (!mSleeping) {
8624                mSleeping = true;
8625                mStackSupervisor.goingToSleepLocked();
8626
8627                // Initialize the wake times of all processes.
8628                checkExcessivePowerUsageLocked(false);
8629                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8630                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8631                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8632            }
8633        }
8634    }
8635
8636    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
8637        mTaskPersister.notify(task, flush);
8638    }
8639
8640    @Override
8641    public boolean shutdown(int timeout) {
8642        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8643                != PackageManager.PERMISSION_GRANTED) {
8644            throw new SecurityException("Requires permission "
8645                    + android.Manifest.permission.SHUTDOWN);
8646        }
8647
8648        boolean timedout = false;
8649
8650        synchronized(this) {
8651            mShuttingDown = true;
8652            updateEventDispatchingLocked();
8653            timedout = mStackSupervisor.shutdownLocked(timeout);
8654        }
8655
8656        mAppOpsService.shutdown();
8657        mUsageStatsService.shutdown();
8658        mBatteryStatsService.shutdown();
8659        synchronized (this) {
8660            mProcessStats.shutdownLocked();
8661        }
8662        notifyTaskPersisterLocked(null, true);
8663
8664        return timedout;
8665    }
8666
8667    public final void activitySlept(IBinder token) {
8668        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8669
8670        final long origId = Binder.clearCallingIdentity();
8671
8672        synchronized (this) {
8673            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8674            if (r != null) {
8675                mStackSupervisor.activitySleptLocked(r);
8676            }
8677        }
8678
8679        Binder.restoreCallingIdentity(origId);
8680    }
8681
8682    void logLockScreen(String msg) {
8683        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8684                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8685                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8686                mStackSupervisor.mDismissKeyguardOnNextActivity);
8687    }
8688
8689    private void comeOutOfSleepIfNeededLocked() {
8690        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
8691            if (mSleeping) {
8692                mSleeping = false;
8693                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8694            }
8695        }
8696    }
8697
8698    void wakingUp() {
8699        synchronized(this) {
8700            mWentToSleep = false;
8701            updateEventDispatchingLocked();
8702            comeOutOfSleepIfNeededLocked();
8703        }
8704    }
8705
8706    void startRunningVoiceLocked() {
8707        if (!mRunningVoice) {
8708            mRunningVoice = true;
8709            comeOutOfSleepIfNeededLocked();
8710        }
8711    }
8712
8713    private void updateEventDispatchingLocked() {
8714        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8715    }
8716
8717    public void setLockScreenShown(boolean shown) {
8718        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8719                != PackageManager.PERMISSION_GRANTED) {
8720            throw new SecurityException("Requires permission "
8721                    + android.Manifest.permission.DEVICE_POWER);
8722        }
8723
8724        synchronized(this) {
8725            long ident = Binder.clearCallingIdentity();
8726            try {
8727                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8728                mLockScreenShown = shown;
8729                comeOutOfSleepIfNeededLocked();
8730            } finally {
8731                Binder.restoreCallingIdentity(ident);
8732            }
8733        }
8734    }
8735
8736    public void stopAppSwitches() {
8737        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8738                != PackageManager.PERMISSION_GRANTED) {
8739            throw new SecurityException("Requires permission "
8740                    + android.Manifest.permission.STOP_APP_SWITCHES);
8741        }
8742
8743        synchronized(this) {
8744            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8745                    + APP_SWITCH_DELAY_TIME;
8746            mDidAppSwitch = false;
8747            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8748            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8749            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8750        }
8751    }
8752
8753    public void resumeAppSwitches() {
8754        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8755                != PackageManager.PERMISSION_GRANTED) {
8756            throw new SecurityException("Requires permission "
8757                    + android.Manifest.permission.STOP_APP_SWITCHES);
8758        }
8759
8760        synchronized(this) {
8761            // Note that we don't execute any pending app switches... we will
8762            // let those wait until either the timeout, or the next start
8763            // activity request.
8764            mAppSwitchesAllowedTime = 0;
8765        }
8766    }
8767
8768    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8769            String name) {
8770        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8771            return true;
8772        }
8773
8774        final int perm = checkComponentPermission(
8775                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8776                callingUid, -1, true);
8777        if (perm == PackageManager.PERMISSION_GRANTED) {
8778            return true;
8779        }
8780
8781        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8782        return false;
8783    }
8784
8785    public void setDebugApp(String packageName, boolean waitForDebugger,
8786            boolean persistent) {
8787        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8788                "setDebugApp()");
8789
8790        long ident = Binder.clearCallingIdentity();
8791        try {
8792            // Note that this is not really thread safe if there are multiple
8793            // callers into it at the same time, but that's not a situation we
8794            // care about.
8795            if (persistent) {
8796                final ContentResolver resolver = mContext.getContentResolver();
8797                Settings.Global.putString(
8798                    resolver, Settings.Global.DEBUG_APP,
8799                    packageName);
8800                Settings.Global.putInt(
8801                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8802                    waitForDebugger ? 1 : 0);
8803            }
8804
8805            synchronized (this) {
8806                if (!persistent) {
8807                    mOrigDebugApp = mDebugApp;
8808                    mOrigWaitForDebugger = mWaitForDebugger;
8809                }
8810                mDebugApp = packageName;
8811                mWaitForDebugger = waitForDebugger;
8812                mDebugTransient = !persistent;
8813                if (packageName != null) {
8814                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8815                            false, UserHandle.USER_ALL, "set debug app");
8816                }
8817            }
8818        } finally {
8819            Binder.restoreCallingIdentity(ident);
8820        }
8821    }
8822
8823    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8824        synchronized (this) {
8825            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8826            if (!isDebuggable) {
8827                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8828                    throw new SecurityException("Process not debuggable: " + app.packageName);
8829                }
8830            }
8831
8832            mOpenGlTraceApp = processName;
8833        }
8834    }
8835
8836    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8837            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8838        synchronized (this) {
8839            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8840            if (!isDebuggable) {
8841                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8842                    throw new SecurityException("Process not debuggable: " + app.packageName);
8843                }
8844            }
8845            mProfileApp = processName;
8846            mProfileFile = profileFile;
8847            if (mProfileFd != null) {
8848                try {
8849                    mProfileFd.close();
8850                } catch (IOException e) {
8851                }
8852                mProfileFd = null;
8853            }
8854            mProfileFd = profileFd;
8855            mProfileType = 0;
8856            mAutoStopProfiler = autoStopProfiler;
8857        }
8858    }
8859
8860    @Override
8861    public void setAlwaysFinish(boolean enabled) {
8862        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8863                "setAlwaysFinish()");
8864
8865        Settings.Global.putInt(
8866                mContext.getContentResolver(),
8867                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8868
8869        synchronized (this) {
8870            mAlwaysFinishActivities = enabled;
8871        }
8872    }
8873
8874    @Override
8875    public void setActivityController(IActivityController controller) {
8876        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8877                "setActivityController()");
8878        synchronized (this) {
8879            mController = controller;
8880            Watchdog.getInstance().setActivityController(controller);
8881        }
8882    }
8883
8884    @Override
8885    public void setUserIsMonkey(boolean userIsMonkey) {
8886        synchronized (this) {
8887            synchronized (mPidsSelfLocked) {
8888                final int callingPid = Binder.getCallingPid();
8889                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8890                if (precessRecord == null) {
8891                    throw new SecurityException("Unknown process: " + callingPid);
8892                }
8893                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8894                    throw new SecurityException("Only an instrumentation process "
8895                            + "with a UiAutomation can call setUserIsMonkey");
8896                }
8897            }
8898            mUserIsMonkey = userIsMonkey;
8899        }
8900    }
8901
8902    @Override
8903    public boolean isUserAMonkey() {
8904        synchronized (this) {
8905            // If there is a controller also implies the user is a monkey.
8906            return (mUserIsMonkey || mController != null);
8907        }
8908    }
8909
8910    public void requestBugReport() {
8911        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8912        SystemProperties.set("ctl.start", "bugreport");
8913    }
8914
8915    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8916        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8917    }
8918
8919    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8920        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8921            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8922        }
8923        return KEY_DISPATCHING_TIMEOUT;
8924    }
8925
8926    @Override
8927    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8928        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8929                != PackageManager.PERMISSION_GRANTED) {
8930            throw new SecurityException("Requires permission "
8931                    + android.Manifest.permission.FILTER_EVENTS);
8932        }
8933        ProcessRecord proc;
8934        long timeout;
8935        synchronized (this) {
8936            synchronized (mPidsSelfLocked) {
8937                proc = mPidsSelfLocked.get(pid);
8938            }
8939            timeout = getInputDispatchingTimeoutLocked(proc);
8940        }
8941
8942        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8943            return -1;
8944        }
8945
8946        return timeout;
8947    }
8948
8949    /**
8950     * Handle input dispatching timeouts.
8951     * Returns whether input dispatching should be aborted or not.
8952     */
8953    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8954            final ActivityRecord activity, final ActivityRecord parent,
8955            final boolean aboveSystem, String reason) {
8956        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8957                != PackageManager.PERMISSION_GRANTED) {
8958            throw new SecurityException("Requires permission "
8959                    + android.Manifest.permission.FILTER_EVENTS);
8960        }
8961
8962        final String annotation;
8963        if (reason == null) {
8964            annotation = "Input dispatching timed out";
8965        } else {
8966            annotation = "Input dispatching timed out (" + reason + ")";
8967        }
8968
8969        if (proc != null) {
8970            synchronized (this) {
8971                if (proc.debugging) {
8972                    return false;
8973                }
8974
8975                if (mDidDexOpt) {
8976                    // Give more time since we were dexopting.
8977                    mDidDexOpt = false;
8978                    return false;
8979                }
8980
8981                if (proc.instrumentationClass != null) {
8982                    Bundle info = new Bundle();
8983                    info.putString("shortMsg", "keyDispatchingTimedOut");
8984                    info.putString("longMsg", annotation);
8985                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8986                    return true;
8987                }
8988            }
8989            mHandler.post(new Runnable() {
8990                @Override
8991                public void run() {
8992                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
8993                }
8994            });
8995        }
8996
8997        return true;
8998    }
8999
9000    public Bundle getAssistContextExtras(int requestType) {
9001        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9002                "getAssistContextExtras()");
9003        PendingAssistExtras pae;
9004        Bundle extras = new Bundle();
9005        synchronized (this) {
9006            ActivityRecord activity = getFocusedStack().mResumedActivity;
9007            if (activity == null) {
9008                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9009                return null;
9010            }
9011            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9012            if (activity.app == null || activity.app.thread == null) {
9013                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9014                return extras;
9015            }
9016            if (activity.app.pid == Binder.getCallingPid()) {
9017                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9018                return extras;
9019            }
9020            pae = new PendingAssistExtras(activity);
9021            try {
9022                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9023                        requestType);
9024                mPendingAssistExtras.add(pae);
9025                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9026            } catch (RemoteException e) {
9027                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9028                return extras;
9029            }
9030        }
9031        synchronized (pae) {
9032            while (!pae.haveResult) {
9033                try {
9034                    pae.wait();
9035                } catch (InterruptedException e) {
9036                }
9037            }
9038            if (pae.result != null) {
9039                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9040            }
9041        }
9042        synchronized (this) {
9043            mPendingAssistExtras.remove(pae);
9044            mHandler.removeCallbacks(pae);
9045        }
9046        return extras;
9047    }
9048
9049    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9050        PendingAssistExtras pae = (PendingAssistExtras)token;
9051        synchronized (pae) {
9052            pae.result = extras;
9053            pae.haveResult = true;
9054            pae.notifyAll();
9055        }
9056    }
9057
9058    public void registerProcessObserver(IProcessObserver observer) {
9059        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9060                "registerProcessObserver()");
9061        synchronized (this) {
9062            mProcessObservers.register(observer);
9063        }
9064    }
9065
9066    @Override
9067    public void unregisterProcessObserver(IProcessObserver observer) {
9068        synchronized (this) {
9069            mProcessObservers.unregister(observer);
9070        }
9071    }
9072
9073    @Override
9074    public boolean convertFromTranslucent(IBinder token) {
9075        final long origId = Binder.clearCallingIdentity();
9076        try {
9077            synchronized (this) {
9078                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9079                if (r == null) {
9080                    return false;
9081                }
9082                if (r.changeWindowTranslucency(true)) {
9083                    mWindowManager.setAppFullscreen(token, true);
9084                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9085                    return true;
9086                }
9087                return false;
9088            }
9089        } finally {
9090            Binder.restoreCallingIdentity(origId);
9091        }
9092    }
9093
9094    @Override
9095    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9096        final long origId = Binder.clearCallingIdentity();
9097        try {
9098            synchronized (this) {
9099                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9100                if (r == null) {
9101                    return false;
9102                }
9103                if (r.changeWindowTranslucency(false)) {
9104                    r.task.stack.convertToTranslucent(r, options);
9105                    mWindowManager.setAppFullscreen(token, false);
9106                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9107                    return true;
9108                }
9109                return false;
9110            }
9111        } finally {
9112            Binder.restoreCallingIdentity(origId);
9113        }
9114    }
9115
9116    @Override
9117    public ActivityOptions getActivityOptions(IBinder token) {
9118        final long origId = Binder.clearCallingIdentity();
9119        try {
9120            synchronized (this) {
9121                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9122                if (r != null) {
9123                    final ActivityOptions activityOptions = r.pendingOptions;
9124                    r.pendingOptions = null;
9125                    return activityOptions;
9126                }
9127                return null;
9128            }
9129        } finally {
9130            Binder.restoreCallingIdentity(origId);
9131        }
9132    }
9133
9134    @Override
9135    public void setImmersive(IBinder token, boolean immersive) {
9136        synchronized(this) {
9137            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9138            if (r == null) {
9139                throw new IllegalArgumentException();
9140            }
9141            r.immersive = immersive;
9142
9143            // update associated state if we're frontmost
9144            if (r == mFocusedActivity) {
9145                if (DEBUG_IMMERSIVE) {
9146                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9147                }
9148                applyUpdateLockStateLocked(r);
9149            }
9150        }
9151    }
9152
9153    @Override
9154    public boolean isImmersive(IBinder token) {
9155        synchronized (this) {
9156            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9157            if (r == null) {
9158                throw new IllegalArgumentException();
9159            }
9160            return r.immersive;
9161        }
9162    }
9163
9164    public boolean isTopActivityImmersive() {
9165        enforceNotIsolatedCaller("startActivity");
9166        synchronized (this) {
9167            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9168            return (r != null) ? r.immersive : false;
9169        }
9170    }
9171
9172    public final void enterSafeMode() {
9173        synchronized(this) {
9174            // It only makes sense to do this before the system is ready
9175            // and started launching other packages.
9176            if (!mSystemReady) {
9177                try {
9178                    AppGlobals.getPackageManager().enterSafeMode();
9179                } catch (RemoteException e) {
9180                }
9181            }
9182
9183            mSafeMode = true;
9184        }
9185    }
9186
9187    public final void showSafeModeOverlay() {
9188        View v = LayoutInflater.from(mContext).inflate(
9189                com.android.internal.R.layout.safe_mode, null);
9190        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9191        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9192        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9193        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9194        lp.gravity = Gravity.BOTTOM | Gravity.START;
9195        lp.format = v.getBackground().getOpacity();
9196        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9197                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9198        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9199        ((WindowManager)mContext.getSystemService(
9200                Context.WINDOW_SERVICE)).addView(v, lp);
9201    }
9202
9203    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9204        if (!(sender instanceof PendingIntentRecord)) {
9205            return;
9206        }
9207        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9208        synchronized (stats) {
9209            if (mBatteryStatsService.isOnBattery()) {
9210                mBatteryStatsService.enforceCallingPermission();
9211                PendingIntentRecord rec = (PendingIntentRecord)sender;
9212                int MY_UID = Binder.getCallingUid();
9213                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9214                BatteryStatsImpl.Uid.Pkg pkg =
9215                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9216                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9217                pkg.incWakeupsLocked();
9218            }
9219        }
9220    }
9221
9222    public boolean killPids(int[] pids, String pReason, boolean secure) {
9223        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9224            throw new SecurityException("killPids only available to the system");
9225        }
9226        String reason = (pReason == null) ? "Unknown" : pReason;
9227        // XXX Note: don't acquire main activity lock here, because the window
9228        // manager calls in with its locks held.
9229
9230        boolean killed = false;
9231        synchronized (mPidsSelfLocked) {
9232            int[] types = new int[pids.length];
9233            int worstType = 0;
9234            for (int i=0; i<pids.length; i++) {
9235                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9236                if (proc != null) {
9237                    int type = proc.setAdj;
9238                    types[i] = type;
9239                    if (type > worstType) {
9240                        worstType = type;
9241                    }
9242                }
9243            }
9244
9245            // If the worst oom_adj is somewhere in the cached proc LRU range,
9246            // then constrain it so we will kill all cached procs.
9247            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9248                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9249                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9250            }
9251
9252            // If this is not a secure call, don't let it kill processes that
9253            // are important.
9254            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9255                worstType = ProcessList.SERVICE_ADJ;
9256            }
9257
9258            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9259            for (int i=0; i<pids.length; i++) {
9260                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9261                if (proc == null) {
9262                    continue;
9263                }
9264                int adj = proc.setAdj;
9265                if (adj >= worstType && !proc.killedByAm) {
9266                    killUnneededProcessLocked(proc, reason);
9267                    killed = true;
9268                }
9269            }
9270        }
9271        return killed;
9272    }
9273
9274    @Override
9275    public void killUid(int uid, String reason) {
9276        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9277            throw new SecurityException("killUid only available to the system");
9278        }
9279        synchronized (this) {
9280            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9281                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9282                    reason != null ? reason : "kill uid");
9283        }
9284    }
9285
9286    @Override
9287    public boolean killProcessesBelowForeground(String reason) {
9288        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9289            throw new SecurityException("killProcessesBelowForeground() only available to system");
9290        }
9291
9292        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9293    }
9294
9295    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9296        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9297            throw new SecurityException("killProcessesBelowAdj() only available to system");
9298        }
9299
9300        boolean killed = false;
9301        synchronized (mPidsSelfLocked) {
9302            final int size = mPidsSelfLocked.size();
9303            for (int i = 0; i < size; i++) {
9304                final int pid = mPidsSelfLocked.keyAt(i);
9305                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9306                if (proc == null) continue;
9307
9308                final int adj = proc.setAdj;
9309                if (adj > belowAdj && !proc.killedByAm) {
9310                    killUnneededProcessLocked(proc, reason);
9311                    killed = true;
9312                }
9313            }
9314        }
9315        return killed;
9316    }
9317
9318    @Override
9319    public void hang(final IBinder who, boolean allowRestart) {
9320        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9321                != PackageManager.PERMISSION_GRANTED) {
9322            throw new SecurityException("Requires permission "
9323                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9324        }
9325
9326        final IBinder.DeathRecipient death = new DeathRecipient() {
9327            @Override
9328            public void binderDied() {
9329                synchronized (this) {
9330                    notifyAll();
9331                }
9332            }
9333        };
9334
9335        try {
9336            who.linkToDeath(death, 0);
9337        } catch (RemoteException e) {
9338            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9339            return;
9340        }
9341
9342        synchronized (this) {
9343            Watchdog.getInstance().setAllowRestart(allowRestart);
9344            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9345            synchronized (death) {
9346                while (who.isBinderAlive()) {
9347                    try {
9348                        death.wait();
9349                    } catch (InterruptedException e) {
9350                    }
9351                }
9352            }
9353            Watchdog.getInstance().setAllowRestart(true);
9354        }
9355    }
9356
9357    @Override
9358    public void restart() {
9359        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9360                != PackageManager.PERMISSION_GRANTED) {
9361            throw new SecurityException("Requires permission "
9362                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9363        }
9364
9365        Log.i(TAG, "Sending shutdown broadcast...");
9366
9367        BroadcastReceiver br = new BroadcastReceiver() {
9368            @Override public void onReceive(Context context, Intent intent) {
9369                // Now the broadcast is done, finish up the low-level shutdown.
9370                Log.i(TAG, "Shutting down activity manager...");
9371                shutdown(10000);
9372                Log.i(TAG, "Shutdown complete, restarting!");
9373                Process.killProcess(Process.myPid());
9374                System.exit(10);
9375            }
9376        };
9377
9378        // First send the high-level shut down broadcast.
9379        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9380        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9381        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9382        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9383        mContext.sendOrderedBroadcastAsUser(intent,
9384                UserHandle.ALL, null, br, mHandler, 0, null, null);
9385        */
9386        br.onReceive(mContext, intent);
9387    }
9388
9389    private long getLowRamTimeSinceIdle(long now) {
9390        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9391    }
9392
9393    @Override
9394    public void performIdleMaintenance() {
9395        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9396                != PackageManager.PERMISSION_GRANTED) {
9397            throw new SecurityException("Requires permission "
9398                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9399        }
9400
9401        synchronized (this) {
9402            final long now = SystemClock.uptimeMillis();
9403            final long timeSinceLastIdle = now - mLastIdleTime;
9404            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9405            mLastIdleTime = now;
9406            mLowRamTimeSinceLastIdle = 0;
9407            if (mLowRamStartTime != 0) {
9408                mLowRamStartTime = now;
9409            }
9410
9411            StringBuilder sb = new StringBuilder(128);
9412            sb.append("Idle maintenance over ");
9413            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9414            sb.append(" low RAM for ");
9415            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9416            Slog.i(TAG, sb.toString());
9417
9418            // If at least 1/3 of our time since the last idle period has been spent
9419            // with RAM low, then we want to kill processes.
9420            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9421
9422            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9423                ProcessRecord proc = mLruProcesses.get(i);
9424                if (proc.notCachedSinceIdle) {
9425                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9426                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9427                        if (doKilling && proc.initialIdlePss != 0
9428                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9429                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9430                                    + " from " + proc.initialIdlePss + ")");
9431                        }
9432                    }
9433                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9434                    proc.notCachedSinceIdle = true;
9435                    proc.initialIdlePss = 0;
9436                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9437                            isSleeping(), now);
9438                }
9439            }
9440
9441            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9442            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9443        }
9444    }
9445
9446    private void retrieveSettings() {
9447        final ContentResolver resolver = mContext.getContentResolver();
9448        String debugApp = Settings.Global.getString(
9449            resolver, Settings.Global.DEBUG_APP);
9450        boolean waitForDebugger = Settings.Global.getInt(
9451            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9452        boolean alwaysFinishActivities = Settings.Global.getInt(
9453            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9454        boolean forceRtl = Settings.Global.getInt(
9455                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9456        // Transfer any global setting for forcing RTL layout, into a System Property
9457        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9458
9459        Configuration configuration = new Configuration();
9460        Settings.System.getConfiguration(resolver, configuration);
9461        if (forceRtl) {
9462            // This will take care of setting the correct layout direction flags
9463            configuration.setLayoutDirection(configuration.locale);
9464        }
9465
9466        synchronized (this) {
9467            mDebugApp = mOrigDebugApp = debugApp;
9468            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9469            mAlwaysFinishActivities = alwaysFinishActivities;
9470            // This happens before any activities are started, so we can
9471            // change mConfiguration in-place.
9472            updateConfigurationLocked(configuration, null, false, true);
9473            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9474        }
9475    }
9476
9477    public boolean testIsSystemReady() {
9478        // no need to synchronize(this) just to read & return the value
9479        return mSystemReady;
9480    }
9481
9482    private static File getCalledPreBootReceiversFile() {
9483        File dataDir = Environment.getDataDirectory();
9484        File systemDir = new File(dataDir, "system");
9485        File fname = new File(systemDir, "called_pre_boots.dat");
9486        return fname;
9487    }
9488
9489    static final int LAST_DONE_VERSION = 10000;
9490
9491    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9492        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9493        File file = getCalledPreBootReceiversFile();
9494        FileInputStream fis = null;
9495        try {
9496            fis = new FileInputStream(file);
9497            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9498            int fvers = dis.readInt();
9499            if (fvers == LAST_DONE_VERSION) {
9500                String vers = dis.readUTF();
9501                String codename = dis.readUTF();
9502                String build = dis.readUTF();
9503                if (android.os.Build.VERSION.RELEASE.equals(vers)
9504                        && android.os.Build.VERSION.CODENAME.equals(codename)
9505                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9506                    int num = dis.readInt();
9507                    while (num > 0) {
9508                        num--;
9509                        String pkg = dis.readUTF();
9510                        String cls = dis.readUTF();
9511                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9512                    }
9513                }
9514            }
9515        } catch (FileNotFoundException e) {
9516        } catch (IOException e) {
9517            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9518        } finally {
9519            if (fis != null) {
9520                try {
9521                    fis.close();
9522                } catch (IOException e) {
9523                }
9524            }
9525        }
9526        return lastDoneReceivers;
9527    }
9528
9529    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9530        File file = getCalledPreBootReceiversFile();
9531        FileOutputStream fos = null;
9532        DataOutputStream dos = null;
9533        try {
9534            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9535            fos = new FileOutputStream(file);
9536            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9537            dos.writeInt(LAST_DONE_VERSION);
9538            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9539            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9540            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9541            dos.writeInt(list.size());
9542            for (int i=0; i<list.size(); i++) {
9543                dos.writeUTF(list.get(i).getPackageName());
9544                dos.writeUTF(list.get(i).getClassName());
9545            }
9546        } catch (IOException e) {
9547            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9548            file.delete();
9549        } finally {
9550            FileUtils.sync(fos);
9551            if (dos != null) {
9552                try {
9553                    dos.close();
9554                } catch (IOException e) {
9555                    // TODO Auto-generated catch block
9556                    e.printStackTrace();
9557                }
9558            }
9559        }
9560    }
9561
9562    public void systemReady(final Runnable goingCallback) {
9563        synchronized(this) {
9564            if (mSystemReady) {
9565                if (goingCallback != null) goingCallback.run();
9566                return;
9567            }
9568
9569            mRecentTasks = mTaskPersister.restoreTasksLocked();
9570            if (!mRecentTasks.isEmpty()) {
9571                mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
9572            }
9573            mTaskPersister.startPersisting();
9574
9575            // Check to see if there are any update receivers to run.
9576            if (!mDidUpdate) {
9577                if (mWaitingUpdate) {
9578                    return;
9579                }
9580                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9581                List<ResolveInfo> ris = null;
9582                try {
9583                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9584                            intent, null, 0, 0);
9585                } catch (RemoteException e) {
9586                }
9587                if (ris != null) {
9588                    for (int i=ris.size()-1; i>=0; i--) {
9589                        if ((ris.get(i).activityInfo.applicationInfo.flags
9590                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9591                            ris.remove(i);
9592                        }
9593                    }
9594                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9595
9596                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9597
9598                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9599                    for (int i=0; i<ris.size(); i++) {
9600                        ActivityInfo ai = ris.get(i).activityInfo;
9601                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9602                        if (lastDoneReceivers.contains(comp)) {
9603                            // We already did the pre boot receiver for this app with the current
9604                            // platform version, so don't do it again...
9605                            ris.remove(i);
9606                            i--;
9607                            // ...however, do keep it as one that has been done, so we don't
9608                            // forget about it when rewriting the file of last done receivers.
9609                            doneReceivers.add(comp);
9610                        }
9611                    }
9612
9613                    final int[] users = getUsersLocked();
9614                    for (int i=0; i<ris.size(); i++) {
9615                        ActivityInfo ai = ris.get(i).activityInfo;
9616                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9617                        doneReceivers.add(comp);
9618                        intent.setComponent(comp);
9619                        for (int j=0; j<users.length; j++) {
9620                            IIntentReceiver finisher = null;
9621                            if (i == ris.size()-1 && j == users.length-1) {
9622                                finisher = new IIntentReceiver.Stub() {
9623                                    public void performReceive(Intent intent, int resultCode,
9624                                            String data, Bundle extras, boolean ordered,
9625                                            boolean sticky, int sendingUser) {
9626                                        // The raw IIntentReceiver interface is called
9627                                        // with the AM lock held, so redispatch to
9628                                        // execute our code without the lock.
9629                                        mHandler.post(new Runnable() {
9630                                            public void run() {
9631                                                synchronized (ActivityManagerService.this) {
9632                                                    mDidUpdate = true;
9633                                                }
9634                                                writeLastDonePreBootReceivers(doneReceivers);
9635                                                showBootMessage(mContext.getText(
9636                                                        R.string.android_upgrading_complete),
9637                                                        false);
9638                                                systemReady(goingCallback);
9639                                            }
9640                                        });
9641                                    }
9642                                };
9643                            }
9644                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9645                                    + " for user " + users[j]);
9646                            broadcastIntentLocked(null, null, intent, null, finisher,
9647                                    0, null, null, null, AppOpsManager.OP_NONE,
9648                                    true, false, MY_PID, Process.SYSTEM_UID,
9649                                    users[j]);
9650                            if (finisher != null) {
9651                                mWaitingUpdate = true;
9652                            }
9653                        }
9654                    }
9655                }
9656                if (mWaitingUpdate) {
9657                    return;
9658                }
9659                mDidUpdate = true;
9660            }
9661
9662            mAppOpsService.systemReady();
9663            mUsageStatsService.systemReady();
9664            mSystemReady = true;
9665        }
9666
9667        ArrayList<ProcessRecord> procsToKill = null;
9668        synchronized(mPidsSelfLocked) {
9669            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9670                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9671                if (!isAllowedWhileBooting(proc.info)){
9672                    if (procsToKill == null) {
9673                        procsToKill = new ArrayList<ProcessRecord>();
9674                    }
9675                    procsToKill.add(proc);
9676                }
9677            }
9678        }
9679
9680        synchronized(this) {
9681            if (procsToKill != null) {
9682                for (int i=procsToKill.size()-1; i>=0; i--) {
9683                    ProcessRecord proc = procsToKill.get(i);
9684                    Slog.i(TAG, "Removing system update proc: " + proc);
9685                    removeProcessLocked(proc, true, false, "system update done");
9686                }
9687            }
9688
9689            // Now that we have cleaned up any update processes, we
9690            // are ready to start launching real processes and know that
9691            // we won't trample on them any more.
9692            mProcessesReady = true;
9693        }
9694
9695        Slog.i(TAG, "System now ready");
9696        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9697            SystemClock.uptimeMillis());
9698
9699        synchronized(this) {
9700            // Make sure we have no pre-ready processes sitting around.
9701
9702            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9703                ResolveInfo ri = mContext.getPackageManager()
9704                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9705                                STOCK_PM_FLAGS);
9706                CharSequence errorMsg = null;
9707                if (ri != null) {
9708                    ActivityInfo ai = ri.activityInfo;
9709                    ApplicationInfo app = ai.applicationInfo;
9710                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9711                        mTopAction = Intent.ACTION_FACTORY_TEST;
9712                        mTopData = null;
9713                        mTopComponent = new ComponentName(app.packageName,
9714                                ai.name);
9715                    } else {
9716                        errorMsg = mContext.getResources().getText(
9717                                com.android.internal.R.string.factorytest_not_system);
9718                    }
9719                } else {
9720                    errorMsg = mContext.getResources().getText(
9721                            com.android.internal.R.string.factorytest_no_action);
9722                }
9723                if (errorMsg != null) {
9724                    mTopAction = null;
9725                    mTopData = null;
9726                    mTopComponent = null;
9727                    Message msg = Message.obtain();
9728                    msg.what = SHOW_FACTORY_ERROR_MSG;
9729                    msg.getData().putCharSequence("msg", errorMsg);
9730                    mHandler.sendMessage(msg);
9731                }
9732            }
9733        }
9734
9735        retrieveSettings();
9736
9737        synchronized (this) {
9738            readGrantedUriPermissionsLocked();
9739        }
9740
9741        if (goingCallback != null) goingCallback.run();
9742
9743        mSystemServiceManager.startUser(mCurrentUserId);
9744
9745        synchronized (this) {
9746            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9747                try {
9748                    List apps = AppGlobals.getPackageManager().
9749                        getPersistentApplications(STOCK_PM_FLAGS);
9750                    if (apps != null) {
9751                        int N = apps.size();
9752                        int i;
9753                        for (i=0; i<N; i++) {
9754                            ApplicationInfo info
9755                                = (ApplicationInfo)apps.get(i);
9756                            if (info != null &&
9757                                    !info.packageName.equals("android")) {
9758                                addAppLocked(info, false);
9759                            }
9760                        }
9761                    }
9762                } catch (RemoteException ex) {
9763                    // pm is in same process, this will never happen.
9764                }
9765            }
9766
9767            // Start up initial activity.
9768            mBooting = true;
9769
9770            try {
9771                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9772                    Message msg = Message.obtain();
9773                    msg.what = SHOW_UID_ERROR_MSG;
9774                    mHandler.sendMessage(msg);
9775                }
9776            } catch (RemoteException e) {
9777            }
9778
9779            long ident = Binder.clearCallingIdentity();
9780            try {
9781                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9782                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9783                        | Intent.FLAG_RECEIVER_FOREGROUND);
9784                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9785                broadcastIntentLocked(null, null, intent,
9786                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9787                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9788                intent = new Intent(Intent.ACTION_USER_STARTING);
9789                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9790                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9791                broadcastIntentLocked(null, null, intent,
9792                        null, new IIntentReceiver.Stub() {
9793                            @Override
9794                            public void performReceive(Intent intent, int resultCode, String data,
9795                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9796                                    throws RemoteException {
9797                            }
9798                        }, 0, null, null,
9799                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9800                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9801            } catch (Throwable t) {
9802                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
9803            } finally {
9804                Binder.restoreCallingIdentity(ident);
9805            }
9806            mStackSupervisor.resumeTopActivitiesLocked();
9807            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9808        }
9809    }
9810
9811    private boolean makeAppCrashingLocked(ProcessRecord app,
9812            String shortMsg, String longMsg, String stackTrace) {
9813        app.crashing = true;
9814        app.crashingReport = generateProcessError(app,
9815                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9816        startAppProblemLocked(app);
9817        app.stopFreezingAllLocked();
9818        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9819    }
9820
9821    private void makeAppNotRespondingLocked(ProcessRecord app,
9822            String activity, String shortMsg, String longMsg) {
9823        app.notResponding = true;
9824        app.notRespondingReport = generateProcessError(app,
9825                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9826                activity, shortMsg, longMsg, null);
9827        startAppProblemLocked(app);
9828        app.stopFreezingAllLocked();
9829    }
9830
9831    /**
9832     * Generate a process error record, suitable for attachment to a ProcessRecord.
9833     *
9834     * @param app The ProcessRecord in which the error occurred.
9835     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9836     *                      ActivityManager.AppErrorStateInfo
9837     * @param activity The activity associated with the crash, if known.
9838     * @param shortMsg Short message describing the crash.
9839     * @param longMsg Long message describing the crash.
9840     * @param stackTrace Full crash stack trace, may be null.
9841     *
9842     * @return Returns a fully-formed AppErrorStateInfo record.
9843     */
9844    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9845            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9846        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9847
9848        report.condition = condition;
9849        report.processName = app.processName;
9850        report.pid = app.pid;
9851        report.uid = app.info.uid;
9852        report.tag = activity;
9853        report.shortMsg = shortMsg;
9854        report.longMsg = longMsg;
9855        report.stackTrace = stackTrace;
9856
9857        return report;
9858    }
9859
9860    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9861        synchronized (this) {
9862            app.crashing = false;
9863            app.crashingReport = null;
9864            app.notResponding = false;
9865            app.notRespondingReport = null;
9866            if (app.anrDialog == fromDialog) {
9867                app.anrDialog = null;
9868            }
9869            if (app.waitDialog == fromDialog) {
9870                app.waitDialog = null;
9871            }
9872            if (app.pid > 0 && app.pid != MY_PID) {
9873                handleAppCrashLocked(app, null, null, null);
9874                killUnneededProcessLocked(app, "user request after error");
9875            }
9876        }
9877    }
9878
9879    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9880            String stackTrace) {
9881        long now = SystemClock.uptimeMillis();
9882
9883        Long crashTime;
9884        if (!app.isolated) {
9885            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9886        } else {
9887            crashTime = null;
9888        }
9889        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9890            // This process loses!
9891            Slog.w(TAG, "Process " + app.info.processName
9892                    + " has crashed too many times: killing!");
9893            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9894                    app.userId, app.info.processName, app.uid);
9895            mStackSupervisor.handleAppCrashLocked(app);
9896            if (!app.persistent) {
9897                // We don't want to start this process again until the user
9898                // explicitly does so...  but for persistent process, we really
9899                // need to keep it running.  If a persistent process is actually
9900                // repeatedly crashing, then badness for everyone.
9901                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9902                        app.info.processName);
9903                if (!app.isolated) {
9904                    // XXX We don't have a way to mark isolated processes
9905                    // as bad, since they don't have a peristent identity.
9906                    mBadProcesses.put(app.info.processName, app.uid,
9907                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9908                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9909                }
9910                app.bad = true;
9911                app.removed = true;
9912                // Don't let services in this process be restarted and potentially
9913                // annoy the user repeatedly.  Unless it is persistent, since those
9914                // processes run critical code.
9915                removeProcessLocked(app, false, false, "crash");
9916                mStackSupervisor.resumeTopActivitiesLocked();
9917                return false;
9918            }
9919            mStackSupervisor.resumeTopActivitiesLocked();
9920        } else {
9921            mStackSupervisor.finishTopRunningActivityLocked(app);
9922        }
9923
9924        // Bump up the crash count of any services currently running in the proc.
9925        for (int i=app.services.size()-1; i>=0; i--) {
9926            // Any services running in the application need to be placed
9927            // back in the pending list.
9928            ServiceRecord sr = app.services.valueAt(i);
9929            sr.crashCount++;
9930        }
9931
9932        // If the crashing process is what we consider to be the "home process" and it has been
9933        // replaced by a third-party app, clear the package preferred activities from packages
9934        // with a home activity running in the process to prevent a repeatedly crashing app
9935        // from blocking the user to manually clear the list.
9936        final ArrayList<ActivityRecord> activities = app.activities;
9937        if (app == mHomeProcess && activities.size() > 0
9938                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9939            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9940                final ActivityRecord r = activities.get(activityNdx);
9941                if (r.isHomeActivity()) {
9942                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9943                    try {
9944                        ActivityThread.getPackageManager()
9945                                .clearPackagePreferredActivities(r.packageName);
9946                    } catch (RemoteException c) {
9947                        // pm is in same process, this will never happen.
9948                    }
9949                }
9950            }
9951        }
9952
9953        if (!app.isolated) {
9954            // XXX Can't keep track of crash times for isolated processes,
9955            // because they don't have a perisistent identity.
9956            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9957        }
9958
9959        return true;
9960    }
9961
9962    void startAppProblemLocked(ProcessRecord app) {
9963        if (app.userId == mCurrentUserId) {
9964            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9965                    mContext, app.info.packageName, app.info.flags);
9966        } else {
9967            // If this app is not running under the current user, then we
9968            // can't give it a report button because that would require
9969            // launching the report UI under a different user.
9970            app.errorReportReceiver = null;
9971        }
9972        skipCurrentReceiverLocked(app);
9973    }
9974
9975    void skipCurrentReceiverLocked(ProcessRecord app) {
9976        for (BroadcastQueue queue : mBroadcastQueues) {
9977            queue.skipCurrentReceiverLocked(app);
9978        }
9979    }
9980
9981    /**
9982     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9983     * The application process will exit immediately after this call returns.
9984     * @param app object of the crashing app, null for the system server
9985     * @param crashInfo describing the exception
9986     */
9987    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9988        ProcessRecord r = findAppProcess(app, "Crash");
9989        final String processName = app == null ? "system_server"
9990                : (r == null ? "unknown" : r.processName);
9991
9992        handleApplicationCrashInner("crash", r, processName, crashInfo);
9993    }
9994
9995    /* Native crash reporting uses this inner version because it needs to be somewhat
9996     * decoupled from the AM-managed cleanup lifecycle
9997     */
9998    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
9999            ApplicationErrorReport.CrashInfo crashInfo) {
10000        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10001                UserHandle.getUserId(Binder.getCallingUid()), processName,
10002                r == null ? -1 : r.info.flags,
10003                crashInfo.exceptionClassName,
10004                crashInfo.exceptionMessage,
10005                crashInfo.throwFileName,
10006                crashInfo.throwLineNumber);
10007
10008        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10009
10010        crashApplication(r, crashInfo);
10011    }
10012
10013    public void handleApplicationStrictModeViolation(
10014            IBinder app,
10015            int violationMask,
10016            StrictMode.ViolationInfo info) {
10017        ProcessRecord r = findAppProcess(app, "StrictMode");
10018        if (r == null) {
10019            return;
10020        }
10021
10022        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10023            Integer stackFingerprint = info.hashCode();
10024            boolean logIt = true;
10025            synchronized (mAlreadyLoggedViolatedStacks) {
10026                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10027                    logIt = false;
10028                    // TODO: sub-sample into EventLog for these, with
10029                    // the info.durationMillis?  Then we'd get
10030                    // the relative pain numbers, without logging all
10031                    // the stack traces repeatedly.  We'd want to do
10032                    // likewise in the client code, which also does
10033                    // dup suppression, before the Binder call.
10034                } else {
10035                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10036                        mAlreadyLoggedViolatedStacks.clear();
10037                    }
10038                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10039                }
10040            }
10041            if (logIt) {
10042                logStrictModeViolationToDropBox(r, info);
10043            }
10044        }
10045
10046        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10047            AppErrorResult result = new AppErrorResult();
10048            synchronized (this) {
10049                final long origId = Binder.clearCallingIdentity();
10050
10051                Message msg = Message.obtain();
10052                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10053                HashMap<String, Object> data = new HashMap<String, Object>();
10054                data.put("result", result);
10055                data.put("app", r);
10056                data.put("violationMask", violationMask);
10057                data.put("info", info);
10058                msg.obj = data;
10059                mHandler.sendMessage(msg);
10060
10061                Binder.restoreCallingIdentity(origId);
10062            }
10063            int res = result.get();
10064            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10065        }
10066    }
10067
10068    // Depending on the policy in effect, there could be a bunch of
10069    // these in quick succession so we try to batch these together to
10070    // minimize disk writes, number of dropbox entries, and maximize
10071    // compression, by having more fewer, larger records.
10072    private void logStrictModeViolationToDropBox(
10073            ProcessRecord process,
10074            StrictMode.ViolationInfo info) {
10075        if (info == null) {
10076            return;
10077        }
10078        final boolean isSystemApp = process == null ||
10079                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10080                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10081        final String processName = process == null ? "unknown" : process.processName;
10082        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10083        final DropBoxManager dbox = (DropBoxManager)
10084                mContext.getSystemService(Context.DROPBOX_SERVICE);
10085
10086        // Exit early if the dropbox isn't configured to accept this report type.
10087        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10088
10089        boolean bufferWasEmpty;
10090        boolean needsFlush;
10091        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10092        synchronized (sb) {
10093            bufferWasEmpty = sb.length() == 0;
10094            appendDropBoxProcessHeaders(process, processName, sb);
10095            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10096            sb.append("System-App: ").append(isSystemApp).append("\n");
10097            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10098            if (info.violationNumThisLoop != 0) {
10099                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10100            }
10101            if (info.numAnimationsRunning != 0) {
10102                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10103            }
10104            if (info.broadcastIntentAction != null) {
10105                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10106            }
10107            if (info.durationMillis != -1) {
10108                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10109            }
10110            if (info.numInstances != -1) {
10111                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10112            }
10113            if (info.tags != null) {
10114                for (String tag : info.tags) {
10115                    sb.append("Span-Tag: ").append(tag).append("\n");
10116                }
10117            }
10118            sb.append("\n");
10119            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10120                sb.append(info.crashInfo.stackTrace);
10121            }
10122            sb.append("\n");
10123
10124            // Only buffer up to ~64k.  Various logging bits truncate
10125            // things at 128k.
10126            needsFlush = (sb.length() > 64 * 1024);
10127        }
10128
10129        // Flush immediately if the buffer's grown too large, or this
10130        // is a non-system app.  Non-system apps are isolated with a
10131        // different tag & policy and not batched.
10132        //
10133        // Batching is useful during internal testing with
10134        // StrictMode settings turned up high.  Without batching,
10135        // thousands of separate files could be created on boot.
10136        if (!isSystemApp || needsFlush) {
10137            new Thread("Error dump: " + dropboxTag) {
10138                @Override
10139                public void run() {
10140                    String report;
10141                    synchronized (sb) {
10142                        report = sb.toString();
10143                        sb.delete(0, sb.length());
10144                        sb.trimToSize();
10145                    }
10146                    if (report.length() != 0) {
10147                        dbox.addText(dropboxTag, report);
10148                    }
10149                }
10150            }.start();
10151            return;
10152        }
10153
10154        // System app batching:
10155        if (!bufferWasEmpty) {
10156            // An existing dropbox-writing thread is outstanding, so
10157            // we don't need to start it up.  The existing thread will
10158            // catch the buffer appends we just did.
10159            return;
10160        }
10161
10162        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10163        // (After this point, we shouldn't access AMS internal data structures.)
10164        new Thread("Error dump: " + dropboxTag) {
10165            @Override
10166            public void run() {
10167                // 5 second sleep to let stacks arrive and be batched together
10168                try {
10169                    Thread.sleep(5000);  // 5 seconds
10170                } catch (InterruptedException e) {}
10171
10172                String errorReport;
10173                synchronized (mStrictModeBuffer) {
10174                    errorReport = mStrictModeBuffer.toString();
10175                    if (errorReport.length() == 0) {
10176                        return;
10177                    }
10178                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10179                    mStrictModeBuffer.trimToSize();
10180                }
10181                dbox.addText(dropboxTag, errorReport);
10182            }
10183        }.start();
10184    }
10185
10186    /**
10187     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10188     * @param app object of the crashing app, null for the system server
10189     * @param tag reported by the caller
10190     * @param crashInfo describing the context of the error
10191     * @return true if the process should exit immediately (WTF is fatal)
10192     */
10193    public boolean handleApplicationWtf(IBinder app, String tag,
10194            ApplicationErrorReport.CrashInfo crashInfo) {
10195        ProcessRecord r = findAppProcess(app, "WTF");
10196        final String processName = app == null ? "system_server"
10197                : (r == null ? "unknown" : r.processName);
10198
10199        EventLog.writeEvent(EventLogTags.AM_WTF,
10200                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10201                processName,
10202                r == null ? -1 : r.info.flags,
10203                tag, crashInfo.exceptionMessage);
10204
10205        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10206
10207        if (r != null && r.pid != Process.myPid() &&
10208                Settings.Global.getInt(mContext.getContentResolver(),
10209                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10210            crashApplication(r, crashInfo);
10211            return true;
10212        } else {
10213            return false;
10214        }
10215    }
10216
10217    /**
10218     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10219     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10220     */
10221    private ProcessRecord findAppProcess(IBinder app, String reason) {
10222        if (app == null) {
10223            return null;
10224        }
10225
10226        synchronized (this) {
10227            final int NP = mProcessNames.getMap().size();
10228            for (int ip=0; ip<NP; ip++) {
10229                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10230                final int NA = apps.size();
10231                for (int ia=0; ia<NA; ia++) {
10232                    ProcessRecord p = apps.valueAt(ia);
10233                    if (p.thread != null && p.thread.asBinder() == app) {
10234                        return p;
10235                    }
10236                }
10237            }
10238
10239            Slog.w(TAG, "Can't find mystery application for " + reason
10240                    + " from pid=" + Binder.getCallingPid()
10241                    + " uid=" + Binder.getCallingUid() + ": " + app);
10242            return null;
10243        }
10244    }
10245
10246    /**
10247     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10248     * to append various headers to the dropbox log text.
10249     */
10250    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10251            StringBuilder sb) {
10252        // Watchdog thread ends up invoking this function (with
10253        // a null ProcessRecord) to add the stack file to dropbox.
10254        // Do not acquire a lock on this (am) in such cases, as it
10255        // could cause a potential deadlock, if and when watchdog
10256        // is invoked due to unavailability of lock on am and it
10257        // would prevent watchdog from killing system_server.
10258        if (process == null) {
10259            sb.append("Process: ").append(processName).append("\n");
10260            return;
10261        }
10262        // Note: ProcessRecord 'process' is guarded by the service
10263        // instance.  (notably process.pkgList, which could otherwise change
10264        // concurrently during execution of this method)
10265        synchronized (this) {
10266            sb.append("Process: ").append(processName).append("\n");
10267            int flags = process.info.flags;
10268            IPackageManager pm = AppGlobals.getPackageManager();
10269            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10270            for (int ip=0; ip<process.pkgList.size(); ip++) {
10271                String pkg = process.pkgList.keyAt(ip);
10272                sb.append("Package: ").append(pkg);
10273                try {
10274                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10275                    if (pi != null) {
10276                        sb.append(" v").append(pi.versionCode);
10277                        if (pi.versionName != null) {
10278                            sb.append(" (").append(pi.versionName).append(")");
10279                        }
10280                    }
10281                } catch (RemoteException e) {
10282                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10283                }
10284                sb.append("\n");
10285            }
10286        }
10287    }
10288
10289    private static String processClass(ProcessRecord process) {
10290        if (process == null || process.pid == MY_PID) {
10291            return "system_server";
10292        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10293            return "system_app";
10294        } else {
10295            return "data_app";
10296        }
10297    }
10298
10299    /**
10300     * Write a description of an error (crash, WTF, ANR) to the drop box.
10301     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10302     * @param process which caused the error, null means the system server
10303     * @param activity which triggered the error, null if unknown
10304     * @param parent activity related to the error, null if unknown
10305     * @param subject line related to the error, null if absent
10306     * @param report in long form describing the error, null if absent
10307     * @param logFile to include in the report, null if none
10308     * @param crashInfo giving an application stack trace, null if absent
10309     */
10310    public void addErrorToDropBox(String eventType,
10311            ProcessRecord process, String processName, ActivityRecord activity,
10312            ActivityRecord parent, String subject,
10313            final String report, final File logFile,
10314            final ApplicationErrorReport.CrashInfo crashInfo) {
10315        // NOTE -- this must never acquire the ActivityManagerService lock,
10316        // otherwise the watchdog may be prevented from resetting the system.
10317
10318        final String dropboxTag = processClass(process) + "_" + eventType;
10319        final DropBoxManager dbox = (DropBoxManager)
10320                mContext.getSystemService(Context.DROPBOX_SERVICE);
10321
10322        // Exit early if the dropbox isn't configured to accept this report type.
10323        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10324
10325        final StringBuilder sb = new StringBuilder(1024);
10326        appendDropBoxProcessHeaders(process, processName, sb);
10327        if (activity != null) {
10328            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10329        }
10330        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10331            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10332        }
10333        if (parent != null && parent != activity) {
10334            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10335        }
10336        if (subject != null) {
10337            sb.append("Subject: ").append(subject).append("\n");
10338        }
10339        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10340        if (Debug.isDebuggerConnected()) {
10341            sb.append("Debugger: Connected\n");
10342        }
10343        sb.append("\n");
10344
10345        // Do the rest in a worker thread to avoid blocking the caller on I/O
10346        // (After this point, we shouldn't access AMS internal data structures.)
10347        Thread worker = new Thread("Error dump: " + dropboxTag) {
10348            @Override
10349            public void run() {
10350                if (report != null) {
10351                    sb.append(report);
10352                }
10353                if (logFile != null) {
10354                    try {
10355                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10356                                    "\n\n[[TRUNCATED]]"));
10357                    } catch (IOException e) {
10358                        Slog.e(TAG, "Error reading " + logFile, e);
10359                    }
10360                }
10361                if (crashInfo != null && crashInfo.stackTrace != null) {
10362                    sb.append(crashInfo.stackTrace);
10363                }
10364
10365                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10366                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10367                if (lines > 0) {
10368                    sb.append("\n");
10369
10370                    // Merge several logcat streams, and take the last N lines
10371                    InputStreamReader input = null;
10372                    try {
10373                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10374                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10375                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10376
10377                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10378                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10379                        input = new InputStreamReader(logcat.getInputStream());
10380
10381                        int num;
10382                        char[] buf = new char[8192];
10383                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10384                    } catch (IOException e) {
10385                        Slog.e(TAG, "Error running logcat", e);
10386                    } finally {
10387                        if (input != null) try { input.close(); } catch (IOException e) {}
10388                    }
10389                }
10390
10391                dbox.addText(dropboxTag, sb.toString());
10392            }
10393        };
10394
10395        if (process == null) {
10396            // If process is null, we are being called from some internal code
10397            // and may be about to die -- run this synchronously.
10398            worker.run();
10399        } else {
10400            worker.start();
10401        }
10402    }
10403
10404    /**
10405     * Bring up the "unexpected error" dialog box for a crashing app.
10406     * Deal with edge cases (intercepts from instrumented applications,
10407     * ActivityController, error intent receivers, that sort of thing).
10408     * @param r the application crashing
10409     * @param crashInfo describing the failure
10410     */
10411    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10412        long timeMillis = System.currentTimeMillis();
10413        String shortMsg = crashInfo.exceptionClassName;
10414        String longMsg = crashInfo.exceptionMessage;
10415        String stackTrace = crashInfo.stackTrace;
10416        if (shortMsg != null && longMsg != null) {
10417            longMsg = shortMsg + ": " + longMsg;
10418        } else if (shortMsg != null) {
10419            longMsg = shortMsg;
10420        }
10421
10422        AppErrorResult result = new AppErrorResult();
10423        synchronized (this) {
10424            if (mController != null) {
10425                try {
10426                    String name = r != null ? r.processName : null;
10427                    int pid = r != null ? r.pid : Binder.getCallingPid();
10428                    if (!mController.appCrashed(name, pid,
10429                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10430                        Slog.w(TAG, "Force-killing crashed app " + name
10431                                + " at watcher's request");
10432                        Process.killProcess(pid);
10433                        return;
10434                    }
10435                } catch (RemoteException e) {
10436                    mController = null;
10437                    Watchdog.getInstance().setActivityController(null);
10438                }
10439            }
10440
10441            final long origId = Binder.clearCallingIdentity();
10442
10443            // If this process is running instrumentation, finish it.
10444            if (r != null && r.instrumentationClass != null) {
10445                Slog.w(TAG, "Error in app " + r.processName
10446                      + " running instrumentation " + r.instrumentationClass + ":");
10447                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10448                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10449                Bundle info = new Bundle();
10450                info.putString("shortMsg", shortMsg);
10451                info.putString("longMsg", longMsg);
10452                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10453                Binder.restoreCallingIdentity(origId);
10454                return;
10455            }
10456
10457            // If we can't identify the process or it's already exceeded its crash quota,
10458            // quit right away without showing a crash dialog.
10459            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10460                Binder.restoreCallingIdentity(origId);
10461                return;
10462            }
10463
10464            Message msg = Message.obtain();
10465            msg.what = SHOW_ERROR_MSG;
10466            HashMap data = new HashMap();
10467            data.put("result", result);
10468            data.put("app", r);
10469            msg.obj = data;
10470            mHandler.sendMessage(msg);
10471
10472            Binder.restoreCallingIdentity(origId);
10473        }
10474
10475        int res = result.get();
10476
10477        Intent appErrorIntent = null;
10478        synchronized (this) {
10479            if (r != null && !r.isolated) {
10480                // XXX Can't keep track of crash time for isolated processes,
10481                // since they don't have a persistent identity.
10482                mProcessCrashTimes.put(r.info.processName, r.uid,
10483                        SystemClock.uptimeMillis());
10484            }
10485            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10486                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10487            }
10488        }
10489
10490        if (appErrorIntent != null) {
10491            try {
10492                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10493            } catch (ActivityNotFoundException e) {
10494                Slog.w(TAG, "bug report receiver dissappeared", e);
10495            }
10496        }
10497    }
10498
10499    Intent createAppErrorIntentLocked(ProcessRecord r,
10500            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10501        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10502        if (report == null) {
10503            return null;
10504        }
10505        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10506        result.setComponent(r.errorReportReceiver);
10507        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10508        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10509        return result;
10510    }
10511
10512    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10513            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10514        if (r.errorReportReceiver == null) {
10515            return null;
10516        }
10517
10518        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10519            return null;
10520        }
10521
10522        ApplicationErrorReport report = new ApplicationErrorReport();
10523        report.packageName = r.info.packageName;
10524        report.installerPackageName = r.errorReportReceiver.getPackageName();
10525        report.processName = r.processName;
10526        report.time = timeMillis;
10527        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10528
10529        if (r.crashing || r.forceCrashReport) {
10530            report.type = ApplicationErrorReport.TYPE_CRASH;
10531            report.crashInfo = crashInfo;
10532        } else if (r.notResponding) {
10533            report.type = ApplicationErrorReport.TYPE_ANR;
10534            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10535
10536            report.anrInfo.activity = r.notRespondingReport.tag;
10537            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10538            report.anrInfo.info = r.notRespondingReport.longMsg;
10539        }
10540
10541        return report;
10542    }
10543
10544    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10545        enforceNotIsolatedCaller("getProcessesInErrorState");
10546        // assume our apps are happy - lazy create the list
10547        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10548
10549        final boolean allUsers = ActivityManager.checkUidPermission(
10550                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10551                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10552        int userId = UserHandle.getUserId(Binder.getCallingUid());
10553
10554        synchronized (this) {
10555
10556            // iterate across all processes
10557            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10558                ProcessRecord app = mLruProcesses.get(i);
10559                if (!allUsers && app.userId != userId) {
10560                    continue;
10561                }
10562                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10563                    // This one's in trouble, so we'll generate a report for it
10564                    // crashes are higher priority (in case there's a crash *and* an anr)
10565                    ActivityManager.ProcessErrorStateInfo report = null;
10566                    if (app.crashing) {
10567                        report = app.crashingReport;
10568                    } else if (app.notResponding) {
10569                        report = app.notRespondingReport;
10570                    }
10571
10572                    if (report != null) {
10573                        if (errList == null) {
10574                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10575                        }
10576                        errList.add(report);
10577                    } else {
10578                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10579                                " crashing = " + app.crashing +
10580                                " notResponding = " + app.notResponding);
10581                    }
10582                }
10583            }
10584        }
10585
10586        return errList;
10587    }
10588
10589    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10590        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10591            if (currApp != null) {
10592                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10593            }
10594            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10595        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10596            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10597        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10598            if (currApp != null) {
10599                currApp.lru = 0;
10600            }
10601            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10602        } else if (adj >= ProcessList.SERVICE_ADJ) {
10603            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10604        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10605            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10606        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10607            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10608        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10609            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10610        } else {
10611            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10612        }
10613    }
10614
10615    private void fillInProcMemInfo(ProcessRecord app,
10616            ActivityManager.RunningAppProcessInfo outInfo) {
10617        outInfo.pid = app.pid;
10618        outInfo.uid = app.info.uid;
10619        if (mHeavyWeightProcess == app) {
10620            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10621        }
10622        if (app.persistent) {
10623            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10624        }
10625        if (app.activities.size() > 0) {
10626            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10627        }
10628        outInfo.lastTrimLevel = app.trimMemoryLevel;
10629        int adj = app.curAdj;
10630        outInfo.importance = oomAdjToImportance(adj, outInfo);
10631        outInfo.importanceReasonCode = app.adjTypeCode;
10632        outInfo.processState = app.curProcState;
10633    }
10634
10635    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10636        enforceNotIsolatedCaller("getRunningAppProcesses");
10637        // Lazy instantiation of list
10638        List<ActivityManager.RunningAppProcessInfo> runList = null;
10639        final boolean allUsers = ActivityManager.checkUidPermission(
10640                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10641                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10642        int userId = UserHandle.getUserId(Binder.getCallingUid());
10643        synchronized (this) {
10644            // Iterate across all processes
10645            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10646                ProcessRecord app = mLruProcesses.get(i);
10647                if (!allUsers && app.userId != userId) {
10648                    continue;
10649                }
10650                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10651                    // Generate process state info for running application
10652                    ActivityManager.RunningAppProcessInfo currApp =
10653                        new ActivityManager.RunningAppProcessInfo(app.processName,
10654                                app.pid, app.getPackageList());
10655                    fillInProcMemInfo(app, currApp);
10656                    if (app.adjSource instanceof ProcessRecord) {
10657                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10658                        currApp.importanceReasonImportance = oomAdjToImportance(
10659                                app.adjSourceOom, null);
10660                    } else if (app.adjSource instanceof ActivityRecord) {
10661                        ActivityRecord r = (ActivityRecord)app.adjSource;
10662                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10663                    }
10664                    if (app.adjTarget instanceof ComponentName) {
10665                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10666                    }
10667                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10668                    //        + " lru=" + currApp.lru);
10669                    if (runList == null) {
10670                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10671                    }
10672                    runList.add(currApp);
10673                }
10674            }
10675        }
10676        return runList;
10677    }
10678
10679    public List<ApplicationInfo> getRunningExternalApplications() {
10680        enforceNotIsolatedCaller("getRunningExternalApplications");
10681        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10682        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10683        if (runningApps != null && runningApps.size() > 0) {
10684            Set<String> extList = new HashSet<String>();
10685            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10686                if (app.pkgList != null) {
10687                    for (String pkg : app.pkgList) {
10688                        extList.add(pkg);
10689                    }
10690                }
10691            }
10692            IPackageManager pm = AppGlobals.getPackageManager();
10693            for (String pkg : extList) {
10694                try {
10695                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10696                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10697                        retList.add(info);
10698                    }
10699                } catch (RemoteException e) {
10700                }
10701            }
10702        }
10703        return retList;
10704    }
10705
10706    @Override
10707    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10708        enforceNotIsolatedCaller("getMyMemoryState");
10709        synchronized (this) {
10710            ProcessRecord proc;
10711            synchronized (mPidsSelfLocked) {
10712                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10713            }
10714            fillInProcMemInfo(proc, outInfo);
10715        }
10716    }
10717
10718    @Override
10719    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10720        if (checkCallingPermission(android.Manifest.permission.DUMP)
10721                != PackageManager.PERMISSION_GRANTED) {
10722            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10723                    + Binder.getCallingPid()
10724                    + ", uid=" + Binder.getCallingUid()
10725                    + " without permission "
10726                    + android.Manifest.permission.DUMP);
10727            return;
10728        }
10729
10730        boolean dumpAll = false;
10731        boolean dumpClient = false;
10732        String dumpPackage = null;
10733
10734        int opti = 0;
10735        while (opti < args.length) {
10736            String opt = args[opti];
10737            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10738                break;
10739            }
10740            opti++;
10741            if ("-a".equals(opt)) {
10742                dumpAll = true;
10743            } else if ("-c".equals(opt)) {
10744                dumpClient = true;
10745            } else if ("-h".equals(opt)) {
10746                pw.println("Activity manager dump options:");
10747                pw.println("  [-a] [-c] [-h] [cmd] ...");
10748                pw.println("  cmd may be one of:");
10749                pw.println("    a[ctivities]: activity stack state");
10750                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10751                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10752                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10753                pw.println("    o[om]: out of memory management");
10754                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10755                pw.println("    provider [COMP_SPEC]: provider client-side state");
10756                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10757                pw.println("    service [COMP_SPEC]: service client-side state");
10758                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10759                pw.println("    all: dump all activities");
10760                pw.println("    top: dump the top activity");
10761                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10762                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10763                pw.println("    a partial substring in a component name, a");
10764                pw.println("    hex object identifier.");
10765                pw.println("  -a: include all available server state.");
10766                pw.println("  -c: include client state.");
10767                return;
10768            } else {
10769                pw.println("Unknown argument: " + opt + "; use -h for help");
10770            }
10771        }
10772
10773        long origId = Binder.clearCallingIdentity();
10774        boolean more = false;
10775        // Is the caller requesting to dump a particular piece of data?
10776        if (opti < args.length) {
10777            String cmd = args[opti];
10778            opti++;
10779            if ("activities".equals(cmd) || "a".equals(cmd)) {
10780                synchronized (this) {
10781                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10782                }
10783            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10784                String[] newArgs;
10785                String name;
10786                if (opti >= args.length) {
10787                    name = null;
10788                    newArgs = EMPTY_STRING_ARRAY;
10789                } else {
10790                    name = args[opti];
10791                    opti++;
10792                    newArgs = new String[args.length - opti];
10793                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10794                            args.length - opti);
10795                }
10796                synchronized (this) {
10797                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10798                }
10799            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10800                String[] newArgs;
10801                String name;
10802                if (opti >= args.length) {
10803                    name = null;
10804                    newArgs = EMPTY_STRING_ARRAY;
10805                } else {
10806                    name = args[opti];
10807                    opti++;
10808                    newArgs = new String[args.length - opti];
10809                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10810                            args.length - opti);
10811                }
10812                synchronized (this) {
10813                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10814                }
10815            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10816                String[] newArgs;
10817                String name;
10818                if (opti >= args.length) {
10819                    name = null;
10820                    newArgs = EMPTY_STRING_ARRAY;
10821                } else {
10822                    name = args[opti];
10823                    opti++;
10824                    newArgs = new String[args.length - opti];
10825                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10826                            args.length - opti);
10827                }
10828                synchronized (this) {
10829                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10830                }
10831            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10832                synchronized (this) {
10833                    dumpOomLocked(fd, pw, args, opti, true);
10834                }
10835            } else if ("provider".equals(cmd)) {
10836                String[] newArgs;
10837                String name;
10838                if (opti >= args.length) {
10839                    name = null;
10840                    newArgs = EMPTY_STRING_ARRAY;
10841                } else {
10842                    name = args[opti];
10843                    opti++;
10844                    newArgs = new String[args.length - opti];
10845                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10846                }
10847                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10848                    pw.println("No providers match: " + name);
10849                    pw.println("Use -h for help.");
10850                }
10851            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10852                synchronized (this) {
10853                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10854                }
10855            } else if ("service".equals(cmd)) {
10856                String[] newArgs;
10857                String name;
10858                if (opti >= args.length) {
10859                    name = null;
10860                    newArgs = EMPTY_STRING_ARRAY;
10861                } else {
10862                    name = args[opti];
10863                    opti++;
10864                    newArgs = new String[args.length - opti];
10865                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10866                            args.length - opti);
10867                }
10868                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10869                    pw.println("No services match: " + name);
10870                    pw.println("Use -h for help.");
10871                }
10872            } else if ("package".equals(cmd)) {
10873                String[] newArgs;
10874                if (opti >= args.length) {
10875                    pw.println("package: no package name specified");
10876                    pw.println("Use -h for help.");
10877                } else {
10878                    dumpPackage = args[opti];
10879                    opti++;
10880                    newArgs = new String[args.length - opti];
10881                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10882                            args.length - opti);
10883                    args = newArgs;
10884                    opti = 0;
10885                    more = true;
10886                }
10887            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10888                synchronized (this) {
10889                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10890                }
10891            } else {
10892                // Dumping a single activity?
10893                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10894                    pw.println("Bad activity command, or no activities match: " + cmd);
10895                    pw.println("Use -h for help.");
10896                }
10897            }
10898            if (!more) {
10899                Binder.restoreCallingIdentity(origId);
10900                return;
10901            }
10902        }
10903
10904        // No piece of data specified, dump everything.
10905        synchronized (this) {
10906            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10907            pw.println();
10908            if (dumpAll) {
10909                pw.println("-------------------------------------------------------------------------------");
10910            }
10911            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10912            pw.println();
10913            if (dumpAll) {
10914                pw.println("-------------------------------------------------------------------------------");
10915            }
10916            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10917            pw.println();
10918            if (dumpAll) {
10919                pw.println("-------------------------------------------------------------------------------");
10920            }
10921            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10922            pw.println();
10923            if (dumpAll) {
10924                pw.println("-------------------------------------------------------------------------------");
10925            }
10926            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10927            pw.println();
10928            if (dumpAll) {
10929                pw.println("-------------------------------------------------------------------------------");
10930            }
10931            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10932        }
10933        Binder.restoreCallingIdentity(origId);
10934    }
10935
10936    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10937            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10938        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10939
10940        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10941                dumpPackage);
10942        boolean needSep = printedAnything;
10943
10944        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10945                dumpPackage, needSep, "  mFocusedActivity: ");
10946        if (printed) {
10947            printedAnything = true;
10948            needSep = false;
10949        }
10950
10951        if (dumpPackage == null) {
10952            if (needSep) {
10953                pw.println();
10954            }
10955            needSep = true;
10956            printedAnything = true;
10957            mStackSupervisor.dump(pw, "  ");
10958        }
10959
10960        if (mRecentTasks.size() > 0) {
10961            boolean printedHeader = false;
10962
10963            final int N = mRecentTasks.size();
10964            for (int i=0; i<N; i++) {
10965                TaskRecord tr = mRecentTasks.get(i);
10966                if (dumpPackage != null) {
10967                    if (tr.realActivity == null ||
10968                            !dumpPackage.equals(tr.realActivity)) {
10969                        continue;
10970                    }
10971                }
10972                if (!printedHeader) {
10973                    if (needSep) {
10974                        pw.println();
10975                    }
10976                    pw.println("  Recent tasks:");
10977                    printedHeader = true;
10978                    printedAnything = true;
10979                }
10980                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10981                        pw.println(tr);
10982                if (dumpAll) {
10983                    mRecentTasks.get(i).dump(pw, "    ");
10984                }
10985            }
10986        }
10987
10988        if (!printedAnything) {
10989            pw.println("  (nothing)");
10990        }
10991    }
10992
10993    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10994            int opti, boolean dumpAll, String dumpPackage) {
10995        boolean needSep = false;
10996        boolean printedAnything = false;
10997        int numPers = 0;
10998
10999        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11000
11001        if (dumpAll) {
11002            final int NP = mProcessNames.getMap().size();
11003            for (int ip=0; ip<NP; ip++) {
11004                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11005                final int NA = procs.size();
11006                for (int ia=0; ia<NA; ia++) {
11007                    ProcessRecord r = procs.valueAt(ia);
11008                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11009                        continue;
11010                    }
11011                    if (!needSep) {
11012                        pw.println("  All known processes:");
11013                        needSep = true;
11014                        printedAnything = true;
11015                    }
11016                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11017                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11018                        pw.print(" "); pw.println(r);
11019                    r.dump(pw, "    ");
11020                    if (r.persistent) {
11021                        numPers++;
11022                    }
11023                }
11024            }
11025        }
11026
11027        if (mIsolatedProcesses.size() > 0) {
11028            boolean printed = false;
11029            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11030                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11031                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11032                    continue;
11033                }
11034                if (!printed) {
11035                    if (needSep) {
11036                        pw.println();
11037                    }
11038                    pw.println("  Isolated process list (sorted by uid):");
11039                    printedAnything = true;
11040                    printed = true;
11041                    needSep = true;
11042                }
11043                pw.println(String.format("%sIsolated #%2d: %s",
11044                        "    ", i, r.toString()));
11045            }
11046        }
11047
11048        if (mLruProcesses.size() > 0) {
11049            if (needSep) {
11050                pw.println();
11051            }
11052            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11053                    pw.print(" total, non-act at ");
11054                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11055                    pw.print(", non-svc at ");
11056                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11057                    pw.println("):");
11058            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11059            needSep = true;
11060            printedAnything = true;
11061        }
11062
11063        if (dumpAll || dumpPackage != null) {
11064            synchronized (mPidsSelfLocked) {
11065                boolean printed = false;
11066                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11067                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11068                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11069                        continue;
11070                    }
11071                    if (!printed) {
11072                        if (needSep) pw.println();
11073                        needSep = true;
11074                        pw.println("  PID mappings:");
11075                        printed = true;
11076                        printedAnything = true;
11077                    }
11078                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11079                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11080                }
11081            }
11082        }
11083
11084        if (mForegroundProcesses.size() > 0) {
11085            synchronized (mPidsSelfLocked) {
11086                boolean printed = false;
11087                for (int i=0; i<mForegroundProcesses.size(); i++) {
11088                    ProcessRecord r = mPidsSelfLocked.get(
11089                            mForegroundProcesses.valueAt(i).pid);
11090                    if (dumpPackage != null && (r == null
11091                            || !r.pkgList.containsKey(dumpPackage))) {
11092                        continue;
11093                    }
11094                    if (!printed) {
11095                        if (needSep) pw.println();
11096                        needSep = true;
11097                        pw.println("  Foreground Processes:");
11098                        printed = true;
11099                        printedAnything = true;
11100                    }
11101                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11102                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11103                }
11104            }
11105        }
11106
11107        if (mPersistentStartingProcesses.size() > 0) {
11108            if (needSep) pw.println();
11109            needSep = true;
11110            printedAnything = true;
11111            pw.println("  Persisent processes that are starting:");
11112            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11113                    "Starting Norm", "Restarting PERS", dumpPackage);
11114        }
11115
11116        if (mRemovedProcesses.size() > 0) {
11117            if (needSep) pw.println();
11118            needSep = true;
11119            printedAnything = true;
11120            pw.println("  Processes that are being removed:");
11121            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11122                    "Removed Norm", "Removed PERS", dumpPackage);
11123        }
11124
11125        if (mProcessesOnHold.size() > 0) {
11126            if (needSep) pw.println();
11127            needSep = true;
11128            printedAnything = true;
11129            pw.println("  Processes that are on old until the system is ready:");
11130            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11131                    "OnHold Norm", "OnHold PERS", dumpPackage);
11132        }
11133
11134        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11135
11136        if (mProcessCrashTimes.getMap().size() > 0) {
11137            boolean printed = false;
11138            long now = SystemClock.uptimeMillis();
11139            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11140            final int NP = pmap.size();
11141            for (int ip=0; ip<NP; ip++) {
11142                String pname = pmap.keyAt(ip);
11143                SparseArray<Long> uids = pmap.valueAt(ip);
11144                final int N = uids.size();
11145                for (int i=0; i<N; i++) {
11146                    int puid = uids.keyAt(i);
11147                    ProcessRecord r = mProcessNames.get(pname, puid);
11148                    if (dumpPackage != null && (r == null
11149                            || !r.pkgList.containsKey(dumpPackage))) {
11150                        continue;
11151                    }
11152                    if (!printed) {
11153                        if (needSep) pw.println();
11154                        needSep = true;
11155                        pw.println("  Time since processes crashed:");
11156                        printed = true;
11157                        printedAnything = true;
11158                    }
11159                    pw.print("    Process "); pw.print(pname);
11160                            pw.print(" uid "); pw.print(puid);
11161                            pw.print(": last crashed ");
11162                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11163                            pw.println(" ago");
11164                }
11165            }
11166        }
11167
11168        if (mBadProcesses.getMap().size() > 0) {
11169            boolean printed = false;
11170            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11171            final int NP = pmap.size();
11172            for (int ip=0; ip<NP; ip++) {
11173                String pname = pmap.keyAt(ip);
11174                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11175                final int N = uids.size();
11176                for (int i=0; i<N; i++) {
11177                    int puid = uids.keyAt(i);
11178                    ProcessRecord r = mProcessNames.get(pname, puid);
11179                    if (dumpPackage != null && (r == null
11180                            || !r.pkgList.containsKey(dumpPackage))) {
11181                        continue;
11182                    }
11183                    if (!printed) {
11184                        if (needSep) pw.println();
11185                        needSep = true;
11186                        pw.println("  Bad processes:");
11187                        printedAnything = true;
11188                    }
11189                    BadProcessInfo info = uids.valueAt(i);
11190                    pw.print("    Bad process "); pw.print(pname);
11191                            pw.print(" uid "); pw.print(puid);
11192                            pw.print(": crashed at time "); pw.println(info.time);
11193                    if (info.shortMsg != null) {
11194                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11195                    }
11196                    if (info.longMsg != null) {
11197                        pw.print("      Long msg: "); pw.println(info.longMsg);
11198                    }
11199                    if (info.stack != null) {
11200                        pw.println("      Stack:");
11201                        int lastPos = 0;
11202                        for (int pos=0; pos<info.stack.length(); pos++) {
11203                            if (info.stack.charAt(pos) == '\n') {
11204                                pw.print("        ");
11205                                pw.write(info.stack, lastPos, pos-lastPos);
11206                                pw.println();
11207                                lastPos = pos+1;
11208                            }
11209                        }
11210                        if (lastPos < info.stack.length()) {
11211                            pw.print("        ");
11212                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11213                            pw.println();
11214                        }
11215                    }
11216                }
11217            }
11218        }
11219
11220        if (dumpPackage == null) {
11221            pw.println();
11222            needSep = false;
11223            pw.println("  mStartedUsers:");
11224            for (int i=0; i<mStartedUsers.size(); i++) {
11225                UserStartedState uss = mStartedUsers.valueAt(i);
11226                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11227                        pw.print(": "); uss.dump("", pw);
11228            }
11229            pw.print("  mStartedUserArray: [");
11230            for (int i=0; i<mStartedUserArray.length; i++) {
11231                if (i > 0) pw.print(", ");
11232                pw.print(mStartedUserArray[i]);
11233            }
11234            pw.println("]");
11235            pw.print("  mUserLru: [");
11236            for (int i=0; i<mUserLru.size(); i++) {
11237                if (i > 0) pw.print(", ");
11238                pw.print(mUserLru.get(i));
11239            }
11240            pw.println("]");
11241            if (dumpAll) {
11242                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11243            }
11244        }
11245        if (mHomeProcess != null && (dumpPackage == null
11246                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11247            if (needSep) {
11248                pw.println();
11249                needSep = false;
11250            }
11251            pw.println("  mHomeProcess: " + mHomeProcess);
11252        }
11253        if (mPreviousProcess != null && (dumpPackage == null
11254                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11255            if (needSep) {
11256                pw.println();
11257                needSep = false;
11258            }
11259            pw.println("  mPreviousProcess: " + mPreviousProcess);
11260        }
11261        if (dumpAll) {
11262            StringBuilder sb = new StringBuilder(128);
11263            sb.append("  mPreviousProcessVisibleTime: ");
11264            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11265            pw.println(sb);
11266        }
11267        if (mHeavyWeightProcess != null && (dumpPackage == null
11268                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11269            if (needSep) {
11270                pw.println();
11271                needSep = false;
11272            }
11273            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11274        }
11275        if (dumpPackage == null) {
11276            pw.println("  mConfiguration: " + mConfiguration);
11277        }
11278        if (dumpAll) {
11279            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11280            if (mCompatModePackages.getPackages().size() > 0) {
11281                boolean printed = false;
11282                for (Map.Entry<String, Integer> entry
11283                        : mCompatModePackages.getPackages().entrySet()) {
11284                    String pkg = entry.getKey();
11285                    int mode = entry.getValue();
11286                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11287                        continue;
11288                    }
11289                    if (!printed) {
11290                        pw.println("  mScreenCompatPackages:");
11291                        printed = true;
11292                    }
11293                    pw.print("    "); pw.print(pkg); pw.print(": ");
11294                            pw.print(mode); pw.println();
11295                }
11296            }
11297        }
11298        if (dumpPackage == null) {
11299            if (mSleeping || mWentToSleep || mLockScreenShown) {
11300                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11301                        + " mLockScreenShown " + mLockScreenShown);
11302            }
11303            if (mShuttingDown || mRunningVoice) {
11304                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11305            }
11306        }
11307        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11308                || mOrigWaitForDebugger) {
11309            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11310                    || dumpPackage.equals(mOrigDebugApp)) {
11311                if (needSep) {
11312                    pw.println();
11313                    needSep = false;
11314                }
11315                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11316                        + " mDebugTransient=" + mDebugTransient
11317                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11318            }
11319        }
11320        if (mOpenGlTraceApp != null) {
11321            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11322                if (needSep) {
11323                    pw.println();
11324                    needSep = false;
11325                }
11326                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11327            }
11328        }
11329        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11330                || mProfileFd != null) {
11331            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11332                if (needSep) {
11333                    pw.println();
11334                    needSep = false;
11335                }
11336                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11337                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11338                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11339                        + mAutoStopProfiler);
11340            }
11341        }
11342        if (dumpPackage == null) {
11343            if (mAlwaysFinishActivities || mController != null) {
11344                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11345                        + " mController=" + mController);
11346            }
11347            if (dumpAll) {
11348                pw.println("  Total persistent processes: " + numPers);
11349                pw.println("  mProcessesReady=" + mProcessesReady
11350                        + " mSystemReady=" + mSystemReady);
11351                pw.println("  mBooting=" + mBooting
11352                        + " mBooted=" + mBooted
11353                        + " mFactoryTest=" + mFactoryTest);
11354                pw.print("  mLastPowerCheckRealtime=");
11355                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11356                        pw.println("");
11357                pw.print("  mLastPowerCheckUptime=");
11358                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11359                        pw.println("");
11360                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11361                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11362                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11363                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11364                        + " (" + mLruProcesses.size() + " total)"
11365                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11366                        + " mNumServiceProcs=" + mNumServiceProcs
11367                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11368                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11369                        + " mLastMemoryLevel" + mLastMemoryLevel
11370                        + " mLastNumProcesses" + mLastNumProcesses);
11371                long now = SystemClock.uptimeMillis();
11372                pw.print("  mLastIdleTime=");
11373                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11374                        pw.print(" mLowRamSinceLastIdle=");
11375                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11376                        pw.println();
11377            }
11378        }
11379
11380        if (!printedAnything) {
11381            pw.println("  (nothing)");
11382        }
11383    }
11384
11385    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11386            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11387        if (mProcessesToGc.size() > 0) {
11388            boolean printed = false;
11389            long now = SystemClock.uptimeMillis();
11390            for (int i=0; i<mProcessesToGc.size(); i++) {
11391                ProcessRecord proc = mProcessesToGc.get(i);
11392                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11393                    continue;
11394                }
11395                if (!printed) {
11396                    if (needSep) pw.println();
11397                    needSep = true;
11398                    pw.println("  Processes that are waiting to GC:");
11399                    printed = true;
11400                }
11401                pw.print("    Process "); pw.println(proc);
11402                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11403                        pw.print(", last gced=");
11404                        pw.print(now-proc.lastRequestedGc);
11405                        pw.print(" ms ago, last lowMem=");
11406                        pw.print(now-proc.lastLowMemory);
11407                        pw.println(" ms ago");
11408
11409            }
11410        }
11411        return needSep;
11412    }
11413
11414    void printOomLevel(PrintWriter pw, String name, int adj) {
11415        pw.print("    ");
11416        if (adj >= 0) {
11417            pw.print(' ');
11418            if (adj < 10) pw.print(' ');
11419        } else {
11420            if (adj > -10) pw.print(' ');
11421        }
11422        pw.print(adj);
11423        pw.print(": ");
11424        pw.print(name);
11425        pw.print(" (");
11426        pw.print(mProcessList.getMemLevel(adj)/1024);
11427        pw.println(" kB)");
11428    }
11429
11430    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11431            int opti, boolean dumpAll) {
11432        boolean needSep = false;
11433
11434        if (mLruProcesses.size() > 0) {
11435            if (needSep) pw.println();
11436            needSep = true;
11437            pw.println("  OOM levels:");
11438            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11439            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11440            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11441            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11442            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11443            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11444            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11445            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11446            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11447            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11448            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11449            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11450            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11451
11452            if (needSep) pw.println();
11453            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11454                    pw.print(" total, non-act at ");
11455                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11456                    pw.print(", non-svc at ");
11457                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11458                    pw.println("):");
11459            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11460            needSep = true;
11461        }
11462
11463        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11464
11465        pw.println();
11466        pw.println("  mHomeProcess: " + mHomeProcess);
11467        pw.println("  mPreviousProcess: " + mPreviousProcess);
11468        if (mHeavyWeightProcess != null) {
11469            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11470        }
11471
11472        return true;
11473    }
11474
11475    /**
11476     * There are three ways to call this:
11477     *  - no provider specified: dump all the providers
11478     *  - a flattened component name that matched an existing provider was specified as the
11479     *    first arg: dump that one provider
11480     *  - the first arg isn't the flattened component name of an existing provider:
11481     *    dump all providers whose component contains the first arg as a substring
11482     */
11483    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11484            int opti, boolean dumpAll) {
11485        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11486    }
11487
11488    static class ItemMatcher {
11489        ArrayList<ComponentName> components;
11490        ArrayList<String> strings;
11491        ArrayList<Integer> objects;
11492        boolean all;
11493
11494        ItemMatcher() {
11495            all = true;
11496        }
11497
11498        void build(String name) {
11499            ComponentName componentName = ComponentName.unflattenFromString(name);
11500            if (componentName != null) {
11501                if (components == null) {
11502                    components = new ArrayList<ComponentName>();
11503                }
11504                components.add(componentName);
11505                all = false;
11506            } else {
11507                int objectId = 0;
11508                // Not a '/' separated full component name; maybe an object ID?
11509                try {
11510                    objectId = Integer.parseInt(name, 16);
11511                    if (objects == null) {
11512                        objects = new ArrayList<Integer>();
11513                    }
11514                    objects.add(objectId);
11515                    all = false;
11516                } catch (RuntimeException e) {
11517                    // Not an integer; just do string match.
11518                    if (strings == null) {
11519                        strings = new ArrayList<String>();
11520                    }
11521                    strings.add(name);
11522                    all = false;
11523                }
11524            }
11525        }
11526
11527        int build(String[] args, int opti) {
11528            for (; opti<args.length; opti++) {
11529                String name = args[opti];
11530                if ("--".equals(name)) {
11531                    return opti+1;
11532                }
11533                build(name);
11534            }
11535            return opti;
11536        }
11537
11538        boolean match(Object object, ComponentName comp) {
11539            if (all) {
11540                return true;
11541            }
11542            if (components != null) {
11543                for (int i=0; i<components.size(); i++) {
11544                    if (components.get(i).equals(comp)) {
11545                        return true;
11546                    }
11547                }
11548            }
11549            if (objects != null) {
11550                for (int i=0; i<objects.size(); i++) {
11551                    if (System.identityHashCode(object) == objects.get(i)) {
11552                        return true;
11553                    }
11554                }
11555            }
11556            if (strings != null) {
11557                String flat = comp.flattenToString();
11558                for (int i=0; i<strings.size(); i++) {
11559                    if (flat.contains(strings.get(i))) {
11560                        return true;
11561                    }
11562                }
11563            }
11564            return false;
11565        }
11566    }
11567
11568    /**
11569     * There are three things that cmd can be:
11570     *  - a flattened component name that matches an existing activity
11571     *  - the cmd arg isn't the flattened component name of an existing activity:
11572     *    dump all activity whose component contains the cmd as a substring
11573     *  - A hex number of the ActivityRecord object instance.
11574     */
11575    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11576            int opti, boolean dumpAll) {
11577        ArrayList<ActivityRecord> activities;
11578
11579        synchronized (this) {
11580            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11581        }
11582
11583        if (activities.size() <= 0) {
11584            return false;
11585        }
11586
11587        String[] newArgs = new String[args.length - opti];
11588        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11589
11590        TaskRecord lastTask = null;
11591        boolean needSep = false;
11592        for (int i=activities.size()-1; i>=0; i--) {
11593            ActivityRecord r = activities.get(i);
11594            if (needSep) {
11595                pw.println();
11596            }
11597            needSep = true;
11598            synchronized (this) {
11599                if (lastTask != r.task) {
11600                    lastTask = r.task;
11601                    pw.print("TASK "); pw.print(lastTask.affinity);
11602                            pw.print(" id="); pw.println(lastTask.taskId);
11603                    if (dumpAll) {
11604                        lastTask.dump(pw, "  ");
11605                    }
11606                }
11607            }
11608            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11609        }
11610        return true;
11611    }
11612
11613    /**
11614     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11615     * there is a thread associated with the activity.
11616     */
11617    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11618            final ActivityRecord r, String[] args, boolean dumpAll) {
11619        String innerPrefix = prefix + "  ";
11620        synchronized (this) {
11621            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11622                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11623                    pw.print(" pid=");
11624                    if (r.app != null) pw.println(r.app.pid);
11625                    else pw.println("(not running)");
11626            if (dumpAll) {
11627                r.dump(pw, innerPrefix);
11628            }
11629        }
11630        if (r.app != null && r.app.thread != null) {
11631            // flush anything that is already in the PrintWriter since the thread is going
11632            // to write to the file descriptor directly
11633            pw.flush();
11634            try {
11635                TransferPipe tp = new TransferPipe();
11636                try {
11637                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11638                            r.appToken, innerPrefix, args);
11639                    tp.go(fd);
11640                } finally {
11641                    tp.kill();
11642                }
11643            } catch (IOException e) {
11644                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11645            } catch (RemoteException e) {
11646                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11647            }
11648        }
11649    }
11650
11651    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11652            int opti, boolean dumpAll, String dumpPackage) {
11653        boolean needSep = false;
11654        boolean onlyHistory = false;
11655        boolean printedAnything = false;
11656
11657        if ("history".equals(dumpPackage)) {
11658            if (opti < args.length && "-s".equals(args[opti])) {
11659                dumpAll = false;
11660            }
11661            onlyHistory = true;
11662            dumpPackage = null;
11663        }
11664
11665        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11666        if (!onlyHistory && dumpAll) {
11667            if (mRegisteredReceivers.size() > 0) {
11668                boolean printed = false;
11669                Iterator it = mRegisteredReceivers.values().iterator();
11670                while (it.hasNext()) {
11671                    ReceiverList r = (ReceiverList)it.next();
11672                    if (dumpPackage != null && (r.app == null ||
11673                            !dumpPackage.equals(r.app.info.packageName))) {
11674                        continue;
11675                    }
11676                    if (!printed) {
11677                        pw.println("  Registered Receivers:");
11678                        needSep = true;
11679                        printed = true;
11680                        printedAnything = true;
11681                    }
11682                    pw.print("  * "); pw.println(r);
11683                    r.dump(pw, "    ");
11684                }
11685            }
11686
11687            if (mReceiverResolver.dump(pw, needSep ?
11688                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11689                    "    ", dumpPackage, false)) {
11690                needSep = true;
11691                printedAnything = true;
11692            }
11693        }
11694
11695        for (BroadcastQueue q : mBroadcastQueues) {
11696            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11697            printedAnything |= needSep;
11698        }
11699
11700        needSep = true;
11701
11702        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11703            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11704                if (needSep) {
11705                    pw.println();
11706                }
11707                needSep = true;
11708                printedAnything = true;
11709                pw.print("  Sticky broadcasts for user ");
11710                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11711                StringBuilder sb = new StringBuilder(128);
11712                for (Map.Entry<String, ArrayList<Intent>> ent
11713                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11714                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11715                    if (dumpAll) {
11716                        pw.println(":");
11717                        ArrayList<Intent> intents = ent.getValue();
11718                        final int N = intents.size();
11719                        for (int i=0; i<N; i++) {
11720                            sb.setLength(0);
11721                            sb.append("    Intent: ");
11722                            intents.get(i).toShortString(sb, false, true, false, false);
11723                            pw.println(sb.toString());
11724                            Bundle bundle = intents.get(i).getExtras();
11725                            if (bundle != null) {
11726                                pw.print("      ");
11727                                pw.println(bundle.toString());
11728                            }
11729                        }
11730                    } else {
11731                        pw.println("");
11732                    }
11733                }
11734            }
11735        }
11736
11737        if (!onlyHistory && dumpAll) {
11738            pw.println();
11739            for (BroadcastQueue queue : mBroadcastQueues) {
11740                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11741                        + queue.mBroadcastsScheduled);
11742            }
11743            pw.println("  mHandler:");
11744            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11745            needSep = true;
11746            printedAnything = true;
11747        }
11748
11749        if (!printedAnything) {
11750            pw.println("  (nothing)");
11751        }
11752    }
11753
11754    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11755            int opti, boolean dumpAll, String dumpPackage) {
11756        boolean needSep;
11757        boolean printedAnything = false;
11758
11759        ItemMatcher matcher = new ItemMatcher();
11760        matcher.build(args, opti);
11761
11762        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11763
11764        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11765        printedAnything |= needSep;
11766
11767        if (mLaunchingProviders.size() > 0) {
11768            boolean printed = false;
11769            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11770                ContentProviderRecord r = mLaunchingProviders.get(i);
11771                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11772                    continue;
11773                }
11774                if (!printed) {
11775                    if (needSep) pw.println();
11776                    needSep = true;
11777                    pw.println("  Launching content providers:");
11778                    printed = true;
11779                    printedAnything = true;
11780                }
11781                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11782                        pw.println(r);
11783            }
11784        }
11785
11786        if (mGrantedUriPermissions.size() > 0) {
11787            boolean printed = false;
11788            int dumpUid = -2;
11789            if (dumpPackage != null) {
11790                try {
11791                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11792                } catch (NameNotFoundException e) {
11793                    dumpUid = -1;
11794                }
11795            }
11796            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11797                int uid = mGrantedUriPermissions.keyAt(i);
11798                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11799                    continue;
11800                }
11801                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
11802                if (!printed) {
11803                    if (needSep) pw.println();
11804                    needSep = true;
11805                    pw.println("  Granted Uri Permissions:");
11806                    printed = true;
11807                    printedAnything = true;
11808                }
11809                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
11810                for (UriPermission perm : perms.values()) {
11811                    pw.print("    "); pw.println(perm);
11812                    if (dumpAll) {
11813                        perm.dump(pw, "      ");
11814                    }
11815                }
11816            }
11817        }
11818
11819        if (!printedAnything) {
11820            pw.println("  (nothing)");
11821        }
11822    }
11823
11824    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11825            int opti, boolean dumpAll, String dumpPackage) {
11826        boolean printed = false;
11827
11828        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11829
11830        if (mIntentSenderRecords.size() > 0) {
11831            Iterator<WeakReference<PendingIntentRecord>> it
11832                    = mIntentSenderRecords.values().iterator();
11833            while (it.hasNext()) {
11834                WeakReference<PendingIntentRecord> ref = it.next();
11835                PendingIntentRecord rec = ref != null ? ref.get(): null;
11836                if (dumpPackage != null && (rec == null
11837                        || !dumpPackage.equals(rec.key.packageName))) {
11838                    continue;
11839                }
11840                printed = true;
11841                if (rec != null) {
11842                    pw.print("  * "); pw.println(rec);
11843                    if (dumpAll) {
11844                        rec.dump(pw, "    ");
11845                    }
11846                } else {
11847                    pw.print("  * "); pw.println(ref);
11848                }
11849            }
11850        }
11851
11852        if (!printed) {
11853            pw.println("  (nothing)");
11854        }
11855    }
11856
11857    private static final int dumpProcessList(PrintWriter pw,
11858            ActivityManagerService service, List list,
11859            String prefix, String normalLabel, String persistentLabel,
11860            String dumpPackage) {
11861        int numPers = 0;
11862        final int N = list.size()-1;
11863        for (int i=N; i>=0; i--) {
11864            ProcessRecord r = (ProcessRecord)list.get(i);
11865            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11866                continue;
11867            }
11868            pw.println(String.format("%s%s #%2d: %s",
11869                    prefix, (r.persistent ? persistentLabel : normalLabel),
11870                    i, r.toString()));
11871            if (r.persistent) {
11872                numPers++;
11873            }
11874        }
11875        return numPers;
11876    }
11877
11878    private static final boolean dumpProcessOomList(PrintWriter pw,
11879            ActivityManagerService service, List<ProcessRecord> origList,
11880            String prefix, String normalLabel, String persistentLabel,
11881            boolean inclDetails, String dumpPackage) {
11882
11883        ArrayList<Pair<ProcessRecord, Integer>> list
11884                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11885        for (int i=0; i<origList.size(); i++) {
11886            ProcessRecord r = origList.get(i);
11887            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11888                continue;
11889            }
11890            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11891        }
11892
11893        if (list.size() <= 0) {
11894            return false;
11895        }
11896
11897        Comparator<Pair<ProcessRecord, Integer>> comparator
11898                = new Comparator<Pair<ProcessRecord, Integer>>() {
11899            @Override
11900            public int compare(Pair<ProcessRecord, Integer> object1,
11901                    Pair<ProcessRecord, Integer> object2) {
11902                if (object1.first.setAdj != object2.first.setAdj) {
11903                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11904                }
11905                if (object1.second.intValue() != object2.second.intValue()) {
11906                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11907                }
11908                return 0;
11909            }
11910        };
11911
11912        Collections.sort(list, comparator);
11913
11914        final long curRealtime = SystemClock.elapsedRealtime();
11915        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11916        final long curUptime = SystemClock.uptimeMillis();
11917        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11918
11919        for (int i=list.size()-1; i>=0; i--) {
11920            ProcessRecord r = list.get(i).first;
11921            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11922            char schedGroup;
11923            switch (r.setSchedGroup) {
11924                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11925                    schedGroup = 'B';
11926                    break;
11927                case Process.THREAD_GROUP_DEFAULT:
11928                    schedGroup = 'F';
11929                    break;
11930                default:
11931                    schedGroup = '?';
11932                    break;
11933            }
11934            char foreground;
11935            if (r.foregroundActivities) {
11936                foreground = 'A';
11937            } else if (r.foregroundServices) {
11938                foreground = 'S';
11939            } else {
11940                foreground = ' ';
11941            }
11942            String procState = ProcessList.makeProcStateString(r.curProcState);
11943            pw.print(prefix);
11944            pw.print(r.persistent ? persistentLabel : normalLabel);
11945            pw.print(" #");
11946            int num = (origList.size()-1)-list.get(i).second;
11947            if (num < 10) pw.print(' ');
11948            pw.print(num);
11949            pw.print(": ");
11950            pw.print(oomAdj);
11951            pw.print(' ');
11952            pw.print(schedGroup);
11953            pw.print('/');
11954            pw.print(foreground);
11955            pw.print('/');
11956            pw.print(procState);
11957            pw.print(" trm:");
11958            if (r.trimMemoryLevel < 10) pw.print(' ');
11959            pw.print(r.trimMemoryLevel);
11960            pw.print(' ');
11961            pw.print(r.toShortString());
11962            pw.print(" (");
11963            pw.print(r.adjType);
11964            pw.println(')');
11965            if (r.adjSource != null || r.adjTarget != null) {
11966                pw.print(prefix);
11967                pw.print("    ");
11968                if (r.adjTarget instanceof ComponentName) {
11969                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11970                } else if (r.adjTarget != null) {
11971                    pw.print(r.adjTarget.toString());
11972                } else {
11973                    pw.print("{null}");
11974                }
11975                pw.print("<=");
11976                if (r.adjSource instanceof ProcessRecord) {
11977                    pw.print("Proc{");
11978                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11979                    pw.println("}");
11980                } else if (r.adjSource != null) {
11981                    pw.println(r.adjSource.toString());
11982                } else {
11983                    pw.println("{null}");
11984                }
11985            }
11986            if (inclDetails) {
11987                pw.print(prefix);
11988                pw.print("    ");
11989                pw.print("oom: max="); pw.print(r.maxAdj);
11990                pw.print(" curRaw="); pw.print(r.curRawAdj);
11991                pw.print(" setRaw="); pw.print(r.setRawAdj);
11992                pw.print(" cur="); pw.print(r.curAdj);
11993                pw.print(" set="); pw.println(r.setAdj);
11994                pw.print(prefix);
11995                pw.print("    ");
11996                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
11997                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
11998                pw.print(" lastPss="); pw.print(r.lastPss);
11999                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12000                pw.print(prefix);
12001                pw.print("    ");
12002                pw.print("keeping="); pw.print(r.keeping);
12003                pw.print(" cached="); pw.print(r.cached);
12004                pw.print(" empty="); pw.print(r.empty);
12005                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12006
12007                if (!r.keeping) {
12008                    if (r.lastWakeTime != 0) {
12009                        long wtime;
12010                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12011                        synchronized (stats) {
12012                            wtime = stats.getProcessWakeTime(r.info.uid,
12013                                    r.pid, curRealtime);
12014                        }
12015                        long timeUsed = wtime - r.lastWakeTime;
12016                        pw.print(prefix);
12017                        pw.print("    ");
12018                        pw.print("keep awake over ");
12019                        TimeUtils.formatDuration(realtimeSince, pw);
12020                        pw.print(" used ");
12021                        TimeUtils.formatDuration(timeUsed, pw);
12022                        pw.print(" (");
12023                        pw.print((timeUsed*100)/realtimeSince);
12024                        pw.println("%)");
12025                    }
12026                    if (r.lastCpuTime != 0) {
12027                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12028                        pw.print(prefix);
12029                        pw.print("    ");
12030                        pw.print("run cpu over ");
12031                        TimeUtils.formatDuration(uptimeSince, pw);
12032                        pw.print(" used ");
12033                        TimeUtils.formatDuration(timeUsed, pw);
12034                        pw.print(" (");
12035                        pw.print((timeUsed*100)/uptimeSince);
12036                        pw.println("%)");
12037                    }
12038                }
12039            }
12040        }
12041        return true;
12042    }
12043
12044    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12045        ArrayList<ProcessRecord> procs;
12046        synchronized (this) {
12047            if (args != null && args.length > start
12048                    && args[start].charAt(0) != '-') {
12049                procs = new ArrayList<ProcessRecord>();
12050                int pid = -1;
12051                try {
12052                    pid = Integer.parseInt(args[start]);
12053                } catch (NumberFormatException e) {
12054                }
12055                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12056                    ProcessRecord proc = mLruProcesses.get(i);
12057                    if (proc.pid == pid) {
12058                        procs.add(proc);
12059                    } else if (proc.processName.equals(args[start])) {
12060                        procs.add(proc);
12061                    }
12062                }
12063                if (procs.size() <= 0) {
12064                    return null;
12065                }
12066            } else {
12067                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12068            }
12069        }
12070        return procs;
12071    }
12072
12073    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12074            PrintWriter pw, String[] args) {
12075        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12076        if (procs == null) {
12077            pw.println("No process found for: " + args[0]);
12078            return;
12079        }
12080
12081        long uptime = SystemClock.uptimeMillis();
12082        long realtime = SystemClock.elapsedRealtime();
12083        pw.println("Applications Graphics Acceleration Info:");
12084        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12085
12086        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12087            ProcessRecord r = procs.get(i);
12088            if (r.thread != null) {
12089                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12090                pw.flush();
12091                try {
12092                    TransferPipe tp = new TransferPipe();
12093                    try {
12094                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12095                        tp.go(fd);
12096                    } finally {
12097                        tp.kill();
12098                    }
12099                } catch (IOException e) {
12100                    pw.println("Failure while dumping the app: " + r);
12101                    pw.flush();
12102                } catch (RemoteException e) {
12103                    pw.println("Got a RemoteException while dumping the app " + r);
12104                    pw.flush();
12105                }
12106            }
12107        }
12108    }
12109
12110    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12111        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12112        if (procs == null) {
12113            pw.println("No process found for: " + args[0]);
12114            return;
12115        }
12116
12117        pw.println("Applications Database Info:");
12118
12119        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12120            ProcessRecord r = procs.get(i);
12121            if (r.thread != null) {
12122                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12123                pw.flush();
12124                try {
12125                    TransferPipe tp = new TransferPipe();
12126                    try {
12127                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12128                        tp.go(fd);
12129                    } finally {
12130                        tp.kill();
12131                    }
12132                } catch (IOException e) {
12133                    pw.println("Failure while dumping the app: " + r);
12134                    pw.flush();
12135                } catch (RemoteException e) {
12136                    pw.println("Got a RemoteException while dumping the app " + r);
12137                    pw.flush();
12138                }
12139            }
12140        }
12141    }
12142
12143    final static class MemItem {
12144        final boolean isProc;
12145        final String label;
12146        final String shortLabel;
12147        final long pss;
12148        final int id;
12149        final boolean hasActivities;
12150        ArrayList<MemItem> subitems;
12151
12152        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12153                boolean _hasActivities) {
12154            isProc = true;
12155            label = _label;
12156            shortLabel = _shortLabel;
12157            pss = _pss;
12158            id = _id;
12159            hasActivities = _hasActivities;
12160        }
12161
12162        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12163            isProc = false;
12164            label = _label;
12165            shortLabel = _shortLabel;
12166            pss = _pss;
12167            id = _id;
12168            hasActivities = false;
12169        }
12170    }
12171
12172    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12173            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12174        if (sort && !isCompact) {
12175            Collections.sort(items, new Comparator<MemItem>() {
12176                @Override
12177                public int compare(MemItem lhs, MemItem rhs) {
12178                    if (lhs.pss < rhs.pss) {
12179                        return 1;
12180                    } else if (lhs.pss > rhs.pss) {
12181                        return -1;
12182                    }
12183                    return 0;
12184                }
12185            });
12186        }
12187
12188        for (int i=0; i<items.size(); i++) {
12189            MemItem mi = items.get(i);
12190            if (!isCompact) {
12191                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12192            } else if (mi.isProc) {
12193                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12194                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12195                pw.println(mi.hasActivities ? ",a" : ",e");
12196            } else {
12197                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12198                pw.println(mi.pss);
12199            }
12200            if (mi.subitems != null) {
12201                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12202                        true, isCompact);
12203            }
12204        }
12205    }
12206
12207    // These are in KB.
12208    static final long[] DUMP_MEM_BUCKETS = new long[] {
12209        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12210        120*1024, 160*1024, 200*1024,
12211        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12212        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12213    };
12214
12215    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12216            boolean stackLike) {
12217        int start = label.lastIndexOf('.');
12218        if (start >= 0) start++;
12219        else start = 0;
12220        int end = label.length();
12221        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12222            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12223                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12224                out.append(bucket);
12225                out.append(stackLike ? "MB." : "MB ");
12226                out.append(label, start, end);
12227                return;
12228            }
12229        }
12230        out.append(memKB/1024);
12231        out.append(stackLike ? "MB." : "MB ");
12232        out.append(label, start, end);
12233    }
12234
12235    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12236            ProcessList.NATIVE_ADJ,
12237            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12238            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12239            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12240            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12241            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12242    };
12243    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12244            "Native",
12245            "System", "Persistent", "Foreground",
12246            "Visible", "Perceptible",
12247            "Heavy Weight", "Backup",
12248            "A Services", "Home",
12249            "Previous", "B Services", "Cached"
12250    };
12251    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12252            "native",
12253            "sys", "pers", "fore",
12254            "vis", "percept",
12255            "heavy", "backup",
12256            "servicea", "home",
12257            "prev", "serviceb", "cached"
12258    };
12259
12260    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12261            long realtime, boolean isCheckinRequest, boolean isCompact) {
12262        if (isCheckinRequest || isCompact) {
12263            // short checkin version
12264            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12265        } else {
12266            pw.println("Applications Memory Usage (kB):");
12267            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12268        }
12269    }
12270
12271    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12272            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12273        boolean dumpDetails = false;
12274        boolean dumpFullDetails = false;
12275        boolean dumpDalvik = false;
12276        boolean oomOnly = false;
12277        boolean isCompact = false;
12278        boolean localOnly = false;
12279
12280        int opti = 0;
12281        while (opti < args.length) {
12282            String opt = args[opti];
12283            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12284                break;
12285            }
12286            opti++;
12287            if ("-a".equals(opt)) {
12288                dumpDetails = true;
12289                dumpFullDetails = true;
12290                dumpDalvik = true;
12291            } else if ("-d".equals(opt)) {
12292                dumpDalvik = true;
12293            } else if ("-c".equals(opt)) {
12294                isCompact = true;
12295            } else if ("--oom".equals(opt)) {
12296                oomOnly = true;
12297            } else if ("--local".equals(opt)) {
12298                localOnly = true;
12299            } else if ("-h".equals(opt)) {
12300                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12301                pw.println("  -a: include all available information for each process.");
12302                pw.println("  -d: include dalvik details when dumping process details.");
12303                pw.println("  -c: dump in a compact machine-parseable representation.");
12304                pw.println("  --oom: only show processes organized by oom adj.");
12305                pw.println("  --local: only collect details locally, don't call process.");
12306                pw.println("If [process] is specified it can be the name or ");
12307                pw.println("pid of a specific process to dump.");
12308                return;
12309            } else {
12310                pw.println("Unknown argument: " + opt + "; use -h for help");
12311            }
12312        }
12313
12314        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12315        long uptime = SystemClock.uptimeMillis();
12316        long realtime = SystemClock.elapsedRealtime();
12317        final long[] tmpLong = new long[1];
12318
12319        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12320        if (procs == null) {
12321            // No Java processes.  Maybe they want to print a native process.
12322            if (args != null && args.length > opti
12323                    && args[opti].charAt(0) != '-') {
12324                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12325                        = new ArrayList<ProcessCpuTracker.Stats>();
12326                updateCpuStatsNow();
12327                int findPid = -1;
12328                try {
12329                    findPid = Integer.parseInt(args[opti]);
12330                } catch (NumberFormatException e) {
12331                }
12332                synchronized (mProcessCpuThread) {
12333                    final int N = mProcessCpuTracker.countStats();
12334                    for (int i=0; i<N; i++) {
12335                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12336                        if (st.pid == findPid || (st.baseName != null
12337                                && st.baseName.equals(args[opti]))) {
12338                            nativeProcs.add(st);
12339                        }
12340                    }
12341                }
12342                if (nativeProcs.size() > 0) {
12343                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12344                            isCompact);
12345                    Debug.MemoryInfo mi = null;
12346                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12347                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12348                        final int pid = r.pid;
12349                        if (!isCheckinRequest && dumpDetails) {
12350                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12351                        }
12352                        if (mi == null) {
12353                            mi = new Debug.MemoryInfo();
12354                        }
12355                        if (dumpDetails || (!brief && !oomOnly)) {
12356                            Debug.getMemoryInfo(pid, mi);
12357                        } else {
12358                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12359                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12360                        }
12361                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12362                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12363                        if (isCheckinRequest) {
12364                            pw.println();
12365                        }
12366                    }
12367                    return;
12368                }
12369            }
12370            pw.println("No process found for: " + args[opti]);
12371            return;
12372        }
12373
12374        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12375            dumpDetails = true;
12376        }
12377
12378        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12379
12380        String[] innerArgs = new String[args.length-opti];
12381        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12382
12383        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12384        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12385        long nativePss=0, dalvikPss=0, otherPss=0;
12386        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12387
12388        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12389        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12390                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12391
12392        long totalPss = 0;
12393        long cachedPss = 0;
12394
12395        Debug.MemoryInfo mi = null;
12396        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12397            final ProcessRecord r = procs.get(i);
12398            final IApplicationThread thread;
12399            final int pid;
12400            final int oomAdj;
12401            final boolean hasActivities;
12402            synchronized (this) {
12403                thread = r.thread;
12404                pid = r.pid;
12405                oomAdj = r.getSetAdjWithServices();
12406                hasActivities = r.activities.size() > 0;
12407            }
12408            if (thread != null) {
12409                if (!isCheckinRequest && dumpDetails) {
12410                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12411                }
12412                if (mi == null) {
12413                    mi = new Debug.MemoryInfo();
12414                }
12415                if (dumpDetails || (!brief && !oomOnly)) {
12416                    Debug.getMemoryInfo(pid, mi);
12417                } else {
12418                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12419                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12420                }
12421                if (dumpDetails) {
12422                    if (localOnly) {
12423                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12424                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12425                        if (isCheckinRequest) {
12426                            pw.println();
12427                        }
12428                    } else {
12429                        try {
12430                            pw.flush();
12431                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12432                                    dumpDalvik, innerArgs);
12433                        } catch (RemoteException e) {
12434                            if (!isCheckinRequest) {
12435                                pw.println("Got RemoteException!");
12436                                pw.flush();
12437                            }
12438                        }
12439                    }
12440                }
12441
12442                final long myTotalPss = mi.getTotalPss();
12443                final long myTotalUss = mi.getTotalUss();
12444
12445                synchronized (this) {
12446                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12447                        // Record this for posterity if the process has been stable.
12448                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12449                    }
12450                }
12451
12452                if (!isCheckinRequest && mi != null) {
12453                    totalPss += myTotalPss;
12454                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12455                            (hasActivities ? " / activities)" : ")"),
12456                            r.processName, myTotalPss, pid, hasActivities);
12457                    procMems.add(pssItem);
12458                    procMemsMap.put(pid, pssItem);
12459
12460                    nativePss += mi.nativePss;
12461                    dalvikPss += mi.dalvikPss;
12462                    otherPss += mi.otherPss;
12463                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12464                        long mem = mi.getOtherPss(j);
12465                        miscPss[j] += mem;
12466                        otherPss -= mem;
12467                    }
12468
12469                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12470                        cachedPss += myTotalPss;
12471                    }
12472
12473                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12474                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12475                                || oomIndex == (oomPss.length-1)) {
12476                            oomPss[oomIndex] += myTotalPss;
12477                            if (oomProcs[oomIndex] == null) {
12478                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12479                            }
12480                            oomProcs[oomIndex].add(pssItem);
12481                            break;
12482                        }
12483                    }
12484                }
12485            }
12486        }
12487
12488        if (!isCheckinRequest && procs.size() > 1) {
12489            // If we are showing aggregations, also look for native processes to
12490            // include so that our aggregations are more accurate.
12491            updateCpuStatsNow();
12492            synchronized (mProcessCpuThread) {
12493                final int N = mProcessCpuTracker.countStats();
12494                for (int i=0; i<N; i++) {
12495                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12496                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12497                        if (mi == null) {
12498                            mi = new Debug.MemoryInfo();
12499                        }
12500                        if (!brief && !oomOnly) {
12501                            Debug.getMemoryInfo(st.pid, mi);
12502                        } else {
12503                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12504                            mi.nativePrivateDirty = (int)tmpLong[0];
12505                        }
12506
12507                        final long myTotalPss = mi.getTotalPss();
12508                        totalPss += myTotalPss;
12509
12510                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12511                                st.name, myTotalPss, st.pid, false);
12512                        procMems.add(pssItem);
12513
12514                        nativePss += mi.nativePss;
12515                        dalvikPss += mi.dalvikPss;
12516                        otherPss += mi.otherPss;
12517                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12518                            long mem = mi.getOtherPss(j);
12519                            miscPss[j] += mem;
12520                            otherPss -= mem;
12521                        }
12522                        oomPss[0] += myTotalPss;
12523                        if (oomProcs[0] == null) {
12524                            oomProcs[0] = new ArrayList<MemItem>();
12525                        }
12526                        oomProcs[0].add(pssItem);
12527                    }
12528                }
12529            }
12530
12531            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12532
12533            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12534            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12535            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12536            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12537                String label = Debug.MemoryInfo.getOtherLabel(j);
12538                catMems.add(new MemItem(label, label, miscPss[j], j));
12539            }
12540
12541            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12542            for (int j=0; j<oomPss.length; j++) {
12543                if (oomPss[j] != 0) {
12544                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12545                            : DUMP_MEM_OOM_LABEL[j];
12546                    MemItem item = new MemItem(label, label, oomPss[j],
12547                            DUMP_MEM_OOM_ADJ[j]);
12548                    item.subitems = oomProcs[j];
12549                    oomMems.add(item);
12550                }
12551            }
12552
12553            if (!brief && !oomOnly && !isCompact) {
12554                pw.println();
12555                pw.println("Total PSS by process:");
12556                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12557                pw.println();
12558            }
12559            if (!isCompact) {
12560                pw.println("Total PSS by OOM adjustment:");
12561            }
12562            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12563            if (!brief && !oomOnly) {
12564                PrintWriter out = categoryPw != null ? categoryPw : pw;
12565                if (!isCompact) {
12566                    out.println();
12567                    out.println("Total PSS by category:");
12568                }
12569                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12570            }
12571            if (!isCompact) {
12572                pw.println();
12573            }
12574            MemInfoReader memInfo = new MemInfoReader();
12575            memInfo.readMemInfo();
12576            if (!brief) {
12577                if (!isCompact) {
12578                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12579                    pw.print(" kB (status ");
12580                    switch (mLastMemoryLevel) {
12581                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12582                            pw.println("normal)");
12583                            break;
12584                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12585                            pw.println("moderate)");
12586                            break;
12587                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12588                            pw.println("low)");
12589                            break;
12590                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12591                            pw.println("critical)");
12592                            break;
12593                        default:
12594                            pw.print(mLastMemoryLevel);
12595                            pw.println(")");
12596                            break;
12597                    }
12598                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12599                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12600                            pw.print(cachedPss); pw.print(" cached pss + ");
12601                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12602                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12603                } else {
12604                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12605                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12606                            + memInfo.getFreeSizeKb()); pw.print(",");
12607                    pw.println(totalPss - cachedPss);
12608                }
12609            }
12610            if (!isCompact) {
12611                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12612                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12613                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12614                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12615                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12616                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12617                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12618                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12619                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12620                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12621                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12622            }
12623            if (!brief) {
12624                if (memInfo.getZramTotalSizeKb() != 0) {
12625                    if (!isCompact) {
12626                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12627                                pw.print(" kB physical used for ");
12628                                pw.print(memInfo.getSwapTotalSizeKb()
12629                                        - memInfo.getSwapFreeSizeKb());
12630                                pw.print(" kB in swap (");
12631                                pw.print(memInfo.getSwapTotalSizeKb());
12632                                pw.println(" kB total swap)");
12633                    } else {
12634                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12635                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12636                                pw.println(memInfo.getSwapFreeSizeKb());
12637                    }
12638                }
12639                final int[] SINGLE_LONG_FORMAT = new int[] {
12640                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12641                };
12642                long[] longOut = new long[1];
12643                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12644                        SINGLE_LONG_FORMAT, null, longOut, null);
12645                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12646                longOut[0] = 0;
12647                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12648                        SINGLE_LONG_FORMAT, null, longOut, null);
12649                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12650                longOut[0] = 0;
12651                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12652                        SINGLE_LONG_FORMAT, null, longOut, null);
12653                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12654                longOut[0] = 0;
12655                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12656                        SINGLE_LONG_FORMAT, null, longOut, null);
12657                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12658                if (!isCompact) {
12659                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12660                        pw.print("      KSM: "); pw.print(sharing);
12661                                pw.print(" kB saved from shared ");
12662                                pw.print(shared); pw.println(" kB");
12663                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12664                                pw.print(voltile); pw.println(" kB volatile");
12665                    }
12666                    pw.print("   Tuning: ");
12667                    pw.print(ActivityManager.staticGetMemoryClass());
12668                    pw.print(" (large ");
12669                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12670                    pw.print("), oom ");
12671                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12672                    pw.print(" kB");
12673                    pw.print(", restore limit ");
12674                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12675                    pw.print(" kB");
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                } else {
12684                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12685                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12686                    pw.println(voltile);
12687                    pw.print("tuning,");
12688                    pw.print(ActivityManager.staticGetMemoryClass());
12689                    pw.print(',');
12690                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12691                    pw.print(',');
12692                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12693                    if (ActivityManager.isLowRamDeviceStatic()) {
12694                        pw.print(",low-ram");
12695                    }
12696                    if (ActivityManager.isHighEndGfx()) {
12697                        pw.print(",high-end-gfx");
12698                    }
12699                    pw.println();
12700                }
12701            }
12702        }
12703    }
12704
12705    /**
12706     * Searches array of arguments for the specified string
12707     * @param args array of argument strings
12708     * @param value value to search for
12709     * @return true if the value is contained in the array
12710     */
12711    private static boolean scanArgs(String[] args, String value) {
12712        if (args != null) {
12713            for (String arg : args) {
12714                if (value.equals(arg)) {
12715                    return true;
12716                }
12717            }
12718        }
12719        return false;
12720    }
12721
12722    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12723            ContentProviderRecord cpr, boolean always) {
12724        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12725
12726        if (!inLaunching || always) {
12727            synchronized (cpr) {
12728                cpr.launchingApp = null;
12729                cpr.notifyAll();
12730            }
12731            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12732            String names[] = cpr.info.authority.split(";");
12733            for (int j = 0; j < names.length; j++) {
12734                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12735            }
12736        }
12737
12738        for (int i=0; i<cpr.connections.size(); i++) {
12739            ContentProviderConnection conn = cpr.connections.get(i);
12740            if (conn.waiting) {
12741                // If this connection is waiting for the provider, then we don't
12742                // need to mess with its process unless we are always removing
12743                // or for some reason the provider is not currently launching.
12744                if (inLaunching && !always) {
12745                    continue;
12746                }
12747            }
12748            ProcessRecord capp = conn.client;
12749            conn.dead = true;
12750            if (conn.stableCount > 0) {
12751                if (!capp.persistent && capp.thread != null
12752                        && capp.pid != 0
12753                        && capp.pid != MY_PID) {
12754                    killUnneededProcessLocked(capp, "depends on provider "
12755                            + cpr.name.flattenToShortString()
12756                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12757                }
12758            } else if (capp.thread != null && conn.provider.provider != null) {
12759                try {
12760                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12761                } catch (RemoteException e) {
12762                }
12763                // In the protocol here, we don't expect the client to correctly
12764                // clean up this connection, we'll just remove it.
12765                cpr.connections.remove(i);
12766                conn.client.conProviders.remove(conn);
12767            }
12768        }
12769
12770        if (inLaunching && always) {
12771            mLaunchingProviders.remove(cpr);
12772        }
12773        return inLaunching;
12774    }
12775
12776    /**
12777     * Main code for cleaning up a process when it has gone away.  This is
12778     * called both as a result of the process dying, or directly when stopping
12779     * a process when running in single process mode.
12780     */
12781    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12782            boolean restarting, boolean allowRestart, int index) {
12783        if (index >= 0) {
12784            removeLruProcessLocked(app);
12785            ProcessList.remove(app.pid);
12786        }
12787
12788        mProcessesToGc.remove(app);
12789        mPendingPssProcesses.remove(app);
12790
12791        // Dismiss any open dialogs.
12792        if (app.crashDialog != null && !app.forceCrashReport) {
12793            app.crashDialog.dismiss();
12794            app.crashDialog = null;
12795        }
12796        if (app.anrDialog != null) {
12797            app.anrDialog.dismiss();
12798            app.anrDialog = null;
12799        }
12800        if (app.waitDialog != null) {
12801            app.waitDialog.dismiss();
12802            app.waitDialog = null;
12803        }
12804
12805        app.crashing = false;
12806        app.notResponding = false;
12807
12808        app.resetPackageList(mProcessStats);
12809        app.unlinkDeathRecipient();
12810        app.makeInactive(mProcessStats);
12811        app.forcingToForeground = null;
12812        updateProcessForegroundLocked(app, false, false);
12813        app.foregroundActivities = false;
12814        app.hasShownUi = false;
12815        app.treatLikeActivity = false;
12816        app.hasAboveClient = false;
12817        app.hasClientActivities = false;
12818
12819        mServices.killServicesLocked(app, allowRestart);
12820
12821        boolean restart = false;
12822
12823        // Remove published content providers.
12824        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12825            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12826            final boolean always = app.bad || !allowRestart;
12827            if (removeDyingProviderLocked(app, cpr, always) || always) {
12828                // We left the provider in the launching list, need to
12829                // restart it.
12830                restart = true;
12831            }
12832
12833            cpr.provider = null;
12834            cpr.proc = null;
12835        }
12836        app.pubProviders.clear();
12837
12838        // Take care of any launching providers waiting for this process.
12839        if (checkAppInLaunchingProvidersLocked(app, false)) {
12840            restart = true;
12841        }
12842
12843        // Unregister from connected content providers.
12844        if (!app.conProviders.isEmpty()) {
12845            for (int i=0; i<app.conProviders.size(); i++) {
12846                ContentProviderConnection conn = app.conProviders.get(i);
12847                conn.provider.connections.remove(conn);
12848            }
12849            app.conProviders.clear();
12850        }
12851
12852        // At this point there may be remaining entries in mLaunchingProviders
12853        // where we were the only one waiting, so they are no longer of use.
12854        // Look for these and clean up if found.
12855        // XXX Commented out for now.  Trying to figure out a way to reproduce
12856        // the actual situation to identify what is actually going on.
12857        if (false) {
12858            for (int i=0; i<mLaunchingProviders.size(); i++) {
12859                ContentProviderRecord cpr = (ContentProviderRecord)
12860                        mLaunchingProviders.get(i);
12861                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12862                    synchronized (cpr) {
12863                        cpr.launchingApp = null;
12864                        cpr.notifyAll();
12865                    }
12866                }
12867            }
12868        }
12869
12870        skipCurrentReceiverLocked(app);
12871
12872        // Unregister any receivers.
12873        for (int i=app.receivers.size()-1; i>=0; i--) {
12874            removeReceiverLocked(app.receivers.valueAt(i));
12875        }
12876        app.receivers.clear();
12877
12878        // If the app is undergoing backup, tell the backup manager about it
12879        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12880            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12881                    + mBackupTarget.appInfo + " died during backup");
12882            try {
12883                IBackupManager bm = IBackupManager.Stub.asInterface(
12884                        ServiceManager.getService(Context.BACKUP_SERVICE));
12885                bm.agentDisconnected(app.info.packageName);
12886            } catch (RemoteException e) {
12887                // can't happen; backup manager is local
12888            }
12889        }
12890
12891        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12892            ProcessChangeItem item = mPendingProcessChanges.get(i);
12893            if (item.pid == app.pid) {
12894                mPendingProcessChanges.remove(i);
12895                mAvailProcessChanges.add(item);
12896            }
12897        }
12898        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12899
12900        // If the caller is restarting this app, then leave it in its
12901        // current lists and let the caller take care of it.
12902        if (restarting) {
12903            return;
12904        }
12905
12906        if (!app.persistent || app.isolated) {
12907            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12908                    "Removing non-persistent process during cleanup: " + app);
12909            mProcessNames.remove(app.processName, app.uid);
12910            mIsolatedProcesses.remove(app.uid);
12911            if (mHeavyWeightProcess == app) {
12912                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12913                        mHeavyWeightProcess.userId, 0));
12914                mHeavyWeightProcess = null;
12915            }
12916        } else if (!app.removed) {
12917            // This app is persistent, so we need to keep its record around.
12918            // If it is not already on the pending app list, add it there
12919            // and start a new process for it.
12920            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12921                mPersistentStartingProcesses.add(app);
12922                restart = true;
12923            }
12924        }
12925        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12926                "Clean-up removing on hold: " + app);
12927        mProcessesOnHold.remove(app);
12928
12929        if (app == mHomeProcess) {
12930            mHomeProcess = null;
12931        }
12932        if (app == mPreviousProcess) {
12933            mPreviousProcess = null;
12934        }
12935
12936        if (restart && !app.isolated) {
12937            // We have components that still need to be running in the
12938            // process, so re-launch it.
12939            mProcessNames.put(app.processName, app.uid, app);
12940            startProcessLocked(app, "restart", app.processName);
12941        } else if (app.pid > 0 && app.pid != MY_PID) {
12942            // Goodbye!
12943            boolean removed;
12944            synchronized (mPidsSelfLocked) {
12945                mPidsSelfLocked.remove(app.pid);
12946                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12947            }
12948            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
12949                    app.processName, app.info.uid);
12950            if (app.isolated) {
12951                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
12952            }
12953            app.setPid(0);
12954        }
12955    }
12956
12957    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12958        // Look through the content providers we are waiting to have launched,
12959        // and if any run in this process then either schedule a restart of
12960        // the process or kill the client waiting for it if this process has
12961        // gone bad.
12962        int NL = mLaunchingProviders.size();
12963        boolean restart = false;
12964        for (int i=0; i<NL; i++) {
12965            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12966            if (cpr.launchingApp == app) {
12967                if (!alwaysBad && !app.bad) {
12968                    restart = true;
12969                } else {
12970                    removeDyingProviderLocked(app, cpr, true);
12971                    // cpr should have been removed from mLaunchingProviders
12972                    NL = mLaunchingProviders.size();
12973                    i--;
12974                }
12975            }
12976        }
12977        return restart;
12978    }
12979
12980    // =========================================================
12981    // SERVICES
12982    // =========================================================
12983
12984    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12985            int flags) {
12986        enforceNotIsolatedCaller("getServices");
12987        synchronized (this) {
12988            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12989        }
12990    }
12991
12992    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12993        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12994        synchronized (this) {
12995            return mServices.getRunningServiceControlPanelLocked(name);
12996        }
12997    }
12998
12999    public ComponentName startService(IApplicationThread caller, Intent service,
13000            String resolvedType, int userId) {
13001        enforceNotIsolatedCaller("startService");
13002        // Refuse possible leaked file descriptors
13003        if (service != null && service.hasFileDescriptors() == true) {
13004            throw new IllegalArgumentException("File descriptors passed in Intent");
13005        }
13006
13007        if (DEBUG_SERVICE)
13008            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13009        synchronized(this) {
13010            final int callingPid = Binder.getCallingPid();
13011            final int callingUid = Binder.getCallingUid();
13012            final long origId = Binder.clearCallingIdentity();
13013            ComponentName res = mServices.startServiceLocked(caller, service,
13014                    resolvedType, callingPid, callingUid, userId);
13015            Binder.restoreCallingIdentity(origId);
13016            return res;
13017        }
13018    }
13019
13020    ComponentName startServiceInPackage(int uid,
13021            Intent service, String resolvedType, int userId) {
13022        synchronized(this) {
13023            if (DEBUG_SERVICE)
13024                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13025            final long origId = Binder.clearCallingIdentity();
13026            ComponentName res = mServices.startServiceLocked(null, service,
13027                    resolvedType, -1, uid, userId);
13028            Binder.restoreCallingIdentity(origId);
13029            return res;
13030        }
13031    }
13032
13033    public int stopService(IApplicationThread caller, Intent service,
13034            String resolvedType, int userId) {
13035        enforceNotIsolatedCaller("stopService");
13036        // Refuse possible leaked file descriptors
13037        if (service != null && service.hasFileDescriptors() == true) {
13038            throw new IllegalArgumentException("File descriptors passed in Intent");
13039        }
13040
13041        synchronized(this) {
13042            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13043        }
13044    }
13045
13046    public IBinder peekService(Intent service, String resolvedType) {
13047        enforceNotIsolatedCaller("peekService");
13048        // Refuse possible leaked file descriptors
13049        if (service != null && service.hasFileDescriptors() == true) {
13050            throw new IllegalArgumentException("File descriptors passed in Intent");
13051        }
13052        synchronized(this) {
13053            return mServices.peekServiceLocked(service, resolvedType);
13054        }
13055    }
13056
13057    public boolean stopServiceToken(ComponentName className, IBinder token,
13058            int startId) {
13059        synchronized(this) {
13060            return mServices.stopServiceTokenLocked(className, token, startId);
13061        }
13062    }
13063
13064    public void setServiceForeground(ComponentName className, IBinder token,
13065            int id, Notification notification, boolean removeNotification) {
13066        synchronized(this) {
13067            mServices.setServiceForegroundLocked(className, token, id, notification,
13068                    removeNotification);
13069        }
13070    }
13071
13072    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13073            boolean requireFull, String name, String callerPackage) {
13074        final int callingUserId = UserHandle.getUserId(callingUid);
13075        if (callingUserId != userId) {
13076            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13077                if ((requireFull || checkComponentPermission(
13078                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13079                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
13080                        && checkComponentPermission(
13081                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
13082                                callingPid, callingUid, -1, true)
13083                                != PackageManager.PERMISSION_GRANTED) {
13084                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13085                        // In this case, they would like to just execute as their
13086                        // owner user instead of failing.
13087                        userId = callingUserId;
13088                    } else {
13089                        StringBuilder builder = new StringBuilder(128);
13090                        builder.append("Permission Denial: ");
13091                        builder.append(name);
13092                        if (callerPackage != null) {
13093                            builder.append(" from ");
13094                            builder.append(callerPackage);
13095                        }
13096                        builder.append(" asks to run as user ");
13097                        builder.append(userId);
13098                        builder.append(" but is calling from user ");
13099                        builder.append(UserHandle.getUserId(callingUid));
13100                        builder.append("; this requires ");
13101                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
13102                        if (!requireFull) {
13103                            builder.append(" or ");
13104                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
13105                        }
13106                        String msg = builder.toString();
13107                        Slog.w(TAG, msg);
13108                        throw new SecurityException(msg);
13109                    }
13110                }
13111            }
13112            if (userId == UserHandle.USER_CURRENT
13113                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
13114                // Note that we may be accessing this outside of a lock...
13115                // shouldn't be a big deal, if this is being called outside
13116                // of a locked context there is intrinsically a race with
13117                // the value the caller will receive and someone else changing it.
13118                userId = mCurrentUserId;
13119            }
13120            if (!allowAll && userId < 0) {
13121                throw new IllegalArgumentException(
13122                        "Call does not support special user #" + userId);
13123            }
13124        }
13125        return userId;
13126    }
13127
13128    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13129            String className, int flags) {
13130        boolean result = false;
13131        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13132            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
13133                if (ActivityManager.checkUidPermission(
13134                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13135                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13136                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13137                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13138                            + " requests FLAG_SINGLE_USER, but app does not hold "
13139                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
13140                    Slog.w(TAG, msg);
13141                    throw new SecurityException(msg);
13142                }
13143                result = true;
13144            }
13145        } else if (componentProcessName == aInfo.packageName) {
13146            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13147        } else if ("system".equals(componentProcessName)) {
13148            result = true;
13149        }
13150        if (DEBUG_MU) {
13151            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13152                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13153        }
13154        return result;
13155    }
13156
13157    public int bindService(IApplicationThread caller, IBinder token,
13158            Intent service, String resolvedType,
13159            IServiceConnection connection, int flags, int userId) {
13160        enforceNotIsolatedCaller("bindService");
13161        // Refuse possible leaked file descriptors
13162        if (service != null && service.hasFileDescriptors() == true) {
13163            throw new IllegalArgumentException("File descriptors passed in Intent");
13164        }
13165
13166        synchronized(this) {
13167            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13168                    connection, flags, userId);
13169        }
13170    }
13171
13172    public boolean unbindService(IServiceConnection connection) {
13173        synchronized (this) {
13174            return mServices.unbindServiceLocked(connection);
13175        }
13176    }
13177
13178    public void publishService(IBinder token, Intent intent, IBinder service) {
13179        // Refuse possible leaked file descriptors
13180        if (intent != null && intent.hasFileDescriptors() == true) {
13181            throw new IllegalArgumentException("File descriptors passed in Intent");
13182        }
13183
13184        synchronized(this) {
13185            if (!(token instanceof ServiceRecord)) {
13186                throw new IllegalArgumentException("Invalid service token");
13187            }
13188            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13189        }
13190    }
13191
13192    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13193        // Refuse possible leaked file descriptors
13194        if (intent != null && intent.hasFileDescriptors() == true) {
13195            throw new IllegalArgumentException("File descriptors passed in Intent");
13196        }
13197
13198        synchronized(this) {
13199            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13200        }
13201    }
13202
13203    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13204        synchronized(this) {
13205            if (!(token instanceof ServiceRecord)) {
13206                throw new IllegalArgumentException("Invalid service token");
13207            }
13208            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13209        }
13210    }
13211
13212    // =========================================================
13213    // BACKUP AND RESTORE
13214    // =========================================================
13215
13216    // Cause the target app to be launched if necessary and its backup agent
13217    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13218    // activity manager to announce its creation.
13219    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13220        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13221        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
13222
13223        synchronized(this) {
13224            // !!! TODO: currently no check here that we're already bound
13225            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13226            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13227            synchronized (stats) {
13228                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13229            }
13230
13231            // Backup agent is now in use, its package can't be stopped.
13232            try {
13233                AppGlobals.getPackageManager().setPackageStoppedState(
13234                        app.packageName, false, UserHandle.getUserId(app.uid));
13235            } catch (RemoteException e) {
13236            } catch (IllegalArgumentException e) {
13237                Slog.w(TAG, "Failed trying to unstop package "
13238                        + app.packageName + ": " + e);
13239            }
13240
13241            BackupRecord r = new BackupRecord(ss, app, backupMode);
13242            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13243                    ? new ComponentName(app.packageName, app.backupAgentName)
13244                    : new ComponentName("android", "FullBackupAgent");
13245            // startProcessLocked() returns existing proc's record if it's already running
13246            ProcessRecord proc = startProcessLocked(app.processName, app,
13247                    false, 0, "backup", hostingName, false, false, false);
13248            if (proc == null) {
13249                Slog.e(TAG, "Unable to start backup agent process " + r);
13250                return false;
13251            }
13252
13253            r.app = proc;
13254            mBackupTarget = r;
13255            mBackupAppName = app.packageName;
13256
13257            // Try not to kill the process during backup
13258            updateOomAdjLocked(proc);
13259
13260            // If the process is already attached, schedule the creation of the backup agent now.
13261            // If it is not yet live, this will be done when it attaches to the framework.
13262            if (proc.thread != null) {
13263                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13264                try {
13265                    proc.thread.scheduleCreateBackupAgent(app,
13266                            compatibilityInfoForPackageLocked(app), backupMode);
13267                } catch (RemoteException e) {
13268                    // Will time out on the backup manager side
13269                }
13270            } else {
13271                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13272            }
13273            // Invariants: at this point, the target app process exists and the application
13274            // is either already running or in the process of coming up.  mBackupTarget and
13275            // mBackupAppName describe the app, so that when it binds back to the AM we
13276            // know that it's scheduled for a backup-agent operation.
13277        }
13278
13279        return true;
13280    }
13281
13282    @Override
13283    public void clearPendingBackup() {
13284        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13285        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13286
13287        synchronized (this) {
13288            mBackupTarget = null;
13289            mBackupAppName = null;
13290        }
13291    }
13292
13293    // A backup agent has just come up
13294    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13295        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13296                + " = " + agent);
13297
13298        synchronized(this) {
13299            if (!agentPackageName.equals(mBackupAppName)) {
13300                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13301                return;
13302            }
13303        }
13304
13305        long oldIdent = Binder.clearCallingIdentity();
13306        try {
13307            IBackupManager bm = IBackupManager.Stub.asInterface(
13308                    ServiceManager.getService(Context.BACKUP_SERVICE));
13309            bm.agentConnected(agentPackageName, agent);
13310        } catch (RemoteException e) {
13311            // can't happen; the backup manager service is local
13312        } catch (Exception e) {
13313            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13314            e.printStackTrace();
13315        } finally {
13316            Binder.restoreCallingIdentity(oldIdent);
13317        }
13318    }
13319
13320    // done with this agent
13321    public void unbindBackupAgent(ApplicationInfo appInfo) {
13322        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13323        if (appInfo == null) {
13324            Slog.w(TAG, "unbind backup agent for null app");
13325            return;
13326        }
13327
13328        synchronized(this) {
13329            try {
13330                if (mBackupAppName == null) {
13331                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13332                    return;
13333                }
13334
13335                if (!mBackupAppName.equals(appInfo.packageName)) {
13336                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13337                    return;
13338                }
13339
13340                // Not backing this app up any more; reset its OOM adjustment
13341                final ProcessRecord proc = mBackupTarget.app;
13342                updateOomAdjLocked(proc);
13343
13344                // If the app crashed during backup, 'thread' will be null here
13345                if (proc.thread != null) {
13346                    try {
13347                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13348                                compatibilityInfoForPackageLocked(appInfo));
13349                    } catch (Exception e) {
13350                        Slog.e(TAG, "Exception when unbinding backup agent:");
13351                        e.printStackTrace();
13352                    }
13353                }
13354            } finally {
13355                mBackupTarget = null;
13356                mBackupAppName = null;
13357            }
13358        }
13359    }
13360    // =========================================================
13361    // BROADCASTS
13362    // =========================================================
13363
13364    private final List getStickiesLocked(String action, IntentFilter filter,
13365            List cur, int userId) {
13366        final ContentResolver resolver = mContext.getContentResolver();
13367        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13368        if (stickies == null) {
13369            return cur;
13370        }
13371        final ArrayList<Intent> list = stickies.get(action);
13372        if (list == null) {
13373            return cur;
13374        }
13375        int N = list.size();
13376        for (int i=0; i<N; i++) {
13377            Intent intent = list.get(i);
13378            if (filter.match(resolver, intent, true, TAG) >= 0) {
13379                if (cur == null) {
13380                    cur = new ArrayList<Intent>();
13381                }
13382                cur.add(intent);
13383            }
13384        }
13385        return cur;
13386    }
13387
13388    boolean isPendingBroadcastProcessLocked(int pid) {
13389        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13390                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13391    }
13392
13393    void skipPendingBroadcastLocked(int pid) {
13394            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13395            for (BroadcastQueue queue : mBroadcastQueues) {
13396                queue.skipPendingBroadcastLocked(pid);
13397            }
13398    }
13399
13400    // The app just attached; send any pending broadcasts that it should receive
13401    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13402        boolean didSomething = false;
13403        for (BroadcastQueue queue : mBroadcastQueues) {
13404            didSomething |= queue.sendPendingBroadcastsLocked(app);
13405        }
13406        return didSomething;
13407    }
13408
13409    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13410            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13411        enforceNotIsolatedCaller("registerReceiver");
13412        int callingUid;
13413        int callingPid;
13414        synchronized(this) {
13415            ProcessRecord callerApp = null;
13416            if (caller != null) {
13417                callerApp = getRecordForAppLocked(caller);
13418                if (callerApp == null) {
13419                    throw new SecurityException(
13420                            "Unable to find app for caller " + caller
13421                            + " (pid=" + Binder.getCallingPid()
13422                            + ") when registering receiver " + receiver);
13423                }
13424                if (callerApp.info.uid != Process.SYSTEM_UID &&
13425                        !callerApp.pkgList.containsKey(callerPackage) &&
13426                        !"android".equals(callerPackage)) {
13427                    throw new SecurityException("Given caller package " + callerPackage
13428                            + " is not running in process " + callerApp);
13429                }
13430                callingUid = callerApp.info.uid;
13431                callingPid = callerApp.pid;
13432            } else {
13433                callerPackage = null;
13434                callingUid = Binder.getCallingUid();
13435                callingPid = Binder.getCallingPid();
13436            }
13437
13438            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13439                    true, true, "registerReceiver", callerPackage);
13440
13441            List allSticky = null;
13442
13443            // Look for any matching sticky broadcasts...
13444            Iterator actions = filter.actionsIterator();
13445            if (actions != null) {
13446                while (actions.hasNext()) {
13447                    String action = (String)actions.next();
13448                    allSticky = getStickiesLocked(action, filter, allSticky,
13449                            UserHandle.USER_ALL);
13450                    allSticky = getStickiesLocked(action, filter, allSticky,
13451                            UserHandle.getUserId(callingUid));
13452                }
13453            } else {
13454                allSticky = getStickiesLocked(null, filter, allSticky,
13455                        UserHandle.USER_ALL);
13456                allSticky = getStickiesLocked(null, filter, allSticky,
13457                        UserHandle.getUserId(callingUid));
13458            }
13459
13460            // The first sticky in the list is returned directly back to
13461            // the client.
13462            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13463
13464            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13465                    + ": " + sticky);
13466
13467            if (receiver == null) {
13468                return sticky;
13469            }
13470
13471            ReceiverList rl
13472                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13473            if (rl == null) {
13474                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13475                        userId, receiver);
13476                if (rl.app != null) {
13477                    rl.app.receivers.add(rl);
13478                } else {
13479                    try {
13480                        receiver.asBinder().linkToDeath(rl, 0);
13481                    } catch (RemoteException e) {
13482                        return sticky;
13483                    }
13484                    rl.linkedToDeath = true;
13485                }
13486                mRegisteredReceivers.put(receiver.asBinder(), rl);
13487            } else if (rl.uid != callingUid) {
13488                throw new IllegalArgumentException(
13489                        "Receiver requested to register for uid " + callingUid
13490                        + " was previously registered for uid " + rl.uid);
13491            } else if (rl.pid != callingPid) {
13492                throw new IllegalArgumentException(
13493                        "Receiver requested to register for pid " + callingPid
13494                        + " was previously registered for pid " + rl.pid);
13495            } else if (rl.userId != userId) {
13496                throw new IllegalArgumentException(
13497                        "Receiver requested to register for user " + userId
13498                        + " was previously registered for user " + rl.userId);
13499            }
13500            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13501                    permission, callingUid, userId);
13502            rl.add(bf);
13503            if (!bf.debugCheck()) {
13504                Slog.w(TAG, "==> For Dynamic broadast");
13505            }
13506            mReceiverResolver.addFilter(bf);
13507
13508            // Enqueue broadcasts for all existing stickies that match
13509            // this filter.
13510            if (allSticky != null) {
13511                ArrayList receivers = new ArrayList();
13512                receivers.add(bf);
13513
13514                int N = allSticky.size();
13515                for (int i=0; i<N; i++) {
13516                    Intent intent = (Intent)allSticky.get(i);
13517                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13518                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13519                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13520                            null, null, false, true, true, -1);
13521                    queue.enqueueParallelBroadcastLocked(r);
13522                    queue.scheduleBroadcastsLocked();
13523                }
13524            }
13525
13526            return sticky;
13527        }
13528    }
13529
13530    public void unregisterReceiver(IIntentReceiver receiver) {
13531        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13532
13533        final long origId = Binder.clearCallingIdentity();
13534        try {
13535            boolean doTrim = false;
13536
13537            synchronized(this) {
13538                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13539                if (rl != null) {
13540                    if (rl.curBroadcast != null) {
13541                        BroadcastRecord r = rl.curBroadcast;
13542                        final boolean doNext = finishReceiverLocked(
13543                                receiver.asBinder(), r.resultCode, r.resultData,
13544                                r.resultExtras, r.resultAbort);
13545                        if (doNext) {
13546                            doTrim = true;
13547                            r.queue.processNextBroadcast(false);
13548                        }
13549                    }
13550
13551                    if (rl.app != null) {
13552                        rl.app.receivers.remove(rl);
13553                    }
13554                    removeReceiverLocked(rl);
13555                    if (rl.linkedToDeath) {
13556                        rl.linkedToDeath = false;
13557                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13558                    }
13559                }
13560            }
13561
13562            // If we actually concluded any broadcasts, we might now be able
13563            // to trim the recipients' apps from our working set
13564            if (doTrim) {
13565                trimApplications();
13566                return;
13567            }
13568
13569        } finally {
13570            Binder.restoreCallingIdentity(origId);
13571        }
13572    }
13573
13574    void removeReceiverLocked(ReceiverList rl) {
13575        mRegisteredReceivers.remove(rl.receiver.asBinder());
13576        int N = rl.size();
13577        for (int i=0; i<N; i++) {
13578            mReceiverResolver.removeFilter(rl.get(i));
13579        }
13580    }
13581
13582    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13583        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13584            ProcessRecord r = mLruProcesses.get(i);
13585            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13586                try {
13587                    r.thread.dispatchPackageBroadcast(cmd, packages);
13588                } catch (RemoteException ex) {
13589                }
13590            }
13591        }
13592    }
13593
13594    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13595            int[] users) {
13596        List<ResolveInfo> receivers = null;
13597        try {
13598            HashSet<ComponentName> singleUserReceivers = null;
13599            boolean scannedFirstReceivers = false;
13600            for (int user : users) {
13601                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13602                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13603                if (user != 0 && newReceivers != null) {
13604                    // If this is not the primary user, we need to check for
13605                    // any receivers that should be filtered out.
13606                    for (int i=0; i<newReceivers.size(); i++) {
13607                        ResolveInfo ri = newReceivers.get(i);
13608                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13609                            newReceivers.remove(i);
13610                            i--;
13611                        }
13612                    }
13613                }
13614                if (newReceivers != null && newReceivers.size() == 0) {
13615                    newReceivers = null;
13616                }
13617                if (receivers == null) {
13618                    receivers = newReceivers;
13619                } else if (newReceivers != null) {
13620                    // We need to concatenate the additional receivers
13621                    // found with what we have do far.  This would be easy,
13622                    // but we also need to de-dup any receivers that are
13623                    // singleUser.
13624                    if (!scannedFirstReceivers) {
13625                        // Collect any single user receivers we had already retrieved.
13626                        scannedFirstReceivers = true;
13627                        for (int i=0; i<receivers.size(); i++) {
13628                            ResolveInfo ri = receivers.get(i);
13629                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13630                                ComponentName cn = new ComponentName(
13631                                        ri.activityInfo.packageName, ri.activityInfo.name);
13632                                if (singleUserReceivers == null) {
13633                                    singleUserReceivers = new HashSet<ComponentName>();
13634                                }
13635                                singleUserReceivers.add(cn);
13636                            }
13637                        }
13638                    }
13639                    // Add the new results to the existing results, tracking
13640                    // and de-dupping single user receivers.
13641                    for (int i=0; i<newReceivers.size(); i++) {
13642                        ResolveInfo ri = newReceivers.get(i);
13643                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13644                            ComponentName cn = new ComponentName(
13645                                    ri.activityInfo.packageName, ri.activityInfo.name);
13646                            if (singleUserReceivers == null) {
13647                                singleUserReceivers = new HashSet<ComponentName>();
13648                            }
13649                            if (!singleUserReceivers.contains(cn)) {
13650                                singleUserReceivers.add(cn);
13651                                receivers.add(ri);
13652                            }
13653                        } else {
13654                            receivers.add(ri);
13655                        }
13656                    }
13657                }
13658            }
13659        } catch (RemoteException ex) {
13660            // pm is in same process, this will never happen.
13661        }
13662        return receivers;
13663    }
13664
13665    private final int broadcastIntentLocked(ProcessRecord callerApp,
13666            String callerPackage, Intent intent, String resolvedType,
13667            IIntentReceiver resultTo, int resultCode, String resultData,
13668            Bundle map, String requiredPermission, int appOp,
13669            boolean ordered, boolean sticky, int callingPid, int callingUid,
13670            int userId) {
13671        intent = new Intent(intent);
13672
13673        // By default broadcasts do not go to stopped apps.
13674        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13675
13676        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13677            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13678            + " ordered=" + ordered + " userid=" + userId);
13679        if ((resultTo != null) && !ordered) {
13680            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13681        }
13682
13683        userId = handleIncomingUser(callingPid, callingUid, userId,
13684                true, false, "broadcast", callerPackage);
13685
13686        // Make sure that the user who is receiving this broadcast is started.
13687        // If not, we will just skip it.
13688        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13689            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13690                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13691                Slog.w(TAG, "Skipping broadcast of " + intent
13692                        + ": user " + userId + " is stopped");
13693                return ActivityManager.BROADCAST_SUCCESS;
13694            }
13695        }
13696
13697        /*
13698         * Prevent non-system code (defined here to be non-persistent
13699         * processes) from sending protected broadcasts.
13700         */
13701        int callingAppId = UserHandle.getAppId(callingUid);
13702        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13703            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13704            callingUid == 0) {
13705            // Always okay.
13706        } else if (callerApp == null || !callerApp.persistent) {
13707            try {
13708                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13709                        intent.getAction())) {
13710                    String msg = "Permission Denial: not allowed to send broadcast "
13711                            + intent.getAction() + " from pid="
13712                            + callingPid + ", uid=" + callingUid;
13713                    Slog.w(TAG, msg);
13714                    throw new SecurityException(msg);
13715                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13716                    // Special case for compatibility: we don't want apps to send this,
13717                    // but historically it has not been protected and apps may be using it
13718                    // to poke their own app widget.  So, instead of making it protected,
13719                    // just limit it to the caller.
13720                    if (callerApp == null) {
13721                        String msg = "Permission Denial: not allowed to send broadcast "
13722                                + intent.getAction() + " from unknown caller.";
13723                        Slog.w(TAG, msg);
13724                        throw new SecurityException(msg);
13725                    } else if (intent.getComponent() != null) {
13726                        // They are good enough to send to an explicit component...  verify
13727                        // it is being sent to the calling app.
13728                        if (!intent.getComponent().getPackageName().equals(
13729                                callerApp.info.packageName)) {
13730                            String msg = "Permission Denial: not allowed to send broadcast "
13731                                    + intent.getAction() + " to "
13732                                    + intent.getComponent().getPackageName() + " from "
13733                                    + callerApp.info.packageName;
13734                            Slog.w(TAG, msg);
13735                            throw new SecurityException(msg);
13736                        }
13737                    } else {
13738                        // Limit broadcast to their own package.
13739                        intent.setPackage(callerApp.info.packageName);
13740                    }
13741                }
13742            } catch (RemoteException e) {
13743                Slog.w(TAG, "Remote exception", e);
13744                return ActivityManager.BROADCAST_SUCCESS;
13745            }
13746        }
13747
13748        // Handle special intents: if this broadcast is from the package
13749        // manager about a package being removed, we need to remove all of
13750        // its activities from the history stack.
13751        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13752                intent.getAction());
13753        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13754                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13755                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13756                || uidRemoved) {
13757            if (checkComponentPermission(
13758                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13759                    callingPid, callingUid, -1, true)
13760                    == PackageManager.PERMISSION_GRANTED) {
13761                if (uidRemoved) {
13762                    final Bundle intentExtras = intent.getExtras();
13763                    final int uid = intentExtras != null
13764                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13765                    if (uid >= 0) {
13766                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13767                        synchronized (bs) {
13768                            bs.removeUidStatsLocked(uid);
13769                        }
13770                        mAppOpsService.uidRemoved(uid);
13771                    }
13772                } else {
13773                    // If resources are unavailable just force stop all
13774                    // those packages and flush the attribute cache as well.
13775                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13776                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13777                        if (list != null && (list.length > 0)) {
13778                            for (String pkg : list) {
13779                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13780                                        "storage unmount");
13781                            }
13782                            sendPackageBroadcastLocked(
13783                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13784                        }
13785                    } else {
13786                        Uri data = intent.getData();
13787                        String ssp;
13788                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13789                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13790                                    intent.getAction());
13791                            boolean fullUninstall = removed &&
13792                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13793                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13794                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13795                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13796                                        false, fullUninstall, userId,
13797                                        removed ? "pkg removed" : "pkg changed");
13798                            }
13799                            if (removed) {
13800                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13801                                        new String[] {ssp}, userId);
13802                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13803                                    mAppOpsService.packageRemoved(
13804                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13805
13806                                    // Remove all permissions granted from/to this package
13807                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13808                                }
13809                            }
13810                        }
13811                    }
13812                }
13813            } else {
13814                String msg = "Permission Denial: " + intent.getAction()
13815                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13816                        + ", uid=" + callingUid + ")"
13817                        + " requires "
13818                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13819                Slog.w(TAG, msg);
13820                throw new SecurityException(msg);
13821            }
13822
13823        // Special case for adding a package: by default turn on compatibility
13824        // mode.
13825        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13826            Uri data = intent.getData();
13827            String ssp;
13828            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13829                mCompatModePackages.handlePackageAddedLocked(ssp,
13830                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13831            }
13832        }
13833
13834        /*
13835         * If this is the time zone changed action, queue up a message that will reset the timezone
13836         * of all currently running processes. This message will get queued up before the broadcast
13837         * happens.
13838         */
13839        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13840            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13841        }
13842
13843        /*
13844         * If the user set the time, let all running processes know.
13845         */
13846        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
13847            final int is24Hour = intent.getBooleanExtra(
13848                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
13849            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
13850        }
13851
13852        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13853            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13854        }
13855
13856        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13857            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
13858            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13859        }
13860
13861        // Add to the sticky list if requested.
13862        if (sticky) {
13863            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13864                    callingPid, callingUid)
13865                    != PackageManager.PERMISSION_GRANTED) {
13866                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13867                        + callingPid + ", uid=" + callingUid
13868                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13869                Slog.w(TAG, msg);
13870                throw new SecurityException(msg);
13871            }
13872            if (requiredPermission != null) {
13873                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13874                        + " and enforce permission " + requiredPermission);
13875                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13876            }
13877            if (intent.getComponent() != null) {
13878                throw new SecurityException(
13879                        "Sticky broadcasts can't target a specific component");
13880            }
13881            // We use userId directly here, since the "all" target is maintained
13882            // as a separate set of sticky broadcasts.
13883            if (userId != UserHandle.USER_ALL) {
13884                // But first, if this is not a broadcast to all users, then
13885                // make sure it doesn't conflict with an existing broadcast to
13886                // all users.
13887                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13888                        UserHandle.USER_ALL);
13889                if (stickies != null) {
13890                    ArrayList<Intent> list = stickies.get(intent.getAction());
13891                    if (list != null) {
13892                        int N = list.size();
13893                        int i;
13894                        for (i=0; i<N; i++) {
13895                            if (intent.filterEquals(list.get(i))) {
13896                                throw new IllegalArgumentException(
13897                                        "Sticky broadcast " + intent + " for user "
13898                                        + userId + " conflicts with existing global broadcast");
13899                            }
13900                        }
13901                    }
13902                }
13903            }
13904            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13905            if (stickies == null) {
13906                stickies = new ArrayMap<String, ArrayList<Intent>>();
13907                mStickyBroadcasts.put(userId, stickies);
13908            }
13909            ArrayList<Intent> list = stickies.get(intent.getAction());
13910            if (list == null) {
13911                list = new ArrayList<Intent>();
13912                stickies.put(intent.getAction(), list);
13913            }
13914            int N = list.size();
13915            int i;
13916            for (i=0; i<N; i++) {
13917                if (intent.filterEquals(list.get(i))) {
13918                    // This sticky already exists, replace it.
13919                    list.set(i, new Intent(intent));
13920                    break;
13921                }
13922            }
13923            if (i >= N) {
13924                list.add(new Intent(intent));
13925            }
13926        }
13927
13928        int[] users;
13929        if (userId == UserHandle.USER_ALL) {
13930            // Caller wants broadcast to go to all started users.
13931            users = mStartedUserArray;
13932        } else {
13933            // Caller wants broadcast to go to one specific user.
13934            users = new int[] {userId};
13935        }
13936
13937        // Figure out who all will receive this broadcast.
13938        List receivers = null;
13939        List<BroadcastFilter> registeredReceivers = null;
13940        // Need to resolve the intent to interested receivers...
13941        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13942                 == 0) {
13943            receivers = collectReceiverComponents(intent, resolvedType, users);
13944        }
13945        if (intent.getComponent() == null) {
13946            registeredReceivers = mReceiverResolver.queryIntent(intent,
13947                    resolvedType, false, userId);
13948        }
13949
13950        final boolean replacePending =
13951                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13952
13953        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13954                + " replacePending=" + replacePending);
13955
13956        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13957        if (!ordered && NR > 0) {
13958            // If we are not serializing this broadcast, then send the
13959            // registered receivers separately so they don't wait for the
13960            // components to be launched.
13961            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13962            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13963                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13964                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13965                    ordered, sticky, false, userId);
13966            if (DEBUG_BROADCAST) Slog.v(
13967                    TAG, "Enqueueing parallel broadcast " + r);
13968            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13969            if (!replaced) {
13970                queue.enqueueParallelBroadcastLocked(r);
13971                queue.scheduleBroadcastsLocked();
13972            }
13973            registeredReceivers = null;
13974            NR = 0;
13975        }
13976
13977        // Merge into one list.
13978        int ir = 0;
13979        if (receivers != null) {
13980            // A special case for PACKAGE_ADDED: do not allow the package
13981            // being added to see this broadcast.  This prevents them from
13982            // using this as a back door to get run as soon as they are
13983            // installed.  Maybe in the future we want to have a special install
13984            // broadcast or such for apps, but we'd like to deliberately make
13985            // this decision.
13986            String skipPackages[] = null;
13987            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13988                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13989                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13990                Uri data = intent.getData();
13991                if (data != null) {
13992                    String pkgName = data.getSchemeSpecificPart();
13993                    if (pkgName != null) {
13994                        skipPackages = new String[] { pkgName };
13995                    }
13996                }
13997            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13998                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13999            }
14000            if (skipPackages != null && (skipPackages.length > 0)) {
14001                for (String skipPackage : skipPackages) {
14002                    if (skipPackage != null) {
14003                        int NT = receivers.size();
14004                        for (int it=0; it<NT; it++) {
14005                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14006                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14007                                receivers.remove(it);
14008                                it--;
14009                                NT--;
14010                            }
14011                        }
14012                    }
14013                }
14014            }
14015
14016            int NT = receivers != null ? receivers.size() : 0;
14017            int it = 0;
14018            ResolveInfo curt = null;
14019            BroadcastFilter curr = null;
14020            while (it < NT && ir < NR) {
14021                if (curt == null) {
14022                    curt = (ResolveInfo)receivers.get(it);
14023                }
14024                if (curr == null) {
14025                    curr = registeredReceivers.get(ir);
14026                }
14027                if (curr.getPriority() >= curt.priority) {
14028                    // Insert this broadcast record into the final list.
14029                    receivers.add(it, curr);
14030                    ir++;
14031                    curr = null;
14032                    it++;
14033                    NT++;
14034                } else {
14035                    // Skip to the next ResolveInfo in the final list.
14036                    it++;
14037                    curt = null;
14038                }
14039            }
14040        }
14041        while (ir < NR) {
14042            if (receivers == null) {
14043                receivers = new ArrayList();
14044            }
14045            receivers.add(registeredReceivers.get(ir));
14046            ir++;
14047        }
14048
14049        if ((receivers != null && receivers.size() > 0)
14050                || resultTo != null) {
14051            BroadcastQueue queue = broadcastQueueForIntent(intent);
14052            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14053                    callerPackage, callingPid, callingUid, resolvedType,
14054                    requiredPermission, appOp, receivers, resultTo, resultCode,
14055                    resultData, map, ordered, sticky, false, userId);
14056            if (DEBUG_BROADCAST) Slog.v(
14057                    TAG, "Enqueueing ordered broadcast " + r
14058                    + ": prev had " + queue.mOrderedBroadcasts.size());
14059            if (DEBUG_BROADCAST) {
14060                int seq = r.intent.getIntExtra("seq", -1);
14061                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14062            }
14063            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14064            if (!replaced) {
14065                queue.enqueueOrderedBroadcastLocked(r);
14066                queue.scheduleBroadcastsLocked();
14067            }
14068        }
14069
14070        return ActivityManager.BROADCAST_SUCCESS;
14071    }
14072
14073    final Intent verifyBroadcastLocked(Intent intent) {
14074        // Refuse possible leaked file descriptors
14075        if (intent != null && intent.hasFileDescriptors() == true) {
14076            throw new IllegalArgumentException("File descriptors passed in Intent");
14077        }
14078
14079        int flags = intent.getFlags();
14080
14081        if (!mProcessesReady) {
14082            // if the caller really truly claims to know what they're doing, go
14083            // ahead and allow the broadcast without launching any receivers
14084            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14085                intent = new Intent(intent);
14086                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14087            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14088                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14089                        + " before boot completion");
14090                throw new IllegalStateException("Cannot broadcast before boot completed");
14091            }
14092        }
14093
14094        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14095            throw new IllegalArgumentException(
14096                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14097        }
14098
14099        return intent;
14100    }
14101
14102    public final int broadcastIntent(IApplicationThread caller,
14103            Intent intent, String resolvedType, IIntentReceiver resultTo,
14104            int resultCode, String resultData, Bundle map,
14105            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14106        enforceNotIsolatedCaller("broadcastIntent");
14107        synchronized(this) {
14108            intent = verifyBroadcastLocked(intent);
14109
14110            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14111            final int callingPid = Binder.getCallingPid();
14112            final int callingUid = Binder.getCallingUid();
14113            final long origId = Binder.clearCallingIdentity();
14114            int res = broadcastIntentLocked(callerApp,
14115                    callerApp != null ? callerApp.info.packageName : null,
14116                    intent, resolvedType, resultTo,
14117                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14118                    callingPid, callingUid, userId);
14119            Binder.restoreCallingIdentity(origId);
14120            return res;
14121        }
14122    }
14123
14124    int broadcastIntentInPackage(String packageName, int uid,
14125            Intent intent, String resolvedType, IIntentReceiver resultTo,
14126            int resultCode, String resultData, Bundle map,
14127            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14128        synchronized(this) {
14129            intent = verifyBroadcastLocked(intent);
14130
14131            final long origId = Binder.clearCallingIdentity();
14132            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14133                    resultTo, resultCode, resultData, map, requiredPermission,
14134                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14135            Binder.restoreCallingIdentity(origId);
14136            return res;
14137        }
14138    }
14139
14140    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14141        // Refuse possible leaked file descriptors
14142        if (intent != null && intent.hasFileDescriptors() == true) {
14143            throw new IllegalArgumentException("File descriptors passed in Intent");
14144        }
14145
14146        userId = handleIncomingUser(Binder.getCallingPid(),
14147                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
14148
14149        synchronized(this) {
14150            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14151                    != PackageManager.PERMISSION_GRANTED) {
14152                String msg = "Permission Denial: unbroadcastIntent() from pid="
14153                        + Binder.getCallingPid()
14154                        + ", uid=" + Binder.getCallingUid()
14155                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14156                Slog.w(TAG, msg);
14157                throw new SecurityException(msg);
14158            }
14159            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14160            if (stickies != null) {
14161                ArrayList<Intent> list = stickies.get(intent.getAction());
14162                if (list != null) {
14163                    int N = list.size();
14164                    int i;
14165                    for (i=0; i<N; i++) {
14166                        if (intent.filterEquals(list.get(i))) {
14167                            list.remove(i);
14168                            break;
14169                        }
14170                    }
14171                    if (list.size() <= 0) {
14172                        stickies.remove(intent.getAction());
14173                    }
14174                }
14175                if (stickies.size() <= 0) {
14176                    mStickyBroadcasts.remove(userId);
14177                }
14178            }
14179        }
14180    }
14181
14182    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14183            String resultData, Bundle resultExtras, boolean resultAbort) {
14184        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14185        if (r == null) {
14186            Slog.w(TAG, "finishReceiver called but not found on queue");
14187            return false;
14188        }
14189
14190        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14191    }
14192
14193    void backgroundServicesFinishedLocked(int userId) {
14194        for (BroadcastQueue queue : mBroadcastQueues) {
14195            queue.backgroundServicesFinishedLocked(userId);
14196        }
14197    }
14198
14199    public void finishReceiver(IBinder who, int resultCode, String resultData,
14200            Bundle resultExtras, boolean resultAbort) {
14201        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14202
14203        // Refuse possible leaked file descriptors
14204        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14205            throw new IllegalArgumentException("File descriptors passed in Bundle");
14206        }
14207
14208        final long origId = Binder.clearCallingIdentity();
14209        try {
14210            boolean doNext = false;
14211            BroadcastRecord r;
14212
14213            synchronized(this) {
14214                r = broadcastRecordForReceiverLocked(who);
14215                if (r != null) {
14216                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14217                        resultData, resultExtras, resultAbort, true);
14218                }
14219            }
14220
14221            if (doNext) {
14222                r.queue.processNextBroadcast(false);
14223            }
14224            trimApplications();
14225        } finally {
14226            Binder.restoreCallingIdentity(origId);
14227        }
14228    }
14229
14230    // =========================================================
14231    // INSTRUMENTATION
14232    // =========================================================
14233
14234    public boolean startInstrumentation(ComponentName className,
14235            String profileFile, int flags, Bundle arguments,
14236            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14237            int userId) {
14238        enforceNotIsolatedCaller("startInstrumentation");
14239        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14240                userId, false, true, "startInstrumentation", null);
14241        // Refuse possible leaked file descriptors
14242        if (arguments != null && arguments.hasFileDescriptors()) {
14243            throw new IllegalArgumentException("File descriptors passed in Bundle");
14244        }
14245
14246        synchronized(this) {
14247            InstrumentationInfo ii = null;
14248            ApplicationInfo ai = null;
14249            try {
14250                ii = mContext.getPackageManager().getInstrumentationInfo(
14251                    className, STOCK_PM_FLAGS);
14252                ai = AppGlobals.getPackageManager().getApplicationInfo(
14253                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14254            } catch (PackageManager.NameNotFoundException e) {
14255            } catch (RemoteException e) {
14256            }
14257            if (ii == null) {
14258                reportStartInstrumentationFailure(watcher, className,
14259                        "Unable to find instrumentation info for: " + className);
14260                return false;
14261            }
14262            if (ai == null) {
14263                reportStartInstrumentationFailure(watcher, className,
14264                        "Unable to find instrumentation target package: " + ii.targetPackage);
14265                return false;
14266            }
14267
14268            int match = mContext.getPackageManager().checkSignatures(
14269                    ii.targetPackage, ii.packageName);
14270            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14271                String msg = "Permission Denial: starting instrumentation "
14272                        + className + " from pid="
14273                        + Binder.getCallingPid()
14274                        + ", uid=" + Binder.getCallingPid()
14275                        + " not allowed because package " + ii.packageName
14276                        + " does not have a signature matching the target "
14277                        + ii.targetPackage;
14278                reportStartInstrumentationFailure(watcher, className, msg);
14279                throw new SecurityException(msg);
14280            }
14281
14282            final long origId = Binder.clearCallingIdentity();
14283            // Instrumentation can kill and relaunch even persistent processes
14284            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14285                    "start instr");
14286            ProcessRecord app = addAppLocked(ai, false);
14287            app.instrumentationClass = className;
14288            app.instrumentationInfo = ai;
14289            app.instrumentationProfileFile = profileFile;
14290            app.instrumentationArguments = arguments;
14291            app.instrumentationWatcher = watcher;
14292            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14293            app.instrumentationResultClass = className;
14294            Binder.restoreCallingIdentity(origId);
14295        }
14296
14297        return true;
14298    }
14299
14300    /**
14301     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14302     * error to the logs, but if somebody is watching, send the report there too.  This enables
14303     * the "am" command to report errors with more information.
14304     *
14305     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14306     * @param cn The component name of the instrumentation.
14307     * @param report The error report.
14308     */
14309    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14310            ComponentName cn, String report) {
14311        Slog.w(TAG, report);
14312        try {
14313            if (watcher != null) {
14314                Bundle results = new Bundle();
14315                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14316                results.putString("Error", report);
14317                watcher.instrumentationStatus(cn, -1, results);
14318            }
14319        } catch (RemoteException e) {
14320            Slog.w(TAG, e);
14321        }
14322    }
14323
14324    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14325        if (app.instrumentationWatcher != null) {
14326            try {
14327                // NOTE:  IInstrumentationWatcher *must* be oneway here
14328                app.instrumentationWatcher.instrumentationFinished(
14329                    app.instrumentationClass,
14330                    resultCode,
14331                    results);
14332            } catch (RemoteException e) {
14333            }
14334        }
14335        if (app.instrumentationUiAutomationConnection != null) {
14336            try {
14337                app.instrumentationUiAutomationConnection.shutdown();
14338            } catch (RemoteException re) {
14339                /* ignore */
14340            }
14341            // Only a UiAutomation can set this flag and now that
14342            // it is finished we make sure it is reset to its default.
14343            mUserIsMonkey = false;
14344        }
14345        app.instrumentationWatcher = null;
14346        app.instrumentationUiAutomationConnection = null;
14347        app.instrumentationClass = null;
14348        app.instrumentationInfo = null;
14349        app.instrumentationProfileFile = null;
14350        app.instrumentationArguments = null;
14351
14352        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14353                "finished inst");
14354    }
14355
14356    public void finishInstrumentation(IApplicationThread target,
14357            int resultCode, Bundle results) {
14358        int userId = UserHandle.getCallingUserId();
14359        // Refuse possible leaked file descriptors
14360        if (results != null && results.hasFileDescriptors()) {
14361            throw new IllegalArgumentException("File descriptors passed in Intent");
14362        }
14363
14364        synchronized(this) {
14365            ProcessRecord app = getRecordForAppLocked(target);
14366            if (app == null) {
14367                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14368                return;
14369            }
14370            final long origId = Binder.clearCallingIdentity();
14371            finishInstrumentationLocked(app, resultCode, results);
14372            Binder.restoreCallingIdentity(origId);
14373        }
14374    }
14375
14376    // =========================================================
14377    // CONFIGURATION
14378    // =========================================================
14379
14380    public ConfigurationInfo getDeviceConfigurationInfo() {
14381        ConfigurationInfo config = new ConfigurationInfo();
14382        synchronized (this) {
14383            config.reqTouchScreen = mConfiguration.touchscreen;
14384            config.reqKeyboardType = mConfiguration.keyboard;
14385            config.reqNavigation = mConfiguration.navigation;
14386            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14387                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14388                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14389            }
14390            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14391                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14392                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14393            }
14394            config.reqGlEsVersion = GL_ES_VERSION;
14395        }
14396        return config;
14397    }
14398
14399    ActivityStack getFocusedStack() {
14400        return mStackSupervisor.getFocusedStack();
14401    }
14402
14403    public Configuration getConfiguration() {
14404        Configuration ci;
14405        synchronized(this) {
14406            ci = new Configuration(mConfiguration);
14407        }
14408        return ci;
14409    }
14410
14411    public void updatePersistentConfiguration(Configuration values) {
14412        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14413                "updateConfiguration()");
14414        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14415                "updateConfiguration()");
14416        if (values == null) {
14417            throw new NullPointerException("Configuration must not be null");
14418        }
14419
14420        synchronized(this) {
14421            final long origId = Binder.clearCallingIdentity();
14422            updateConfigurationLocked(values, null, true, false);
14423            Binder.restoreCallingIdentity(origId);
14424        }
14425    }
14426
14427    public void updateConfiguration(Configuration values) {
14428        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14429                "updateConfiguration()");
14430
14431        synchronized(this) {
14432            if (values == null && mWindowManager != null) {
14433                // sentinel: fetch the current configuration from the window manager
14434                values = mWindowManager.computeNewConfiguration();
14435            }
14436
14437            if (mWindowManager != null) {
14438                mProcessList.applyDisplaySize(mWindowManager);
14439            }
14440
14441            final long origId = Binder.clearCallingIdentity();
14442            if (values != null) {
14443                Settings.System.clearConfiguration(values);
14444            }
14445            updateConfigurationLocked(values, null, false, false);
14446            Binder.restoreCallingIdentity(origId);
14447        }
14448    }
14449
14450    /**
14451     * Do either or both things: (1) change the current configuration, and (2)
14452     * make sure the given activity is running with the (now) current
14453     * configuration.  Returns true if the activity has been left running, or
14454     * false if <var>starting</var> is being destroyed to match the new
14455     * configuration.
14456     * @param persistent TODO
14457     */
14458    boolean updateConfigurationLocked(Configuration values,
14459            ActivityRecord starting, boolean persistent, boolean initLocale) {
14460        int changes = 0;
14461
14462        if (values != null) {
14463            Configuration newConfig = new Configuration(mConfiguration);
14464            changes = newConfig.updateFrom(values);
14465            if (changes != 0) {
14466                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14467                    Slog.i(TAG, "Updating configuration to: " + values);
14468                }
14469
14470                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14471
14472                if (values.locale != null && !initLocale) {
14473                    saveLocaleLocked(values.locale,
14474                                     !values.locale.equals(mConfiguration.locale),
14475                                     values.userSetLocale);
14476                }
14477
14478                mConfigurationSeq++;
14479                if (mConfigurationSeq <= 0) {
14480                    mConfigurationSeq = 1;
14481                }
14482                newConfig.seq = mConfigurationSeq;
14483                mConfiguration = newConfig;
14484                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14485                mUsageStatsService.noteStartConfig(newConfig);
14486
14487                final Configuration configCopy = new Configuration(mConfiguration);
14488
14489                // TODO: If our config changes, should we auto dismiss any currently
14490                // showing dialogs?
14491                mShowDialogs = shouldShowDialogs(newConfig);
14492
14493                AttributeCache ac = AttributeCache.instance();
14494                if (ac != null) {
14495                    ac.updateConfiguration(configCopy);
14496                }
14497
14498                // Make sure all resources in our process are updated
14499                // right now, so that anyone who is going to retrieve
14500                // resource values after we return will be sure to get
14501                // the new ones.  This is especially important during
14502                // boot, where the first config change needs to guarantee
14503                // all resources have that config before following boot
14504                // code is executed.
14505                mSystemThread.applyConfigurationToResources(configCopy);
14506
14507                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14508                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14509                    msg.obj = new Configuration(configCopy);
14510                    mHandler.sendMessage(msg);
14511                }
14512
14513                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14514                    ProcessRecord app = mLruProcesses.get(i);
14515                    try {
14516                        if (app.thread != null) {
14517                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14518                                    + app.processName + " new config " + mConfiguration);
14519                            app.thread.scheduleConfigurationChanged(configCopy);
14520                        }
14521                    } catch (Exception e) {
14522                    }
14523                }
14524                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14525                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14526                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14527                        | Intent.FLAG_RECEIVER_FOREGROUND);
14528                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14529                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14530                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14531                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14532                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14533                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14534                    broadcastIntentLocked(null, null, intent,
14535                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14536                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14537                }
14538            }
14539        }
14540
14541        boolean kept = true;
14542        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14543        // mainStack is null during startup.
14544        if (mainStack != null) {
14545            if (changes != 0 && starting == null) {
14546                // If the configuration changed, and the caller is not already
14547                // in the process of starting an activity, then find the top
14548                // activity to check if its configuration needs to change.
14549                starting = mainStack.topRunningActivityLocked(null);
14550            }
14551
14552            if (starting != null) {
14553                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14554                // And we need to make sure at this point that all other activities
14555                // are made visible with the correct configuration.
14556                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14557            }
14558        }
14559
14560        if (values != null && mWindowManager != null) {
14561            mWindowManager.setNewConfiguration(mConfiguration);
14562        }
14563
14564        return kept;
14565    }
14566
14567    /**
14568     * Decide based on the configuration whether we should shouw the ANR,
14569     * crash, etc dialogs.  The idea is that if there is no affordnace to
14570     * press the on-screen buttons, we shouldn't show the dialog.
14571     *
14572     * A thought: SystemUI might also want to get told about this, the Power
14573     * dialog / global actions also might want different behaviors.
14574     */
14575    private static final boolean shouldShowDialogs(Configuration config) {
14576        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14577                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14578    }
14579
14580    /**
14581     * Save the locale.  You must be inside a synchronized (this) block.
14582     */
14583    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14584        if(isDiff) {
14585            SystemProperties.set("user.language", l.getLanguage());
14586            SystemProperties.set("user.region", l.getCountry());
14587        }
14588
14589        if(isPersist) {
14590            SystemProperties.set("persist.sys.language", l.getLanguage());
14591            SystemProperties.set("persist.sys.country", l.getCountry());
14592            SystemProperties.set("persist.sys.localevar", l.getVariant());
14593        }
14594    }
14595
14596    @Override
14597    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14598        ActivityRecord srec = ActivityRecord.forToken(token);
14599        return srec != null && srec.task.affinity != null &&
14600                srec.task.affinity.equals(destAffinity);
14601    }
14602
14603    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14604            Intent resultData) {
14605
14606        synchronized (this) {
14607            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14608            if (stack != null) {
14609                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14610            }
14611            return false;
14612        }
14613    }
14614
14615    public int getLaunchedFromUid(IBinder activityToken) {
14616        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14617        if (srec == null) {
14618            return -1;
14619        }
14620        return srec.launchedFromUid;
14621    }
14622
14623    public String getLaunchedFromPackage(IBinder activityToken) {
14624        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14625        if (srec == null) {
14626            return null;
14627        }
14628        return srec.launchedFromPackage;
14629    }
14630
14631    // =========================================================
14632    // LIFETIME MANAGEMENT
14633    // =========================================================
14634
14635    // Returns which broadcast queue the app is the current [or imminent] receiver
14636    // on, or 'null' if the app is not an active broadcast recipient.
14637    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14638        BroadcastRecord r = app.curReceiver;
14639        if (r != null) {
14640            return r.queue;
14641        }
14642
14643        // It's not the current receiver, but it might be starting up to become one
14644        synchronized (this) {
14645            for (BroadcastQueue queue : mBroadcastQueues) {
14646                r = queue.mPendingBroadcast;
14647                if (r != null && r.curApp == app) {
14648                    // found it; report which queue it's in
14649                    return queue;
14650                }
14651            }
14652        }
14653
14654        return null;
14655    }
14656
14657    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14658            boolean doingAll, long now) {
14659        if (mAdjSeq == app.adjSeq) {
14660            // This adjustment has already been computed.
14661            return app.curRawAdj;
14662        }
14663
14664        if (app.thread == null) {
14665            app.adjSeq = mAdjSeq;
14666            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14667            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14668            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14669        }
14670
14671        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14672        app.adjSource = null;
14673        app.adjTarget = null;
14674        app.empty = false;
14675        app.cached = false;
14676
14677        final int activitiesSize = app.activities.size();
14678
14679        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14680            // The max adjustment doesn't allow this app to be anything
14681            // below foreground, so it is not worth doing work for it.
14682            app.adjType = "fixed";
14683            app.adjSeq = mAdjSeq;
14684            app.curRawAdj = app.maxAdj;
14685            app.foregroundActivities = false;
14686            app.keeping = true;
14687            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14688            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14689            // System processes can do UI, and when they do we want to have
14690            // them trim their memory after the user leaves the UI.  To
14691            // facilitate this, here we need to determine whether or not it
14692            // is currently showing UI.
14693            app.systemNoUi = true;
14694            if (app == TOP_APP) {
14695                app.systemNoUi = false;
14696            } else if (activitiesSize > 0) {
14697                for (int j = 0; j < activitiesSize; j++) {
14698                    final ActivityRecord r = app.activities.get(j);
14699                    if (r.visible) {
14700                        app.systemNoUi = false;
14701                    }
14702                }
14703            }
14704            if (!app.systemNoUi) {
14705                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14706            }
14707            return (app.curAdj=app.maxAdj);
14708        }
14709
14710        app.keeping = false;
14711        app.systemNoUi = false;
14712
14713        // Determine the importance of the process, starting with most
14714        // important to least, and assign an appropriate OOM adjustment.
14715        int adj;
14716        int schedGroup;
14717        int procState;
14718        boolean foregroundActivities = false;
14719        boolean interesting = false;
14720        BroadcastQueue queue;
14721        if (app == TOP_APP) {
14722            // The last app on the list is the foreground app.
14723            adj = ProcessList.FOREGROUND_APP_ADJ;
14724            schedGroup = Process.THREAD_GROUP_DEFAULT;
14725            app.adjType = "top-activity";
14726            foregroundActivities = true;
14727            interesting = true;
14728            procState = ActivityManager.PROCESS_STATE_TOP;
14729        } else if (app.instrumentationClass != null) {
14730            // Don't want to kill running instrumentation.
14731            adj = ProcessList.FOREGROUND_APP_ADJ;
14732            schedGroup = Process.THREAD_GROUP_DEFAULT;
14733            app.adjType = "instrumentation";
14734            interesting = true;
14735            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14736        } else if ((queue = isReceivingBroadcast(app)) != null) {
14737            // An app that is currently receiving a broadcast also
14738            // counts as being in the foreground for OOM killer purposes.
14739            // It's placed in a sched group based on the nature of the
14740            // broadcast as reflected by which queue it's active in.
14741            adj = ProcessList.FOREGROUND_APP_ADJ;
14742            schedGroup = (queue == mFgBroadcastQueue)
14743                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14744            app.adjType = "broadcast";
14745            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14746        } else if (app.executingServices.size() > 0) {
14747            // An app that is currently executing a service callback also
14748            // counts as being in the foreground.
14749            adj = ProcessList.FOREGROUND_APP_ADJ;
14750            schedGroup = app.execServicesFg ?
14751                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14752            app.adjType = "exec-service";
14753            procState = ActivityManager.PROCESS_STATE_SERVICE;
14754            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14755        } else {
14756            // As far as we know the process is empty.  We may change our mind later.
14757            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14758            // At this point we don't actually know the adjustment.  Use the cached adj
14759            // value that the caller wants us to.
14760            adj = cachedAdj;
14761            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14762            app.cached = true;
14763            app.empty = true;
14764            app.adjType = "cch-empty";
14765        }
14766
14767        // Examine all activities if not already foreground.
14768        if (!foregroundActivities && activitiesSize > 0) {
14769            for (int j = 0; j < activitiesSize; j++) {
14770                final ActivityRecord r = app.activities.get(j);
14771                if (r.app != app) {
14772                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14773                            + app + "?!?");
14774                    continue;
14775                }
14776                if (r.visible) {
14777                    // App has a visible activity; only upgrade adjustment.
14778                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14779                        adj = ProcessList.VISIBLE_APP_ADJ;
14780                        app.adjType = "visible";
14781                    }
14782                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14783                        procState = ActivityManager.PROCESS_STATE_TOP;
14784                    }
14785                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14786                    app.cached = false;
14787                    app.empty = false;
14788                    foregroundActivities = true;
14789                    break;
14790                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14791                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14792                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14793                        app.adjType = "pausing";
14794                    }
14795                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14796                        procState = ActivityManager.PROCESS_STATE_TOP;
14797                    }
14798                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14799                    app.cached = false;
14800                    app.empty = false;
14801                    foregroundActivities = true;
14802                } else if (r.state == ActivityState.STOPPING) {
14803                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14804                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14805                        app.adjType = "stopping";
14806                    }
14807                    // For the process state, we will at this point consider the
14808                    // process to be cached.  It will be cached either as an activity
14809                    // or empty depending on whether the activity is finishing.  We do
14810                    // this so that we can treat the process as cached for purposes of
14811                    // memory trimming (determing current memory level, trim command to
14812                    // send to process) since there can be an arbitrary number of stopping
14813                    // processes and they should soon all go into the cached state.
14814                    if (!r.finishing) {
14815                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14816                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14817                        }
14818                    }
14819                    app.cached = false;
14820                    app.empty = false;
14821                    foregroundActivities = true;
14822                } else {
14823                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14824                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14825                        app.adjType = "cch-act";
14826                    }
14827                }
14828            }
14829        }
14830
14831        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14832            if (app.foregroundServices) {
14833                // The user is aware of this app, so make it visible.
14834                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14835                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14836                app.cached = false;
14837                app.adjType = "fg-service";
14838                schedGroup = Process.THREAD_GROUP_DEFAULT;
14839            } else if (app.forcingToForeground != null) {
14840                // The user is aware of this app, so make it visible.
14841                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14842                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14843                app.cached = false;
14844                app.adjType = "force-fg";
14845                app.adjSource = app.forcingToForeground;
14846                schedGroup = Process.THREAD_GROUP_DEFAULT;
14847            }
14848        }
14849
14850        if (app.foregroundServices) {
14851            interesting = true;
14852        }
14853
14854        if (app == mHeavyWeightProcess) {
14855            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14856                // We don't want to kill the current heavy-weight process.
14857                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14858                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14859                app.cached = false;
14860                app.adjType = "heavy";
14861            }
14862            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14863                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14864            }
14865        }
14866
14867        if (app == mHomeProcess) {
14868            if (adj > ProcessList.HOME_APP_ADJ) {
14869                // This process is hosting what we currently consider to be the
14870                // home app, so we don't want to let it go into the background.
14871                adj = ProcessList.HOME_APP_ADJ;
14872                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14873                app.cached = false;
14874                app.adjType = "home";
14875            }
14876            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14877                procState = ActivityManager.PROCESS_STATE_HOME;
14878            }
14879        }
14880
14881        if (app == mPreviousProcess && app.activities.size() > 0) {
14882            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14883                // This was the previous process that showed UI to the user.
14884                // We want to try to keep it around more aggressively, to give
14885                // a good experience around switching between two apps.
14886                adj = ProcessList.PREVIOUS_APP_ADJ;
14887                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14888                app.cached = false;
14889                app.adjType = "previous";
14890            }
14891            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14892                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14893            }
14894        }
14895
14896        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14897                + " reason=" + app.adjType);
14898
14899        // By default, we use the computed adjustment.  It may be changed if
14900        // there are applications dependent on our services or providers, but
14901        // this gives us a baseline and makes sure we don't get into an
14902        // infinite recursion.
14903        app.adjSeq = mAdjSeq;
14904        app.curRawAdj = adj;
14905        app.hasStartedServices = false;
14906
14907        if (mBackupTarget != null && app == mBackupTarget.app) {
14908            // If possible we want to avoid killing apps while they're being backed up
14909            if (adj > ProcessList.BACKUP_APP_ADJ) {
14910                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14911                adj = ProcessList.BACKUP_APP_ADJ;
14912                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14913                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14914                }
14915                app.adjType = "backup";
14916                app.cached = false;
14917            }
14918            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14919                procState = ActivityManager.PROCESS_STATE_BACKUP;
14920            }
14921        }
14922
14923        boolean mayBeTop = false;
14924
14925        for (int is = app.services.size()-1;
14926                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14927                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14928                        || procState > ActivityManager.PROCESS_STATE_TOP);
14929                is--) {
14930            ServiceRecord s = app.services.valueAt(is);
14931            if (s.startRequested) {
14932                app.hasStartedServices = true;
14933                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14934                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14935                }
14936                if (app.hasShownUi && app != mHomeProcess) {
14937                    // If this process has shown some UI, let it immediately
14938                    // go to the LRU list because it may be pretty heavy with
14939                    // UI stuff.  We'll tag it with a label just to help
14940                    // debug and understand what is going on.
14941                    if (adj > ProcessList.SERVICE_ADJ) {
14942                        app.adjType = "cch-started-ui-services";
14943                    }
14944                } else {
14945                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14946                        // This service has seen some activity within
14947                        // recent memory, so we will keep its process ahead
14948                        // of the background processes.
14949                        if (adj > ProcessList.SERVICE_ADJ) {
14950                            adj = ProcessList.SERVICE_ADJ;
14951                            app.adjType = "started-services";
14952                            app.cached = false;
14953                        }
14954                    }
14955                    // If we have let the service slide into the background
14956                    // state, still have some text describing what it is doing
14957                    // even though the service no longer has an impact.
14958                    if (adj > ProcessList.SERVICE_ADJ) {
14959                        app.adjType = "cch-started-services";
14960                    }
14961                }
14962                // Don't kill this process because it is doing work; it
14963                // has said it is doing work.
14964                app.keeping = true;
14965            }
14966            for (int conni = s.connections.size()-1;
14967                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14968                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14969                            || procState > ActivityManager.PROCESS_STATE_TOP);
14970                    conni--) {
14971                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14972                for (int i = 0;
14973                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14974                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14975                                || procState > ActivityManager.PROCESS_STATE_TOP);
14976                        i++) {
14977                    // XXX should compute this based on the max of
14978                    // all connected clients.
14979                    ConnectionRecord cr = clist.get(i);
14980                    if (cr.binding.client == app) {
14981                        // Binding to ourself is not interesting.
14982                        continue;
14983                    }
14984                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14985                        ProcessRecord client = cr.binding.client;
14986                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14987                                TOP_APP, doingAll, now);
14988                        int clientProcState = client.curProcState;
14989                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14990                            // If the other app is cached for any reason, for purposes here
14991                            // we are going to consider it empty.  The specific cached state
14992                            // doesn't propagate except under certain conditions.
14993                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14994                        }
14995                        String adjType = null;
14996                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14997                            // Not doing bind OOM management, so treat
14998                            // this guy more like a started service.
14999                            if (app.hasShownUi && app != mHomeProcess) {
15000                                // If this process has shown some UI, let it immediately
15001                                // go to the LRU list because it may be pretty heavy with
15002                                // UI stuff.  We'll tag it with a label just to help
15003                                // debug and understand what is going on.
15004                                if (adj > clientAdj) {
15005                                    adjType = "cch-bound-ui-services";
15006                                }
15007                                app.cached = false;
15008                                clientAdj = adj;
15009                                clientProcState = procState;
15010                            } else {
15011                                if (now >= (s.lastActivity
15012                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15013                                    // This service has not seen activity within
15014                                    // recent memory, so allow it to drop to the
15015                                    // LRU list if there is no other reason to keep
15016                                    // it around.  We'll also tag it with a label just
15017                                    // to help debug and undertand what is going on.
15018                                    if (adj > clientAdj) {
15019                                        adjType = "cch-bound-services";
15020                                    }
15021                                    clientAdj = adj;
15022                                }
15023                            }
15024                        }
15025                        if (adj > clientAdj) {
15026                            // If this process has recently shown UI, and
15027                            // the process that is binding to it is less
15028                            // important than being visible, then we don't
15029                            // care about the binding as much as we care
15030                            // about letting this process get into the LRU
15031                            // list to be killed and restarted if needed for
15032                            // memory.
15033                            if (app.hasShownUi && app != mHomeProcess
15034                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15035                                adjType = "cch-bound-ui-services";
15036                            } else {
15037                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15038                                        |Context.BIND_IMPORTANT)) != 0) {
15039                                    adj = clientAdj;
15040                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15041                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15042                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15043                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15044                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15045                                    adj = clientAdj;
15046                                } else {
15047                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15048                                        adj = ProcessList.VISIBLE_APP_ADJ;
15049                                    }
15050                                }
15051                                if (!client.cached) {
15052                                    app.cached = false;
15053                                }
15054                                if (client.keeping) {
15055                                    app.keeping = true;
15056                                }
15057                                adjType = "service";
15058                            }
15059                        }
15060                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15061                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15062                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15063                            }
15064                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15065                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15066                                    // Special handling of clients who are in the top state.
15067                                    // We *may* want to consider this process to be in the
15068                                    // top state as well, but only if there is not another
15069                                    // reason for it to be running.  Being on the top is a
15070                                    // special state, meaning you are specifically running
15071                                    // for the current top app.  If the process is already
15072                                    // running in the background for some other reason, it
15073                                    // is more important to continue considering it to be
15074                                    // in the background state.
15075                                    mayBeTop = true;
15076                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15077                                } else {
15078                                    // Special handling for above-top states (persistent
15079                                    // processes).  These should not bring the current process
15080                                    // into the top state, since they are not on top.  Instead
15081                                    // give them the best state after that.
15082                                    clientProcState =
15083                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15084                                }
15085                            }
15086                        } else {
15087                            if (clientProcState <
15088                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15089                                clientProcState =
15090                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15091                            }
15092                        }
15093                        if (procState > clientProcState) {
15094                            procState = clientProcState;
15095                        }
15096                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15097                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15098                            app.pendingUiClean = true;
15099                        }
15100                        if (adjType != null) {
15101                            app.adjType = adjType;
15102                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15103                                    .REASON_SERVICE_IN_USE;
15104                            app.adjSource = cr.binding.client;
15105                            app.adjSourceOom = clientAdj;
15106                            app.adjTarget = s.name;
15107                        }
15108                    }
15109                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15110                        app.treatLikeActivity = true;
15111                    }
15112                    final ActivityRecord a = cr.activity;
15113                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15114                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15115                                (a.visible || a.state == ActivityState.RESUMED
15116                                 || a.state == ActivityState.PAUSING)) {
15117                            adj = ProcessList.FOREGROUND_APP_ADJ;
15118                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15119                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15120                            }
15121                            app.cached = false;
15122                            app.adjType = "service";
15123                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15124                                    .REASON_SERVICE_IN_USE;
15125                            app.adjSource = a;
15126                            app.adjSourceOom = adj;
15127                            app.adjTarget = s.name;
15128                        }
15129                    }
15130                }
15131            }
15132        }
15133
15134        for (int provi = app.pubProviders.size()-1;
15135                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15136                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15137                        || procState > ActivityManager.PROCESS_STATE_TOP);
15138                provi--) {
15139            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15140            for (int i = cpr.connections.size()-1;
15141                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15142                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15143                            || procState > ActivityManager.PROCESS_STATE_TOP);
15144                    i--) {
15145                ContentProviderConnection conn = cpr.connections.get(i);
15146                ProcessRecord client = conn.client;
15147                if (client == app) {
15148                    // Being our own client is not interesting.
15149                    continue;
15150                }
15151                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15152                int clientProcState = client.curProcState;
15153                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15154                    // If the other app is cached for any reason, for purposes here
15155                    // we are going to consider it empty.
15156                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15157                }
15158                if (adj > clientAdj) {
15159                    if (app.hasShownUi && app != mHomeProcess
15160                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15161                        app.adjType = "cch-ui-provider";
15162                    } else {
15163                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15164                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15165                        app.adjType = "provider";
15166                    }
15167                    app.cached &= client.cached;
15168                    app.keeping |= client.keeping;
15169                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15170                            .REASON_PROVIDER_IN_USE;
15171                    app.adjSource = client;
15172                    app.adjSourceOom = clientAdj;
15173                    app.adjTarget = cpr.name;
15174                }
15175                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15176                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15177                        // Special handling of clients who are in the top state.
15178                        // We *may* want to consider this process to be in the
15179                        // top state as well, but only if there is not another
15180                        // reason for it to be running.  Being on the top is a
15181                        // special state, meaning you are specifically running
15182                        // for the current top app.  If the process is already
15183                        // running in the background for some other reason, it
15184                        // is more important to continue considering it to be
15185                        // in the background state.
15186                        mayBeTop = true;
15187                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15188                    } else {
15189                        // Special handling for above-top states (persistent
15190                        // processes).  These should not bring the current process
15191                        // into the top state, since they are not on top.  Instead
15192                        // give them the best state after that.
15193                        clientProcState =
15194                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15195                    }
15196                }
15197                if (procState > clientProcState) {
15198                    procState = clientProcState;
15199                }
15200                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15201                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15202                }
15203            }
15204            // If the provider has external (non-framework) process
15205            // dependencies, ensure that its adjustment is at least
15206            // FOREGROUND_APP_ADJ.
15207            if (cpr.hasExternalProcessHandles()) {
15208                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15209                    adj = ProcessList.FOREGROUND_APP_ADJ;
15210                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15211                    app.cached = false;
15212                    app.keeping = true;
15213                    app.adjType = "provider";
15214                    app.adjTarget = cpr.name;
15215                }
15216                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15217                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15218                }
15219            }
15220        }
15221
15222        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15223            // A client of one of our services or providers is in the top state.  We
15224            // *may* want to be in the top state, but not if we are already running in
15225            // the background for some other reason.  For the decision here, we are going
15226            // to pick out a few specific states that we want to remain in when a client
15227            // is top (states that tend to be longer-term) and otherwise allow it to go
15228            // to the top state.
15229            switch (procState) {
15230                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15231                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15232                case ActivityManager.PROCESS_STATE_SERVICE:
15233                    // These all are longer-term states, so pull them up to the top
15234                    // of the background states, but not all the way to the top state.
15235                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15236                    break;
15237                default:
15238                    // Otherwise, top is a better choice, so take it.
15239                    procState = ActivityManager.PROCESS_STATE_TOP;
15240                    break;
15241            }
15242        }
15243
15244        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15245            if (app.hasClientActivities) {
15246                // This is a cached process, but with client activities.  Mark it so.
15247                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15248                app.adjType = "cch-client-act";
15249            } else if (app.treatLikeActivity) {
15250                // This is a cached process, but somebody wants us to treat it like it has
15251                // an activity, okay!
15252                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15253                app.adjType = "cch-as-act";
15254            }
15255        }
15256
15257        if (adj == ProcessList.SERVICE_ADJ) {
15258            if (doingAll) {
15259                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15260                mNewNumServiceProcs++;
15261                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15262                if (!app.serviceb) {
15263                    // This service isn't far enough down on the LRU list to
15264                    // normally be a B service, but if we are low on RAM and it
15265                    // is large we want to force it down since we would prefer to
15266                    // keep launcher over it.
15267                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15268                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15269                        app.serviceHighRam = true;
15270                        app.serviceb = true;
15271                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15272                    } else {
15273                        mNewNumAServiceProcs++;
15274                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15275                    }
15276                } else {
15277                    app.serviceHighRam = false;
15278                }
15279            }
15280            if (app.serviceb) {
15281                adj = ProcessList.SERVICE_B_ADJ;
15282            }
15283        }
15284
15285        app.curRawAdj = adj;
15286
15287        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15288        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15289        if (adj > app.maxAdj) {
15290            adj = app.maxAdj;
15291            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15292                schedGroup = Process.THREAD_GROUP_DEFAULT;
15293            }
15294        }
15295        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15296            app.keeping = true;
15297        }
15298
15299        // Do final modification to adj.  Everything we do between here and applying
15300        // the final setAdj must be done in this function, because we will also use
15301        // it when computing the final cached adj later.  Note that we don't need to
15302        // worry about this for max adj above, since max adj will always be used to
15303        // keep it out of the cached vaues.
15304        app.curAdj = app.modifyRawOomAdj(adj);
15305        app.curSchedGroup = schedGroup;
15306        app.curProcState = procState;
15307        app.foregroundActivities = foregroundActivities;
15308
15309        return app.curRawAdj;
15310    }
15311
15312    /**
15313     * Schedule PSS collection of a process.
15314     */
15315    void requestPssLocked(ProcessRecord proc, int procState) {
15316        if (mPendingPssProcesses.contains(proc)) {
15317            return;
15318        }
15319        if (mPendingPssProcesses.size() == 0) {
15320            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15321        }
15322        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15323        proc.pssProcState = procState;
15324        mPendingPssProcesses.add(proc);
15325    }
15326
15327    /**
15328     * Schedule PSS collection of all processes.
15329     */
15330    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15331        if (!always) {
15332            if (now < (mLastFullPssTime +
15333                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15334                return;
15335            }
15336        }
15337        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15338        mLastFullPssTime = now;
15339        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15340        mPendingPssProcesses.clear();
15341        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15342            ProcessRecord app = mLruProcesses.get(i);
15343            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15344                app.pssProcState = app.setProcState;
15345                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15346                        isSleeping(), now);
15347                mPendingPssProcesses.add(app);
15348            }
15349        }
15350        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15351    }
15352
15353    /**
15354     * Ask a given process to GC right now.
15355     */
15356    final void performAppGcLocked(ProcessRecord app) {
15357        try {
15358            app.lastRequestedGc = SystemClock.uptimeMillis();
15359            if (app.thread != null) {
15360                if (app.reportLowMemory) {
15361                    app.reportLowMemory = false;
15362                    app.thread.scheduleLowMemory();
15363                } else {
15364                    app.thread.processInBackground();
15365                }
15366            }
15367        } catch (Exception e) {
15368            // whatever.
15369        }
15370    }
15371
15372    /**
15373     * Returns true if things are idle enough to perform GCs.
15374     */
15375    private final boolean canGcNowLocked() {
15376        boolean processingBroadcasts = false;
15377        for (BroadcastQueue q : mBroadcastQueues) {
15378            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15379                processingBroadcasts = true;
15380            }
15381        }
15382        return !processingBroadcasts
15383                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15384    }
15385
15386    /**
15387     * Perform GCs on all processes that are waiting for it, but only
15388     * if things are idle.
15389     */
15390    final void performAppGcsLocked() {
15391        final int N = mProcessesToGc.size();
15392        if (N <= 0) {
15393            return;
15394        }
15395        if (canGcNowLocked()) {
15396            while (mProcessesToGc.size() > 0) {
15397                ProcessRecord proc = mProcessesToGc.remove(0);
15398                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15399                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15400                            <= SystemClock.uptimeMillis()) {
15401                        // To avoid spamming the system, we will GC processes one
15402                        // at a time, waiting a few seconds between each.
15403                        performAppGcLocked(proc);
15404                        scheduleAppGcsLocked();
15405                        return;
15406                    } else {
15407                        // It hasn't been long enough since we last GCed this
15408                        // process...  put it in the list to wait for its time.
15409                        addProcessToGcListLocked(proc);
15410                        break;
15411                    }
15412                }
15413            }
15414
15415            scheduleAppGcsLocked();
15416        }
15417    }
15418
15419    /**
15420     * If all looks good, perform GCs on all processes waiting for them.
15421     */
15422    final void performAppGcsIfAppropriateLocked() {
15423        if (canGcNowLocked()) {
15424            performAppGcsLocked();
15425            return;
15426        }
15427        // Still not idle, wait some more.
15428        scheduleAppGcsLocked();
15429    }
15430
15431    /**
15432     * Schedule the execution of all pending app GCs.
15433     */
15434    final void scheduleAppGcsLocked() {
15435        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15436
15437        if (mProcessesToGc.size() > 0) {
15438            // Schedule a GC for the time to the next process.
15439            ProcessRecord proc = mProcessesToGc.get(0);
15440            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15441
15442            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15443            long now = SystemClock.uptimeMillis();
15444            if (when < (now+GC_TIMEOUT)) {
15445                when = now + GC_TIMEOUT;
15446            }
15447            mHandler.sendMessageAtTime(msg, when);
15448        }
15449    }
15450
15451    /**
15452     * Add a process to the array of processes waiting to be GCed.  Keeps the
15453     * list in sorted order by the last GC time.  The process can't already be
15454     * on the list.
15455     */
15456    final void addProcessToGcListLocked(ProcessRecord proc) {
15457        boolean added = false;
15458        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15459            if (mProcessesToGc.get(i).lastRequestedGc <
15460                    proc.lastRequestedGc) {
15461                added = true;
15462                mProcessesToGc.add(i+1, proc);
15463                break;
15464            }
15465        }
15466        if (!added) {
15467            mProcessesToGc.add(0, proc);
15468        }
15469    }
15470
15471    /**
15472     * Set up to ask a process to GC itself.  This will either do it
15473     * immediately, or put it on the list of processes to gc the next
15474     * time things are idle.
15475     */
15476    final void scheduleAppGcLocked(ProcessRecord app) {
15477        long now = SystemClock.uptimeMillis();
15478        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15479            return;
15480        }
15481        if (!mProcessesToGc.contains(app)) {
15482            addProcessToGcListLocked(app);
15483            scheduleAppGcsLocked();
15484        }
15485    }
15486
15487    final void checkExcessivePowerUsageLocked(boolean doKills) {
15488        updateCpuStatsNow();
15489
15490        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15491        boolean doWakeKills = doKills;
15492        boolean doCpuKills = doKills;
15493        if (mLastPowerCheckRealtime == 0) {
15494            doWakeKills = false;
15495        }
15496        if (mLastPowerCheckUptime == 0) {
15497            doCpuKills = false;
15498        }
15499        if (stats.isScreenOn()) {
15500            doWakeKills = false;
15501        }
15502        final long curRealtime = SystemClock.elapsedRealtime();
15503        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15504        final long curUptime = SystemClock.uptimeMillis();
15505        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15506        mLastPowerCheckRealtime = curRealtime;
15507        mLastPowerCheckUptime = curUptime;
15508        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15509            doWakeKills = false;
15510        }
15511        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15512            doCpuKills = false;
15513        }
15514        int i = mLruProcesses.size();
15515        while (i > 0) {
15516            i--;
15517            ProcessRecord app = mLruProcesses.get(i);
15518            if (!app.keeping) {
15519                long wtime;
15520                synchronized (stats) {
15521                    wtime = stats.getProcessWakeTime(app.info.uid,
15522                            app.pid, curRealtime);
15523                }
15524                long wtimeUsed = wtime - app.lastWakeTime;
15525                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15526                if (DEBUG_POWER) {
15527                    StringBuilder sb = new StringBuilder(128);
15528                    sb.append("Wake for ");
15529                    app.toShortString(sb);
15530                    sb.append(": over ");
15531                    TimeUtils.formatDuration(realtimeSince, sb);
15532                    sb.append(" used ");
15533                    TimeUtils.formatDuration(wtimeUsed, sb);
15534                    sb.append(" (");
15535                    sb.append((wtimeUsed*100)/realtimeSince);
15536                    sb.append("%)");
15537                    Slog.i(TAG, sb.toString());
15538                    sb.setLength(0);
15539                    sb.append("CPU for ");
15540                    app.toShortString(sb);
15541                    sb.append(": over ");
15542                    TimeUtils.formatDuration(uptimeSince, sb);
15543                    sb.append(" used ");
15544                    TimeUtils.formatDuration(cputimeUsed, sb);
15545                    sb.append(" (");
15546                    sb.append((cputimeUsed*100)/uptimeSince);
15547                    sb.append("%)");
15548                    Slog.i(TAG, sb.toString());
15549                }
15550                // If a process has held a wake lock for more
15551                // than 50% of the time during this period,
15552                // that sounds bad.  Kill!
15553                if (doWakeKills && realtimeSince > 0
15554                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15555                    synchronized (stats) {
15556                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15557                                realtimeSince, wtimeUsed);
15558                    }
15559                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15560                            + " during " + realtimeSince);
15561                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15562                } else if (doCpuKills && uptimeSince > 0
15563                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15564                    synchronized (stats) {
15565                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15566                                uptimeSince, cputimeUsed);
15567                    }
15568                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15569                            + " during " + uptimeSince);
15570                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15571                } else {
15572                    app.lastWakeTime = wtime;
15573                    app.lastCpuTime = app.curCpuTime;
15574                }
15575            }
15576        }
15577    }
15578
15579    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15580            ProcessRecord TOP_APP, boolean doingAll, long now) {
15581        boolean success = true;
15582
15583        if (app.curRawAdj != app.setRawAdj) {
15584            if (wasKeeping && !app.keeping) {
15585                // This app is no longer something we want to keep.  Note
15586                // its current wake lock time to later know to kill it if
15587                // it is not behaving well.
15588                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15589                synchronized (stats) {
15590                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15591                            app.pid, SystemClock.elapsedRealtime());
15592                }
15593                app.lastCpuTime = app.curCpuTime;
15594            }
15595
15596            app.setRawAdj = app.curRawAdj;
15597        }
15598
15599        int changes = 0;
15600
15601        if (app.curAdj != app.setAdj) {
15602            ProcessList.setOomAdj(app.pid, app.curAdj);
15603            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15604                TAG, "Set " + app.pid + " " + app.processName +
15605                " adj " + app.curAdj + ": " + app.adjType);
15606            app.setAdj = app.curAdj;
15607        }
15608
15609        if (app.setSchedGroup != app.curSchedGroup) {
15610            app.setSchedGroup = app.curSchedGroup;
15611            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15612                    "Setting process group of " + app.processName
15613                    + " to " + app.curSchedGroup);
15614            if (app.waitingToKill != null &&
15615                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15616                killUnneededProcessLocked(app, app.waitingToKill);
15617                success = false;
15618            } else {
15619                if (true) {
15620                    long oldId = Binder.clearCallingIdentity();
15621                    try {
15622                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15623                    } catch (Exception e) {
15624                        Slog.w(TAG, "Failed setting process group of " + app.pid
15625                                + " to " + app.curSchedGroup);
15626                        e.printStackTrace();
15627                    } finally {
15628                        Binder.restoreCallingIdentity(oldId);
15629                    }
15630                } else {
15631                    if (app.thread != null) {
15632                        try {
15633                            app.thread.setSchedulingGroup(app.curSchedGroup);
15634                        } catch (RemoteException e) {
15635                        }
15636                    }
15637                }
15638                Process.setSwappiness(app.pid,
15639                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15640            }
15641        }
15642        if (app.repForegroundActivities != app.foregroundActivities) {
15643            app.repForegroundActivities = app.foregroundActivities;
15644            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15645        }
15646        if (app.repProcState != app.curProcState) {
15647            app.repProcState = app.curProcState;
15648            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
15649            if (app.thread != null) {
15650                try {
15651                    if (false) {
15652                        //RuntimeException h = new RuntimeException("here");
15653                        Slog.i(TAG, "Sending new process state " + app.repProcState
15654                                + " to " + app /*, h*/);
15655                    }
15656                    app.thread.setProcessState(app.repProcState);
15657                } catch (RemoteException e) {
15658                }
15659            }
15660        }
15661        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15662                app.setProcState)) {
15663            app.lastStateTime = now;
15664            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15665                    isSleeping(), now);
15666            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15667                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15668                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15669                    + (app.nextPssTime-now) + ": " + app);
15670        } else {
15671            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15672                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15673                requestPssLocked(app, app.setProcState);
15674                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15675                        isSleeping(), now);
15676            } else if (false && DEBUG_PSS) {
15677                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15678            }
15679        }
15680        if (app.setProcState != app.curProcState) {
15681            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15682                    "Proc state change of " + app.processName
15683                    + " to " + app.curProcState);
15684            app.setProcState = app.curProcState;
15685            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15686                app.notCachedSinceIdle = false;
15687            }
15688            if (!doingAll) {
15689                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15690            } else {
15691                app.procStateChanged = true;
15692            }
15693        }
15694
15695        if (changes != 0) {
15696            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15697            int i = mPendingProcessChanges.size()-1;
15698            ProcessChangeItem item = null;
15699            while (i >= 0) {
15700                item = mPendingProcessChanges.get(i);
15701                if (item.pid == app.pid) {
15702                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15703                    break;
15704                }
15705                i--;
15706            }
15707            if (i < 0) {
15708                // No existing item in pending changes; need a new one.
15709                final int NA = mAvailProcessChanges.size();
15710                if (NA > 0) {
15711                    item = mAvailProcessChanges.remove(NA-1);
15712                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15713                } else {
15714                    item = new ProcessChangeItem();
15715                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15716                }
15717                item.changes = 0;
15718                item.pid = app.pid;
15719                item.uid = app.info.uid;
15720                if (mPendingProcessChanges.size() == 0) {
15721                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15722                            "*** Enqueueing dispatch processes changed!");
15723                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15724                }
15725                mPendingProcessChanges.add(item);
15726            }
15727            item.changes |= changes;
15728            item.processState = app.repProcState;
15729            item.foregroundActivities = app.repForegroundActivities;
15730            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
15731                    + Integer.toHexString(System.identityHashCode(item))
15732                    + " " + app.toShortString() + ": changes=" + item.changes
15733                    + " procState=" + item.processState
15734                    + " foreground=" + item.foregroundActivities
15735                    + " type=" + app.adjType + " source=" + app.adjSource
15736                    + " target=" + app.adjTarget);
15737        }
15738
15739        return success;
15740    }
15741
15742    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15743        if (proc.thread != null && proc.baseProcessTracker != null) {
15744            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15745        }
15746    }
15747
15748    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15749            ProcessRecord TOP_APP, boolean doingAll, long now) {
15750        if (app.thread == null) {
15751            return false;
15752        }
15753
15754        final boolean wasKeeping = app.keeping;
15755
15756        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15757
15758        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now);
15759    }
15760
15761    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15762            boolean oomAdj) {
15763        if (isForeground != proc.foregroundServices) {
15764            proc.foregroundServices = isForeground;
15765            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15766                    proc.info.uid);
15767            if (isForeground) {
15768                if (curProcs == null) {
15769                    curProcs = new ArrayList<ProcessRecord>();
15770                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15771                }
15772                if (!curProcs.contains(proc)) {
15773                    curProcs.add(proc);
15774                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15775                            proc.info.packageName, proc.info.uid);
15776                }
15777            } else {
15778                if (curProcs != null) {
15779                    if (curProcs.remove(proc)) {
15780                        mBatteryStatsService.noteEvent(
15781                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15782                                proc.info.packageName, proc.info.uid);
15783                        if (curProcs.size() <= 0) {
15784                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15785                        }
15786                    }
15787                }
15788            }
15789            if (oomAdj) {
15790                updateOomAdjLocked();
15791            }
15792        }
15793    }
15794
15795    private final ActivityRecord resumedAppLocked() {
15796        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15797        String pkg;
15798        int uid;
15799        if (act != null && !act.sleeping) {
15800            pkg = act.packageName;
15801            uid = act.info.applicationInfo.uid;
15802        } else {
15803            pkg = null;
15804            uid = -1;
15805        }
15806        // Has the UID or resumed package name changed?
15807        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15808                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15809            if (mCurResumedPackage != null) {
15810                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15811                        mCurResumedPackage, mCurResumedUid);
15812            }
15813            mCurResumedPackage = pkg;
15814            mCurResumedUid = uid;
15815            if (mCurResumedPackage != null) {
15816                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15817                        mCurResumedPackage, mCurResumedUid);
15818            }
15819        }
15820        return act;
15821    }
15822
15823    final boolean updateOomAdjLocked(ProcessRecord app) {
15824        final ActivityRecord TOP_ACT = resumedAppLocked();
15825        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15826        final boolean wasCached = app.cached;
15827
15828        mAdjSeq++;
15829
15830        // This is the desired cached adjusment we want to tell it to use.
15831        // If our app is currently cached, we know it, and that is it.  Otherwise,
15832        // we don't know it yet, and it needs to now be cached we will then
15833        // need to do a complete oom adj.
15834        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15835                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15836        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
15837                SystemClock.uptimeMillis());
15838        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15839            // Changed to/from cached state, so apps after it in the LRU
15840            // list may also be changed.
15841            updateOomAdjLocked();
15842        }
15843        return success;
15844    }
15845
15846    final void updateOomAdjLocked() {
15847        final ActivityRecord TOP_ACT = resumedAppLocked();
15848        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15849        final long now = SystemClock.uptimeMillis();
15850        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15851        final int N = mLruProcesses.size();
15852
15853        if (false) {
15854            RuntimeException e = new RuntimeException();
15855            e.fillInStackTrace();
15856            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15857        }
15858
15859        mAdjSeq++;
15860        mNewNumServiceProcs = 0;
15861        mNewNumAServiceProcs = 0;
15862
15863        final int emptyProcessLimit;
15864        final int cachedProcessLimit;
15865        if (mProcessLimit <= 0) {
15866            emptyProcessLimit = cachedProcessLimit = 0;
15867        } else if (mProcessLimit == 1) {
15868            emptyProcessLimit = 1;
15869            cachedProcessLimit = 0;
15870        } else {
15871            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15872            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15873        }
15874
15875        // Let's determine how many processes we have running vs.
15876        // how many slots we have for background processes; we may want
15877        // to put multiple processes in a slot of there are enough of
15878        // them.
15879        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15880                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15881        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15882        if (numEmptyProcs > cachedProcessLimit) {
15883            // If there are more empty processes than our limit on cached
15884            // processes, then use the cached process limit for the factor.
15885            // This ensures that the really old empty processes get pushed
15886            // down to the bottom, so if we are running low on memory we will
15887            // have a better chance at keeping around more cached processes
15888            // instead of a gazillion empty processes.
15889            numEmptyProcs = cachedProcessLimit;
15890        }
15891        int emptyFactor = numEmptyProcs/numSlots;
15892        if (emptyFactor < 1) emptyFactor = 1;
15893        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15894        if (cachedFactor < 1) cachedFactor = 1;
15895        int stepCached = 0;
15896        int stepEmpty = 0;
15897        int numCached = 0;
15898        int numEmpty = 0;
15899        int numTrimming = 0;
15900
15901        mNumNonCachedProcs = 0;
15902        mNumCachedHiddenProcs = 0;
15903
15904        // First update the OOM adjustment for each of the
15905        // application processes based on their current state.
15906        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15907        int nextCachedAdj = curCachedAdj+1;
15908        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15909        int nextEmptyAdj = curEmptyAdj+2;
15910        for (int i=N-1; i>=0; i--) {
15911            ProcessRecord app = mLruProcesses.get(i);
15912            if (!app.killedByAm && app.thread != null) {
15913                app.procStateChanged = false;
15914                final boolean wasKeeping = app.keeping;
15915                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15916
15917                // If we haven't yet assigned the final cached adj
15918                // to the process, do that now.
15919                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15920                    switch (app.curProcState) {
15921                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15922                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15923                            // This process is a cached process holding activities...
15924                            // assign it the next cached value for that type, and then
15925                            // step that cached level.
15926                            app.curRawAdj = curCachedAdj;
15927                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15928                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15929                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15930                                    + ")");
15931                            if (curCachedAdj != nextCachedAdj) {
15932                                stepCached++;
15933                                if (stepCached >= cachedFactor) {
15934                                    stepCached = 0;
15935                                    curCachedAdj = nextCachedAdj;
15936                                    nextCachedAdj += 2;
15937                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15938                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15939                                    }
15940                                }
15941                            }
15942                            break;
15943                        default:
15944                            // For everything else, assign next empty cached process
15945                            // level and bump that up.  Note that this means that
15946                            // long-running services that have dropped down to the
15947                            // cached level will be treated as empty (since their process
15948                            // state is still as a service), which is what we want.
15949                            app.curRawAdj = curEmptyAdj;
15950                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15951                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15952                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15953                                    + ")");
15954                            if (curEmptyAdj != nextEmptyAdj) {
15955                                stepEmpty++;
15956                                if (stepEmpty >= emptyFactor) {
15957                                    stepEmpty = 0;
15958                                    curEmptyAdj = nextEmptyAdj;
15959                                    nextEmptyAdj += 2;
15960                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15961                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15962                                    }
15963                                }
15964                            }
15965                            break;
15966                    }
15967                }
15968
15969                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now);
15970
15971                // Count the number of process types.
15972                switch (app.curProcState) {
15973                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15974                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15975                        mNumCachedHiddenProcs++;
15976                        numCached++;
15977                        if (numCached > cachedProcessLimit) {
15978                            killUnneededProcessLocked(app, "cached #" + numCached);
15979                        }
15980                        break;
15981                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15982                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15983                                && app.lastActivityTime < oldTime) {
15984                            killUnneededProcessLocked(app, "empty for "
15985                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15986                                    / 1000) + "s");
15987                        } else {
15988                            numEmpty++;
15989                            if (numEmpty > emptyProcessLimit) {
15990                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15991                            }
15992                        }
15993                        break;
15994                    default:
15995                        mNumNonCachedProcs++;
15996                        break;
15997                }
15998
15999                if (app.isolated && app.services.size() <= 0) {
16000                    // If this is an isolated process, and there are no
16001                    // services running in it, then the process is no longer
16002                    // needed.  We agressively kill these because we can by
16003                    // definition not re-use the same process again, and it is
16004                    // good to avoid having whatever code was running in them
16005                    // left sitting around after no longer needed.
16006                    killUnneededProcessLocked(app, "isolated not needed");
16007                }
16008
16009                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16010                        && !app.killedByAm) {
16011                    numTrimming++;
16012                }
16013            }
16014        }
16015
16016        mNumServiceProcs = mNewNumServiceProcs;
16017
16018        // Now determine the memory trimming level of background processes.
16019        // Unfortunately we need to start at the back of the list to do this
16020        // properly.  We only do this if the number of background apps we
16021        // are managing to keep around is less than half the maximum we desire;
16022        // if we are keeping a good number around, we'll let them use whatever
16023        // memory they want.
16024        final int numCachedAndEmpty = numCached + numEmpty;
16025        int memFactor;
16026        if (numCached <= ProcessList.TRIM_CACHED_APPS
16027                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16028            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16029                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16030            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16031                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16032            } else {
16033                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16034            }
16035        } else {
16036            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16037        }
16038        // We always allow the memory level to go up (better).  We only allow it to go
16039        // down if we are in a state where that is allowed, *and* the total number of processes
16040        // has gone down since last time.
16041        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16042                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16043                + " last=" + mLastNumProcesses);
16044        if (memFactor > mLastMemoryLevel) {
16045            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16046                memFactor = mLastMemoryLevel;
16047                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16048            }
16049        }
16050        mLastMemoryLevel = memFactor;
16051        mLastNumProcesses = mLruProcesses.size();
16052        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16053        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16054        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16055            if (mLowRamStartTime == 0) {
16056                mLowRamStartTime = now;
16057            }
16058            int step = 0;
16059            int fgTrimLevel;
16060            switch (memFactor) {
16061                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16062                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16063                    break;
16064                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16065                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16066                    break;
16067                default:
16068                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16069                    break;
16070            }
16071            int factor = numTrimming/3;
16072            int minFactor = 2;
16073            if (mHomeProcess != null) minFactor++;
16074            if (mPreviousProcess != null) minFactor++;
16075            if (factor < minFactor) factor = minFactor;
16076            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16077            for (int i=N-1; i>=0; i--) {
16078                ProcessRecord app = mLruProcesses.get(i);
16079                if (allChanged || app.procStateChanged) {
16080                    setProcessTrackerState(app, trackerMemFactor, now);
16081                    app.procStateChanged = false;
16082                }
16083                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16084                        && !app.killedByAm) {
16085                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16086                        try {
16087                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16088                                    "Trimming memory of " + app.processName
16089                                    + " to " + curLevel);
16090                            app.thread.scheduleTrimMemory(curLevel);
16091                        } catch (RemoteException e) {
16092                        }
16093                        if (false) {
16094                            // For now we won't do this; our memory trimming seems
16095                            // to be good enough at this point that destroying
16096                            // activities causes more harm than good.
16097                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16098                                    && app != mHomeProcess && app != mPreviousProcess) {
16099                                // Need to do this on its own message because the stack may not
16100                                // be in a consistent state at this point.
16101                                // For these apps we will also finish their activities
16102                                // to help them free memory.
16103                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16104                            }
16105                        }
16106                    }
16107                    app.trimMemoryLevel = curLevel;
16108                    step++;
16109                    if (step >= factor) {
16110                        step = 0;
16111                        switch (curLevel) {
16112                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16113                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16114                                break;
16115                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16116                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16117                                break;
16118                        }
16119                    }
16120                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16121                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16122                            && app.thread != null) {
16123                        try {
16124                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16125                                    "Trimming memory of heavy-weight " + app.processName
16126                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16127                            app.thread.scheduleTrimMemory(
16128                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16129                        } catch (RemoteException e) {
16130                        }
16131                    }
16132                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16133                } else {
16134                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16135                            || app.systemNoUi) && app.pendingUiClean) {
16136                        // If this application is now in the background and it
16137                        // had done UI, then give it the special trim level to
16138                        // have it free UI resources.
16139                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16140                        if (app.trimMemoryLevel < level && app.thread != null) {
16141                            try {
16142                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16143                                        "Trimming memory of bg-ui " + app.processName
16144                                        + " to " + level);
16145                                app.thread.scheduleTrimMemory(level);
16146                            } catch (RemoteException e) {
16147                            }
16148                        }
16149                        app.pendingUiClean = false;
16150                    }
16151                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16152                        try {
16153                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16154                                    "Trimming memory of fg " + app.processName
16155                                    + " to " + fgTrimLevel);
16156                            app.thread.scheduleTrimMemory(fgTrimLevel);
16157                        } catch (RemoteException e) {
16158                        }
16159                    }
16160                    app.trimMemoryLevel = fgTrimLevel;
16161                }
16162            }
16163        } else {
16164            if (mLowRamStartTime != 0) {
16165                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16166                mLowRamStartTime = 0;
16167            }
16168            for (int i=N-1; i>=0; i--) {
16169                ProcessRecord app = mLruProcesses.get(i);
16170                if (allChanged || app.procStateChanged) {
16171                    setProcessTrackerState(app, trackerMemFactor, now);
16172                    app.procStateChanged = false;
16173                }
16174                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16175                        || app.systemNoUi) && app.pendingUiClean) {
16176                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16177                            && app.thread != null) {
16178                        try {
16179                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16180                                    "Trimming memory of ui hidden " + app.processName
16181                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16182                            app.thread.scheduleTrimMemory(
16183                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16184                        } catch (RemoteException e) {
16185                        }
16186                    }
16187                    app.pendingUiClean = false;
16188                }
16189                app.trimMemoryLevel = 0;
16190            }
16191        }
16192
16193        if (mAlwaysFinishActivities) {
16194            // Need to do this on its own message because the stack may not
16195            // be in a consistent state at this point.
16196            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16197        }
16198
16199        if (allChanged) {
16200            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16201        }
16202
16203        if (mProcessStats.shouldWriteNowLocked(now)) {
16204            mHandler.post(new Runnable() {
16205                @Override public void run() {
16206                    synchronized (ActivityManagerService.this) {
16207                        mProcessStats.writeStateAsyncLocked();
16208                    }
16209                }
16210            });
16211        }
16212
16213        if (DEBUG_OOM_ADJ) {
16214            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16215        }
16216    }
16217
16218    final void trimApplications() {
16219        synchronized (this) {
16220            int i;
16221
16222            // First remove any unused application processes whose package
16223            // has been removed.
16224            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16225                final ProcessRecord app = mRemovedProcesses.get(i);
16226                if (app.activities.size() == 0
16227                        && app.curReceiver == null && app.services.size() == 0) {
16228                    Slog.i(
16229                        TAG, "Exiting empty application process "
16230                        + app.processName + " ("
16231                        + (app.thread != null ? app.thread.asBinder() : null)
16232                        + ")\n");
16233                    if (app.pid > 0 && app.pid != MY_PID) {
16234                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16235                                app.processName, app.setAdj, "empty");
16236                        app.killedByAm = true;
16237                        Process.killProcessQuiet(app.pid);
16238                    } else {
16239                        try {
16240                            app.thread.scheduleExit();
16241                        } catch (Exception e) {
16242                            // Ignore exceptions.
16243                        }
16244                    }
16245                    cleanUpApplicationRecordLocked(app, false, true, -1);
16246                    mRemovedProcesses.remove(i);
16247
16248                    if (app.persistent) {
16249                        if (app.persistent) {
16250                            addAppLocked(app.info, false);
16251                        }
16252                    }
16253                }
16254            }
16255
16256            // Now update the oom adj for all processes.
16257            updateOomAdjLocked();
16258        }
16259    }
16260
16261    /** This method sends the specified signal to each of the persistent apps */
16262    public void signalPersistentProcesses(int sig) throws RemoteException {
16263        if (sig != Process.SIGNAL_USR1) {
16264            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16265        }
16266
16267        synchronized (this) {
16268            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16269                    != PackageManager.PERMISSION_GRANTED) {
16270                throw new SecurityException("Requires permission "
16271                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16272            }
16273
16274            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16275                ProcessRecord r = mLruProcesses.get(i);
16276                if (r.thread != null && r.persistent) {
16277                    Process.sendSignal(r.pid, sig);
16278                }
16279            }
16280        }
16281    }
16282
16283    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16284        if (proc == null || proc == mProfileProc) {
16285            proc = mProfileProc;
16286            path = mProfileFile;
16287            profileType = mProfileType;
16288            clearProfilerLocked();
16289        }
16290        if (proc == null) {
16291            return;
16292        }
16293        try {
16294            proc.thread.profilerControl(false, path, null, profileType);
16295        } catch (RemoteException e) {
16296            throw new IllegalStateException("Process disappeared");
16297        }
16298    }
16299
16300    private void clearProfilerLocked() {
16301        if (mProfileFd != null) {
16302            try {
16303                mProfileFd.close();
16304            } catch (IOException e) {
16305            }
16306        }
16307        mProfileApp = null;
16308        mProfileProc = null;
16309        mProfileFile = null;
16310        mProfileType = 0;
16311        mAutoStopProfiler = false;
16312    }
16313
16314    public boolean profileControl(String process, int userId, boolean start,
16315            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16316
16317        try {
16318            synchronized (this) {
16319                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16320                // its own permission.
16321                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16322                        != PackageManager.PERMISSION_GRANTED) {
16323                    throw new SecurityException("Requires permission "
16324                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16325                }
16326
16327                if (start && fd == null) {
16328                    throw new IllegalArgumentException("null fd");
16329                }
16330
16331                ProcessRecord proc = null;
16332                if (process != null) {
16333                    proc = findProcessLocked(process, userId, "profileControl");
16334                }
16335
16336                if (start && (proc == null || proc.thread == null)) {
16337                    throw new IllegalArgumentException("Unknown process: " + process);
16338                }
16339
16340                if (start) {
16341                    stopProfilerLocked(null, null, 0);
16342                    setProfileApp(proc.info, proc.processName, path, fd, false);
16343                    mProfileProc = proc;
16344                    mProfileType = profileType;
16345                    try {
16346                        fd = fd.dup();
16347                    } catch (IOException e) {
16348                        fd = null;
16349                    }
16350                    proc.thread.profilerControl(start, path, fd, profileType);
16351                    fd = null;
16352                    mProfileFd = null;
16353                } else {
16354                    stopProfilerLocked(proc, path, profileType);
16355                    if (fd != null) {
16356                        try {
16357                            fd.close();
16358                        } catch (IOException e) {
16359                        }
16360                    }
16361                }
16362
16363                return true;
16364            }
16365        } catch (RemoteException e) {
16366            throw new IllegalStateException("Process disappeared");
16367        } finally {
16368            if (fd != null) {
16369                try {
16370                    fd.close();
16371                } catch (IOException e) {
16372                }
16373            }
16374        }
16375    }
16376
16377    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16378        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16379                userId, true, true, callName, null);
16380        ProcessRecord proc = null;
16381        try {
16382            int pid = Integer.parseInt(process);
16383            synchronized (mPidsSelfLocked) {
16384                proc = mPidsSelfLocked.get(pid);
16385            }
16386        } catch (NumberFormatException e) {
16387        }
16388
16389        if (proc == null) {
16390            ArrayMap<String, SparseArray<ProcessRecord>> all
16391                    = mProcessNames.getMap();
16392            SparseArray<ProcessRecord> procs = all.get(process);
16393            if (procs != null && procs.size() > 0) {
16394                proc = procs.valueAt(0);
16395                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16396                    for (int i=1; i<procs.size(); i++) {
16397                        ProcessRecord thisProc = procs.valueAt(i);
16398                        if (thisProc.userId == userId) {
16399                            proc = thisProc;
16400                            break;
16401                        }
16402                    }
16403                }
16404            }
16405        }
16406
16407        return proc;
16408    }
16409
16410    public boolean dumpHeap(String process, int userId, boolean managed,
16411            String path, ParcelFileDescriptor fd) throws RemoteException {
16412
16413        try {
16414            synchronized (this) {
16415                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16416                // its own permission (same as profileControl).
16417                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16418                        != PackageManager.PERMISSION_GRANTED) {
16419                    throw new SecurityException("Requires permission "
16420                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16421                }
16422
16423                if (fd == null) {
16424                    throw new IllegalArgumentException("null fd");
16425                }
16426
16427                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16428                if (proc == null || proc.thread == null) {
16429                    throw new IllegalArgumentException("Unknown process: " + process);
16430                }
16431
16432                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16433                if (!isDebuggable) {
16434                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16435                        throw new SecurityException("Process not debuggable: " + proc);
16436                    }
16437                }
16438
16439                proc.thread.dumpHeap(managed, path, fd);
16440                fd = null;
16441                return true;
16442            }
16443        } catch (RemoteException e) {
16444            throw new IllegalStateException("Process disappeared");
16445        } finally {
16446            if (fd != null) {
16447                try {
16448                    fd.close();
16449                } catch (IOException e) {
16450                }
16451            }
16452        }
16453    }
16454
16455    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16456    public void monitor() {
16457        synchronized (this) { }
16458    }
16459
16460    void onCoreSettingsChange(Bundle settings) {
16461        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16462            ProcessRecord processRecord = mLruProcesses.get(i);
16463            try {
16464                if (processRecord.thread != null) {
16465                    processRecord.thread.setCoreSettings(settings);
16466                }
16467            } catch (RemoteException re) {
16468                /* ignore */
16469            }
16470        }
16471    }
16472
16473    // Multi-user methods
16474
16475    /**
16476     * Start user, if its not already running, but don't bring it to foreground.
16477     */
16478    @Override
16479    public boolean startUserInBackground(final int userId) {
16480        return startUser(userId, /* foreground */ false);
16481    }
16482
16483    /**
16484     * Refreshes the list of users related to the current user when either a
16485     * user switch happens or when a new related user is started in the
16486     * background.
16487     */
16488    private void updateCurrentProfileIdsLocked() {
16489        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16490                mCurrentUserId, false /* enabledOnly */);
16491        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16492        for (int i = 0; i < currentProfileIds.length; i++) {
16493            currentProfileIds[i] = profiles.get(i).id;
16494        }
16495        mCurrentProfileIds = currentProfileIds;
16496    }
16497
16498    private Set getProfileIdsLocked(int userId) {
16499        Set userIds = new HashSet<Integer>();
16500        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16501                userId, false /* enabledOnly */);
16502        for (UserInfo user : profiles) {
16503            userIds.add(Integer.valueOf(user.id));
16504        }
16505        return userIds;
16506    }
16507
16508    @Override
16509    public boolean switchUser(final int userId) {
16510        return startUser(userId, /* foregound */ true);
16511    }
16512
16513    private boolean startUser(final int userId, boolean foreground) {
16514        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16515                != PackageManager.PERMISSION_GRANTED) {
16516            String msg = "Permission Denial: switchUser() from pid="
16517                    + Binder.getCallingPid()
16518                    + ", uid=" + Binder.getCallingUid()
16519                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16520            Slog.w(TAG, msg);
16521            throw new SecurityException(msg);
16522        }
16523
16524        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16525
16526        final long ident = Binder.clearCallingIdentity();
16527        try {
16528            synchronized (this) {
16529                final int oldUserId = mCurrentUserId;
16530                if (oldUserId == userId) {
16531                    return true;
16532                }
16533
16534                mStackSupervisor.setLockTaskModeLocked(null);
16535
16536                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16537                if (userInfo == null) {
16538                    Slog.w(TAG, "No user info for user #" + userId);
16539                    return false;
16540                }
16541
16542                if (foreground) {
16543                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16544                            R.anim.screen_user_enter);
16545                }
16546
16547                boolean needStart = false;
16548
16549                // If the user we are switching to is not currently started, then
16550                // we need to start it now.
16551                if (mStartedUsers.get(userId) == null) {
16552                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16553                    updateStartedUserArrayLocked();
16554                    needStart = true;
16555                }
16556
16557                final Integer userIdInt = Integer.valueOf(userId);
16558                mUserLru.remove(userIdInt);
16559                mUserLru.add(userIdInt);
16560
16561                if (foreground) {
16562                    mCurrentUserId = userId;
16563                    updateCurrentProfileIdsLocked();
16564                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16565                    // Once the internal notion of the active user has switched, we lock the device
16566                    // with the option to show the user switcher on the keyguard.
16567                    mWindowManager.lockNow(null);
16568                } else {
16569                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16570                    updateCurrentProfileIdsLocked();
16571                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16572                    mUserLru.remove(currentUserIdInt);
16573                    mUserLru.add(currentUserIdInt);
16574                }
16575
16576                final UserStartedState uss = mStartedUsers.get(userId);
16577
16578                // Make sure user is in the started state.  If it is currently
16579                // stopping, we need to knock that off.
16580                if (uss.mState == UserStartedState.STATE_STOPPING) {
16581                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16582                    // so we can just fairly silently bring the user back from
16583                    // the almost-dead.
16584                    uss.mState = UserStartedState.STATE_RUNNING;
16585                    updateStartedUserArrayLocked();
16586                    needStart = true;
16587                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16588                    // This means ACTION_SHUTDOWN has been sent, so we will
16589                    // need to treat this as a new boot of the user.
16590                    uss.mState = UserStartedState.STATE_BOOTING;
16591                    updateStartedUserArrayLocked();
16592                    needStart = true;
16593                }
16594
16595                if (uss.mState == UserStartedState.STATE_BOOTING) {
16596                    // Booting up a new user, need to tell system services about it.
16597                    // Note that this is on the same handler as scheduling of broadcasts,
16598                    // which is important because it needs to go first.
16599                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
16600                }
16601
16602                if (foreground) {
16603                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId));
16604                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16605                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16606                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16607                            oldUserId, userId, uss));
16608                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16609                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16610                }
16611
16612                if (needStart) {
16613                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16614                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16615                            | Intent.FLAG_RECEIVER_FOREGROUND);
16616                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16617                    broadcastIntentLocked(null, null, intent,
16618                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16619                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16620                }
16621
16622                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16623                    if (userId != UserHandle.USER_OWNER) {
16624                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16625                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16626                        broadcastIntentLocked(null, null, intent, null,
16627                                new IIntentReceiver.Stub() {
16628                                    public void performReceive(Intent intent, int resultCode,
16629                                            String data, Bundle extras, boolean ordered,
16630                                            boolean sticky, int sendingUser) {
16631                                        userInitialized(uss, userId);
16632                                    }
16633                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16634                                true, false, MY_PID, Process.SYSTEM_UID,
16635                                userId);
16636                        uss.initializing = true;
16637                    } else {
16638                        getUserManagerLocked().makeInitialized(userInfo.id);
16639                    }
16640                }
16641
16642                if (foreground) {
16643                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16644                    if (homeInFront) {
16645                        startHomeActivityLocked(userId);
16646                    } else {
16647                        mStackSupervisor.resumeTopActivitiesLocked();
16648                    }
16649                    EventLogTags.writeAmSwitchUser(userId);
16650                    getUserManagerLocked().userForeground(userId);
16651                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16652                } else {
16653                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
16654                }
16655
16656                if (needStart) {
16657                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16658                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16659                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16660                    broadcastIntentLocked(null, null, intent,
16661                            null, new IIntentReceiver.Stub() {
16662                                @Override
16663                                public void performReceive(Intent intent, int resultCode, String data,
16664                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16665                                        throws RemoteException {
16666                                }
16667                            }, 0, null, null,
16668                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16669                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16670                }
16671            }
16672        } finally {
16673            Binder.restoreCallingIdentity(ident);
16674        }
16675
16676        return true;
16677    }
16678
16679    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16680        long ident = Binder.clearCallingIdentity();
16681        try {
16682            Intent intent;
16683            if (oldUserId >= 0) {
16684                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16685                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16686                        | Intent.FLAG_RECEIVER_FOREGROUND);
16687                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16688                broadcastIntentLocked(null, null, intent,
16689                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16690                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16691            }
16692            if (newUserId >= 0) {
16693                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16694                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16695                        | Intent.FLAG_RECEIVER_FOREGROUND);
16696                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16697                broadcastIntentLocked(null, null, intent,
16698                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16699                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16700                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16701                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16702                        | Intent.FLAG_RECEIVER_FOREGROUND);
16703                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16704                broadcastIntentLocked(null, null, intent,
16705                        null, null, 0, null, null,
16706                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16707                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16708            }
16709        } finally {
16710            Binder.restoreCallingIdentity(ident);
16711        }
16712    }
16713
16714    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16715            final int newUserId) {
16716        final int N = mUserSwitchObservers.beginBroadcast();
16717        if (N > 0) {
16718            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16719                int mCount = 0;
16720                @Override
16721                public void sendResult(Bundle data) throws RemoteException {
16722                    synchronized (ActivityManagerService.this) {
16723                        if (mCurUserSwitchCallback == this) {
16724                            mCount++;
16725                            if (mCount == N) {
16726                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16727                            }
16728                        }
16729                    }
16730                }
16731            };
16732            synchronized (this) {
16733                uss.switching = true;
16734                mCurUserSwitchCallback = callback;
16735            }
16736            for (int i=0; i<N; i++) {
16737                try {
16738                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16739                            newUserId, callback);
16740                } catch (RemoteException e) {
16741                }
16742            }
16743        } else {
16744            synchronized (this) {
16745                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16746            }
16747        }
16748        mUserSwitchObservers.finishBroadcast();
16749    }
16750
16751    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16752        synchronized (this) {
16753            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16754            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16755        }
16756    }
16757
16758    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16759        mCurUserSwitchCallback = null;
16760        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16761        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16762                oldUserId, newUserId, uss));
16763    }
16764
16765    void userInitialized(UserStartedState uss, int newUserId) {
16766        completeSwitchAndInitalize(uss, newUserId, true, false);
16767    }
16768
16769    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16770        completeSwitchAndInitalize(uss, newUserId, false, true);
16771    }
16772
16773    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16774            boolean clearInitializing, boolean clearSwitching) {
16775        boolean unfrozen = false;
16776        synchronized (this) {
16777            if (clearInitializing) {
16778                uss.initializing = false;
16779                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16780            }
16781            if (clearSwitching) {
16782                uss.switching = false;
16783            }
16784            if (!uss.switching && !uss.initializing) {
16785                mWindowManager.stopFreezingScreen();
16786                unfrozen = true;
16787            }
16788        }
16789        if (unfrozen) {
16790            final int N = mUserSwitchObservers.beginBroadcast();
16791            for (int i=0; i<N; i++) {
16792                try {
16793                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16794                } catch (RemoteException e) {
16795                }
16796            }
16797            mUserSwitchObservers.finishBroadcast();
16798        }
16799    }
16800
16801    void scheduleStartProfilesLocked() {
16802        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
16803            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
16804                    DateUtils.SECOND_IN_MILLIS);
16805        }
16806    }
16807
16808    void startProfilesLocked() {
16809        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
16810        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16811                mCurrentUserId, false /* enabledOnly */);
16812        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
16813        for (UserInfo user : profiles) {
16814            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
16815                    && user.id != mCurrentUserId) {
16816                toStart.add(user);
16817            }
16818        }
16819        final int n = toStart.size();
16820        int i = 0;
16821        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
16822            startUserInBackground(toStart.get(i).id);
16823        }
16824        if (i < n) {
16825            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
16826        }
16827    }
16828
16829    void finishUserBoot(UserStartedState uss) {
16830        synchronized (this) {
16831            if (uss.mState == UserStartedState.STATE_BOOTING
16832                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16833                uss.mState = UserStartedState.STATE_RUNNING;
16834                final int userId = uss.mHandle.getIdentifier();
16835                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16836                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16837                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16838                broadcastIntentLocked(null, null, intent,
16839                        null, null, 0, null, null,
16840                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16841                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16842            }
16843        }
16844    }
16845
16846    void finishUserSwitch(UserStartedState uss) {
16847        synchronized (this) {
16848            finishUserBoot(uss);
16849
16850            startProfilesLocked();
16851
16852            int num = mUserLru.size();
16853            int i = 0;
16854            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16855                Integer oldUserId = mUserLru.get(i);
16856                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16857                if (oldUss == null) {
16858                    // Shouldn't happen, but be sane if it does.
16859                    mUserLru.remove(i);
16860                    num--;
16861                    continue;
16862                }
16863                if (oldUss.mState == UserStartedState.STATE_STOPPING
16864                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16865                    // This user is already stopping, doesn't count.
16866                    num--;
16867                    i++;
16868                    continue;
16869                }
16870                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16871                    // Owner and current can't be stopped, but count as running.
16872                    i++;
16873                    continue;
16874                }
16875                // This is a user to be stopped.
16876                stopUserLocked(oldUserId, null);
16877                num--;
16878                i++;
16879            }
16880        }
16881    }
16882
16883    @Override
16884    public int stopUser(final int userId, final IStopUserCallback callback) {
16885        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16886                != PackageManager.PERMISSION_GRANTED) {
16887            String msg = "Permission Denial: switchUser() from pid="
16888                    + Binder.getCallingPid()
16889                    + ", uid=" + Binder.getCallingUid()
16890                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16891            Slog.w(TAG, msg);
16892            throw new SecurityException(msg);
16893        }
16894        if (userId <= 0) {
16895            throw new IllegalArgumentException("Can't stop primary user " + userId);
16896        }
16897        synchronized (this) {
16898            return stopUserLocked(userId, callback);
16899        }
16900    }
16901
16902    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16903        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
16904        if (mCurrentUserId == userId) {
16905            return ActivityManager.USER_OP_IS_CURRENT;
16906        }
16907
16908        final UserStartedState uss = mStartedUsers.get(userId);
16909        if (uss == null) {
16910            // User is not started, nothing to do...  but we do need to
16911            // callback if requested.
16912            if (callback != null) {
16913                mHandler.post(new Runnable() {
16914                    @Override
16915                    public void run() {
16916                        try {
16917                            callback.userStopped(userId);
16918                        } catch (RemoteException e) {
16919                        }
16920                    }
16921                });
16922            }
16923            return ActivityManager.USER_OP_SUCCESS;
16924        }
16925
16926        if (callback != null) {
16927            uss.mStopCallbacks.add(callback);
16928        }
16929
16930        if (uss.mState != UserStartedState.STATE_STOPPING
16931                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16932            uss.mState = UserStartedState.STATE_STOPPING;
16933            updateStartedUserArrayLocked();
16934
16935            long ident = Binder.clearCallingIdentity();
16936            try {
16937                // We are going to broadcast ACTION_USER_STOPPING and then
16938                // once that is done send a final ACTION_SHUTDOWN and then
16939                // stop the user.
16940                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16941                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16942                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16943                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16944                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16945                // This is the result receiver for the final shutdown broadcast.
16946                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16947                    @Override
16948                    public void performReceive(Intent intent, int resultCode, String data,
16949                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16950                        finishUserStop(uss);
16951                    }
16952                };
16953                // This is the result receiver for the initial stopping broadcast.
16954                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16955                    @Override
16956                    public void performReceive(Intent intent, int resultCode, String data,
16957                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16958                        // On to the next.
16959                        synchronized (ActivityManagerService.this) {
16960                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16961                                // Whoops, we are being started back up.  Abort, abort!
16962                                return;
16963                            }
16964                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16965                        }
16966                        mSystemServiceManager.stopUser(userId);
16967                        broadcastIntentLocked(null, null, shutdownIntent,
16968                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16969                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16970                    }
16971                };
16972                // Kick things off.
16973                broadcastIntentLocked(null, null, stoppingIntent,
16974                        null, stoppingReceiver, 0, null, null,
16975                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16976                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16977            } finally {
16978                Binder.restoreCallingIdentity(ident);
16979            }
16980        }
16981
16982        return ActivityManager.USER_OP_SUCCESS;
16983    }
16984
16985    void finishUserStop(UserStartedState uss) {
16986        final int userId = uss.mHandle.getIdentifier();
16987        boolean stopped;
16988        ArrayList<IStopUserCallback> callbacks;
16989        synchronized (this) {
16990            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16991            if (mStartedUsers.get(userId) != uss) {
16992                stopped = false;
16993            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16994                stopped = false;
16995            } else {
16996                stopped = true;
16997                // User can no longer run.
16998                mStartedUsers.remove(userId);
16999                mUserLru.remove(Integer.valueOf(userId));
17000                updateStartedUserArrayLocked();
17001
17002                // Clean up all state and processes associated with the user.
17003                // Kill all the processes for the user.
17004                forceStopUserLocked(userId, "finish user");
17005            }
17006        }
17007
17008        for (int i=0; i<callbacks.size(); i++) {
17009            try {
17010                if (stopped) callbacks.get(i).userStopped(userId);
17011                else callbacks.get(i).userStopAborted(userId);
17012            } catch (RemoteException e) {
17013            }
17014        }
17015
17016        if (stopped) {
17017            mSystemServiceManager.cleanupUser(userId);
17018            synchronized (this) {
17019                mStackSupervisor.removeUserLocked(userId);
17020            }
17021        }
17022    }
17023
17024    @Override
17025    public UserInfo getCurrentUser() {
17026        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17027                != PackageManager.PERMISSION_GRANTED) && (
17028                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
17029                != PackageManager.PERMISSION_GRANTED)) {
17030            String msg = "Permission Denial: getCurrentUser() from pid="
17031                    + Binder.getCallingPid()
17032                    + ", uid=" + Binder.getCallingUid()
17033                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17034            Slog.w(TAG, msg);
17035            throw new SecurityException(msg);
17036        }
17037        synchronized (this) {
17038            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17039        }
17040    }
17041
17042    int getCurrentUserIdLocked() {
17043        return mCurrentUserId;
17044    }
17045
17046    @Override
17047    public boolean isUserRunning(int userId, boolean orStopped) {
17048        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17049                != PackageManager.PERMISSION_GRANTED) {
17050            String msg = "Permission Denial: isUserRunning() from pid="
17051                    + Binder.getCallingPid()
17052                    + ", uid=" + Binder.getCallingUid()
17053                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17054            Slog.w(TAG, msg);
17055            throw new SecurityException(msg);
17056        }
17057        synchronized (this) {
17058            return isUserRunningLocked(userId, orStopped);
17059        }
17060    }
17061
17062    boolean isUserRunningLocked(int userId, boolean orStopped) {
17063        UserStartedState state = mStartedUsers.get(userId);
17064        if (state == null) {
17065            return false;
17066        }
17067        if (orStopped) {
17068            return true;
17069        }
17070        return state.mState != UserStartedState.STATE_STOPPING
17071                && state.mState != UserStartedState.STATE_SHUTDOWN;
17072    }
17073
17074    @Override
17075    public int[] getRunningUserIds() {
17076        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17077                != PackageManager.PERMISSION_GRANTED) {
17078            String msg = "Permission Denial: isUserRunning() from pid="
17079                    + Binder.getCallingPid()
17080                    + ", uid=" + Binder.getCallingUid()
17081                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17082            Slog.w(TAG, msg);
17083            throw new SecurityException(msg);
17084        }
17085        synchronized (this) {
17086            return mStartedUserArray;
17087        }
17088    }
17089
17090    private void updateStartedUserArrayLocked() {
17091        int num = 0;
17092        for (int i=0; i<mStartedUsers.size();  i++) {
17093            UserStartedState uss = mStartedUsers.valueAt(i);
17094            // This list does not include stopping users.
17095            if (uss.mState != UserStartedState.STATE_STOPPING
17096                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17097                num++;
17098            }
17099        }
17100        mStartedUserArray = new int[num];
17101        num = 0;
17102        for (int i=0; i<mStartedUsers.size();  i++) {
17103            UserStartedState uss = mStartedUsers.valueAt(i);
17104            if (uss.mState != UserStartedState.STATE_STOPPING
17105                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17106                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17107                num++;
17108            }
17109        }
17110    }
17111
17112    @Override
17113    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17114        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
17115                != PackageManager.PERMISSION_GRANTED) {
17116            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17117                    + Binder.getCallingPid()
17118                    + ", uid=" + Binder.getCallingUid()
17119                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
17120            Slog.w(TAG, msg);
17121            throw new SecurityException(msg);
17122        }
17123
17124        mUserSwitchObservers.register(observer);
17125    }
17126
17127    @Override
17128    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17129        mUserSwitchObservers.unregister(observer);
17130    }
17131
17132    private boolean userExists(int userId) {
17133        if (userId == 0) {
17134            return true;
17135        }
17136        UserManagerService ums = getUserManagerLocked();
17137        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17138    }
17139
17140    int[] getUsersLocked() {
17141        UserManagerService ums = getUserManagerLocked();
17142        return ums != null ? ums.getUserIds() : new int[] { 0 };
17143    }
17144
17145    UserManagerService getUserManagerLocked() {
17146        if (mUserManager == null) {
17147            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17148            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17149        }
17150        return mUserManager;
17151    }
17152
17153    private int applyUserId(int uid, int userId) {
17154        return UserHandle.getUid(userId, uid);
17155    }
17156
17157    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17158        if (info == null) return null;
17159        ApplicationInfo newInfo = new ApplicationInfo(info);
17160        newInfo.uid = applyUserId(info.uid, userId);
17161        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17162                + info.packageName;
17163        return newInfo;
17164    }
17165
17166    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17167        if (aInfo == null
17168                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17169            return aInfo;
17170        }
17171
17172        ActivityInfo info = new ActivityInfo(aInfo);
17173        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17174        return info;
17175    }
17176
17177    private final class LocalService extends ActivityManagerInternal {
17178        @Override
17179        public void goingToSleep() {
17180            ActivityManagerService.this.goingToSleep();
17181        }
17182
17183        @Override
17184        public void wakingUp() {
17185            ActivityManagerService.this.wakingUp();
17186        }
17187    }
17188
17189    /**
17190     * An implementation of IAppTask, that allows an app to manage its own tasks via
17191     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17192     * only the process that calls getAppTasks() can call the AppTask methods.
17193     */
17194    class AppTaskImpl extends IAppTask.Stub {
17195        private int mTaskId;
17196        private int mCallingUid;
17197
17198        public AppTaskImpl(int taskId, int callingUid) {
17199            mTaskId = taskId;
17200            mCallingUid = callingUid;
17201        }
17202
17203        @Override
17204        public void finishAndRemoveTask() {
17205            // Ensure that we are called from the same process that created this AppTask
17206            if (mCallingUid != Binder.getCallingUid()) {
17207                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17208                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17209                return;
17210            }
17211
17212            synchronized (ActivityManagerService.this) {
17213                long origId = Binder.clearCallingIdentity();
17214                try {
17215                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17216                    if (tr != null) {
17217                        // Only kill the process if we are not a new document
17218                        int flags = tr.getBaseIntent().getFlags();
17219                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17220                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17221                        removeTaskByIdLocked(mTaskId,
17222                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17223                    }
17224                } finally {
17225                    Binder.restoreCallingIdentity(origId);
17226                }
17227            }
17228        }
17229
17230        @Override
17231        public ActivityManager.RecentTaskInfo getTaskInfo() {
17232            // Ensure that we are called from the same process that created this AppTask
17233            if (mCallingUid != Binder.getCallingUid()) {
17234                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17235                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17236                return null;
17237            }
17238
17239            synchronized (ActivityManagerService.this) {
17240                long origId = Binder.clearCallingIdentity();
17241                try {
17242                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17243                    if (tr != null) {
17244                        return createRecentTaskInfoFromTaskRecord(tr);
17245                    }
17246                } finally {
17247                    Binder.restoreCallingIdentity(origId);
17248                }
17249                return null;
17250            }
17251        }
17252    }
17253}
17254