ActivityManagerService.java revision a002604af0c9b1204556610537b85685d7055996
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.content.pm.PackageManager.PERMISSION_GRANTED;
20import static com.android.internal.util.XmlUtils.readBooleanAttribute;
21import static com.android.internal.util.XmlUtils.readIntAttribute;
22import static com.android.internal.util.XmlUtils.readLongAttribute;
23import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
24import static com.android.internal.util.XmlUtils.writeIntAttribute;
25import static com.android.internal.util.XmlUtils.writeLongAttribute;
26import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
27import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
28import static org.xmlpull.v1.XmlPullParser.START_TAG;
29import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
30
31import android.Manifest;
32import android.app.AppOpsManager;
33import android.app.IActivityContainer;
34import android.app.IActivityContainerCallback;
35import android.appwidget.AppWidgetManager;
36import android.graphics.Rect;
37import android.os.BatteryStats;
38import android.os.PersistableBundle;
39import android.service.voice.IVoiceInteractionSession;
40import android.util.ArrayMap;
41
42import com.android.internal.R;
43import com.android.internal.annotations.GuardedBy;
44import com.android.internal.app.IAppOpsService;
45import com.android.internal.app.IVoiceInteractor;
46import com.android.internal.app.ProcessMap;
47import com.android.internal.app.ProcessStats;
48import com.android.internal.content.PackageMonitor;
49import com.android.internal.os.BackgroundThread;
50import com.android.internal.os.BatteryStatsImpl;
51import com.android.internal.os.ProcessCpuTracker;
52import com.android.internal.os.TransferPipe;
53import com.android.internal.os.Zygote;
54import com.android.internal.util.FastPrintWriter;
55import com.android.internal.util.FastXmlSerializer;
56import com.android.internal.util.MemInfoReader;
57import com.android.internal.util.Preconditions;
58import com.android.server.AppOpsService;
59import com.android.server.AttributeCache;
60import com.android.server.IntentResolver;
61import com.android.server.LocalServices;
62import com.android.server.ServiceThread;
63import com.android.server.SystemService;
64import com.android.server.SystemServiceManager;
65import com.android.server.Watchdog;
66import com.android.server.am.ActivityStack.ActivityState;
67import com.android.server.firewall.IntentFirewall;
68import com.android.server.pm.UserManagerService;
69import com.android.server.wm.AppTransition;
70import com.android.server.wm.WindowManagerService;
71import com.google.android.collect.Lists;
72import com.google.android.collect.Maps;
73
74import libcore.io.IoUtils;
75
76import org.xmlpull.v1.XmlPullParser;
77import org.xmlpull.v1.XmlPullParserException;
78import org.xmlpull.v1.XmlSerializer;
79
80import android.app.Activity;
81import android.app.ActivityManager;
82import android.app.ActivityManager.RunningTaskInfo;
83import android.app.ActivityManager.StackInfo;
84import android.app.ActivityManagerInternal;
85import android.app.ActivityManagerNative;
86import android.app.ActivityOptions;
87import android.app.ActivityThread;
88import android.app.AlertDialog;
89import android.app.AppGlobals;
90import android.app.ApplicationErrorReport;
91import android.app.Dialog;
92import android.app.IActivityController;
93import android.app.IApplicationThread;
94import android.app.IInstrumentationWatcher;
95import android.app.INotificationManager;
96import android.app.IProcessObserver;
97import android.app.IServiceConnection;
98import android.app.IStopUserCallback;
99import android.app.IUiAutomationConnection;
100import android.app.IUserSwitchObserver;
101import android.app.Instrumentation;
102import android.app.Notification;
103import android.app.NotificationManager;
104import android.app.PendingIntent;
105import android.app.backup.IBackupManager;
106import android.content.ActivityNotFoundException;
107import android.content.BroadcastReceiver;
108import android.content.ClipData;
109import android.content.ComponentCallbacks2;
110import android.content.ComponentName;
111import android.content.ContentProvider;
112import android.content.ContentResolver;
113import android.content.Context;
114import android.content.DialogInterface;
115import android.content.IContentProvider;
116import android.content.IIntentReceiver;
117import android.content.IIntentSender;
118import android.content.Intent;
119import android.content.IntentFilter;
120import android.content.IntentSender;
121import android.content.pm.ActivityInfo;
122import android.content.pm.ApplicationInfo;
123import android.content.pm.ConfigurationInfo;
124import android.content.pm.IPackageDataObserver;
125import android.content.pm.IPackageManager;
126import android.content.pm.InstrumentationInfo;
127import android.content.pm.PackageInfo;
128import android.content.pm.PackageManager;
129import android.content.pm.ParceledListSlice;
130import android.content.pm.UserInfo;
131import android.content.pm.PackageManager.NameNotFoundException;
132import android.content.pm.PathPermission;
133import android.content.pm.ProviderInfo;
134import android.content.pm.ResolveInfo;
135import android.content.pm.ServiceInfo;
136import android.content.res.CompatibilityInfo;
137import android.content.res.Configuration;
138import android.graphics.Bitmap;
139import android.net.Proxy;
140import android.net.ProxyProperties;
141import android.net.Uri;
142import android.os.Binder;
143import android.os.Build;
144import android.os.Bundle;
145import android.os.Debug;
146import android.os.DropBoxManager;
147import android.os.Environment;
148import android.os.FactoryTest;
149import android.os.FileObserver;
150import android.os.FileUtils;
151import android.os.Handler;
152import android.os.IBinder;
153import android.os.IPermissionController;
154import android.os.IRemoteCallback;
155import android.os.IUserManager;
156import android.os.Looper;
157import android.os.Message;
158import android.os.Parcel;
159import android.os.ParcelFileDescriptor;
160import android.os.Process;
161import android.os.RemoteCallbackList;
162import android.os.RemoteException;
163import android.os.SELinux;
164import android.os.ServiceManager;
165import android.os.StrictMode;
166import android.os.SystemClock;
167import android.os.SystemProperties;
168import android.os.UpdateLock;
169import android.os.UserHandle;
170import android.provider.Settings;
171import android.text.format.DateUtils;
172import android.text.format.Time;
173import android.util.AtomicFile;
174import android.util.EventLog;
175import android.util.Log;
176import android.util.Pair;
177import android.util.PrintWriterPrinter;
178import android.util.Slog;
179import android.util.SparseArray;
180import android.util.TimeUtils;
181import android.util.Xml;
182import android.view.Gravity;
183import android.view.LayoutInflater;
184import android.view.View;
185import android.view.WindowManager;
186
187import java.io.BufferedInputStream;
188import java.io.BufferedOutputStream;
189import java.io.DataInputStream;
190import java.io.DataOutputStream;
191import java.io.File;
192import java.io.FileDescriptor;
193import java.io.FileInputStream;
194import java.io.FileNotFoundException;
195import java.io.FileOutputStream;
196import java.io.IOException;
197import java.io.InputStreamReader;
198import java.io.PrintWriter;
199import java.io.StringWriter;
200import java.lang.ref.WeakReference;
201import java.util.ArrayList;
202import java.util.Arrays;
203import java.util.Collections;
204import java.util.Comparator;
205import java.util.HashMap;
206import java.util.HashSet;
207import java.util.Iterator;
208import java.util.List;
209import java.util.Locale;
210import java.util.Map;
211import java.util.Set;
212import java.util.concurrent.atomic.AtomicBoolean;
213import java.util.concurrent.atomic.AtomicLong;
214
215public final class ActivityManagerService extends ActivityManagerNative
216        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
217    private static final String USER_DATA_DIR = "/data/user/";
218    static final String TAG = "ActivityManager";
219    static final String TAG_MU = "ActivityManagerServiceMU";
220    static final boolean DEBUG = false;
221    static final boolean localLOGV = DEBUG;
222    static final boolean DEBUG_BACKUP = localLOGV || false;
223    static final boolean DEBUG_BROADCAST = localLOGV || false;
224    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
225    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
226    static final boolean DEBUG_CLEANUP = localLOGV || false;
227    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
228    static final boolean DEBUG_FOCUS = false;
229    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
230    static final boolean DEBUG_MU = localLOGV || false;
231    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
232    static final boolean DEBUG_LRU = localLOGV || false;
233    static final boolean DEBUG_PAUSE = localLOGV || false;
234    static final boolean DEBUG_POWER = localLOGV || false;
235    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
236    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
237    static final boolean DEBUG_PROCESSES = localLOGV || false;
238    static final boolean DEBUG_PROVIDER = localLOGV || false;
239    static final boolean DEBUG_RESULTS = localLOGV || false;
240    static final boolean DEBUG_SERVICE = localLOGV || false;
241    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
242    static final boolean DEBUG_STACK = localLOGV || false;
243    static final boolean DEBUG_SWITCH = localLOGV || false;
244    static final boolean DEBUG_TASKS = localLOGV || false;
245    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
246    static final boolean DEBUG_TRANSITION = localLOGV || false;
247    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
248    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
249    static final boolean DEBUG_VISBILITY = localLOGV || false;
250    static final boolean DEBUG_PSS = localLOGV || false;
251    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
252    static final boolean VALIDATE_TOKENS = false;
253    static final boolean SHOW_ACTIVITY_START_TIME = true;
254
255    // Control over CPU and battery monitoring.
256    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
257    static final boolean MONITOR_CPU_USAGE = true;
258    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
259    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
260    static final boolean MONITOR_THREAD_CPU_USAGE = false;
261
262    // The flags that are set for all calls we make to the package manager.
263    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
264
265    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
266
267    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
268
269    // Maximum number of recent tasks that we can remember.
270    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20;
271
272    // Amount of time after a call to stopAppSwitches() during which we will
273    // prevent further untrusted switches from happening.
274    static final long APP_SWITCH_DELAY_TIME = 5*1000;
275
276    // How long we wait for a launched process to attach to the activity manager
277    // before we decide it's never going to come up for real.
278    static final int PROC_START_TIMEOUT = 10*1000;
279
280    // How long we wait for a launched process to attach to the activity manager
281    // before we decide it's never going to come up for real, when the process was
282    // started with a wrapper for instrumentation (such as Valgrind) because it
283    // could take much longer than usual.
284    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
285
286    // How long to wait after going idle before forcing apps to GC.
287    static final int GC_TIMEOUT = 5*1000;
288
289    // The minimum amount of time between successive GC requests for a process.
290    static final int GC_MIN_INTERVAL = 60*1000;
291
292    // The minimum amount of time between successive PSS requests for a process.
293    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
294
295    // The minimum amount of time between successive PSS requests for a process
296    // when the request is due to the memory state being lowered.
297    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
298
299    // The rate at which we check for apps using excessive power -- 15 mins.
300    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
301
302    // The minimum sample duration we will allow before deciding we have
303    // enough data on wake locks to start killing things.
304    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
305
306    // The minimum sample duration we will allow before deciding we have
307    // enough data on CPU usage to start killing things.
308    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
309
310    // How long we allow a receiver to run before giving up on it.
311    static final int BROADCAST_FG_TIMEOUT = 10*1000;
312    static final int BROADCAST_BG_TIMEOUT = 60*1000;
313
314    // How long we wait until we timeout on key dispatching.
315    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
316
317    // How long we wait until we timeout on key dispatching during instrumentation.
318    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
319
320    // Amount of time we wait for observers to handle a user switch before
321    // giving up on them and unfreezing the screen.
322    static final int USER_SWITCH_TIMEOUT = 2*1000;
323
324    // Maximum number of users we allow to be running at a time.
325    static final int MAX_RUNNING_USERS = 3;
326
327    // How long to wait in getAssistContextExtras for the activity and foreground services
328    // to respond with the result.
329    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
330
331    // Maximum number of persisted Uri grants a package is allowed
332    static final int MAX_PERSISTED_URI_GRANTS = 128;
333
334    static final int MY_PID = Process.myPid();
335
336    static final String[] EMPTY_STRING_ARRAY = new String[0];
337
338    // How many bytes to write into the dropbox log before truncating
339    static final int DROPBOX_MAX_SIZE = 256 * 1024;
340
341    /** All system services */
342    SystemServiceManager mSystemServiceManager;
343
344    /** Run all ActivityStacks through this */
345    ActivityStackSupervisor mStackSupervisor;
346
347    public IntentFirewall mIntentFirewall;
348
349    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
350    // default actuion automatically.  Important for devices without direct input
351    // devices.
352    private boolean mShowDialogs = true;
353
354    /**
355     * Description of a request to start a new activity, which has been held
356     * due to app switches being disabled.
357     */
358    static class PendingActivityLaunch {
359        final ActivityRecord r;
360        final ActivityRecord sourceRecord;
361        final int startFlags;
362        final ActivityStack stack;
363
364        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
365                int _startFlags, ActivityStack _stack) {
366            r = _r;
367            sourceRecord = _sourceRecord;
368            startFlags = _startFlags;
369            stack = _stack;
370        }
371    }
372
373    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
374            = new ArrayList<PendingActivityLaunch>();
375
376    BroadcastQueue mFgBroadcastQueue;
377    BroadcastQueue mBgBroadcastQueue;
378    // Convenient for easy iteration over the queues. Foreground is first
379    // so that dispatch of foreground broadcasts gets precedence.
380    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
381
382    BroadcastQueue broadcastQueueForIntent(Intent intent) {
383        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
384        if (DEBUG_BACKGROUND_BROADCAST) {
385            Slog.i(TAG, "Broadcast intent " + intent + " on "
386                    + (isFg ? "foreground" : "background")
387                    + " queue");
388        }
389        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
390    }
391
392    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
393        for (BroadcastQueue queue : mBroadcastQueues) {
394            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
395            if (r != null) {
396                return r;
397            }
398        }
399        return null;
400    }
401
402    /**
403     * Activity we have told the window manager to have key focus.
404     */
405    ActivityRecord mFocusedActivity = null;
406
407    /**
408     * List of intents that were used to start the most recent tasks.
409     */
410    final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
411
412    public class PendingAssistExtras extends Binder implements Runnable {
413        public final ActivityRecord activity;
414        public boolean haveResult = false;
415        public Bundle result = null;
416        public PendingAssistExtras(ActivityRecord _activity) {
417            activity = _activity;
418        }
419        @Override
420        public void run() {
421            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
422            synchronized (this) {
423                haveResult = true;
424                notifyAll();
425            }
426        }
427    }
428
429    final ArrayList<PendingAssistExtras> mPendingAssistExtras
430            = new ArrayList<PendingAssistExtras>();
431
432    /**
433     * Process management.
434     */
435    final ProcessList mProcessList = new ProcessList();
436
437    /**
438     * All of the applications we currently have running organized by name.
439     * The keys are strings of the application package name (as
440     * returned by the package manager), and the keys are ApplicationRecord
441     * objects.
442     */
443    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
444
445    /**
446     * Tracking long-term execution of processes to look for abuse and other
447     * bad app behavior.
448     */
449    final ProcessStatsService mProcessStats;
450
451    /**
452     * The currently running isolated processes.
453     */
454    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
455
456    /**
457     * Counter for assigning isolated process uids, to avoid frequently reusing the
458     * same ones.
459     */
460    int mNextIsolatedProcessUid = 0;
461
462    /**
463     * The currently running heavy-weight process, if any.
464     */
465    ProcessRecord mHeavyWeightProcess = null;
466
467    /**
468     * The last time that various processes have crashed.
469     */
470    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
471
472    /**
473     * Information about a process that is currently marked as bad.
474     */
475    static final class BadProcessInfo {
476        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
477            this.time = time;
478            this.shortMsg = shortMsg;
479            this.longMsg = longMsg;
480            this.stack = stack;
481        }
482
483        final long time;
484        final String shortMsg;
485        final String longMsg;
486        final String stack;
487    }
488
489    /**
490     * Set of applications that we consider to be bad, and will reject
491     * incoming broadcasts from (which the user has no control over).
492     * Processes are added to this set when they have crashed twice within
493     * a minimum amount of time; they are removed from it when they are
494     * later restarted (hopefully due to some user action).  The value is the
495     * time it was added to the list.
496     */
497    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
498
499    /**
500     * All of the processes we currently have running organized by pid.
501     * The keys are the pid running the application.
502     *
503     * <p>NOTE: This object is protected by its own lock, NOT the global
504     * activity manager lock!
505     */
506    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
507
508    /**
509     * All of the processes that have been forced to be foreground.  The key
510     * is the pid of the caller who requested it (we hold a death
511     * link on it).
512     */
513    abstract class ForegroundToken implements IBinder.DeathRecipient {
514        int pid;
515        IBinder token;
516    }
517    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
518
519    /**
520     * List of records for processes that someone had tried to start before the
521     * system was ready.  We don't start them at that point, but ensure they
522     * are started by the time booting is complete.
523     */
524    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
525
526    /**
527     * List of persistent applications that are in the process
528     * of being started.
529     */
530    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
531
532    /**
533     * Processes that are being forcibly torn down.
534     */
535    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
536
537    /**
538     * List of running applications, sorted by recent usage.
539     * The first entry in the list is the least recently used.
540     */
541    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
542
543    /**
544     * Where in mLruProcesses that the processes hosting activities start.
545     */
546    int mLruProcessActivityStart = 0;
547
548    /**
549     * Where in mLruProcesses that the processes hosting services start.
550     * This is after (lower index) than mLruProcessesActivityStart.
551     */
552    int mLruProcessServiceStart = 0;
553
554    /**
555     * List of processes that should gc as soon as things are idle.
556     */
557    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
558
559    /**
560     * Processes we want to collect PSS data from.
561     */
562    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
563
564    /**
565     * Last time we requested PSS data of all processes.
566     */
567    long mLastFullPssTime = SystemClock.uptimeMillis();
568
569    /**
570     * This is the process holding what we currently consider to be
571     * the "home" activity.
572     */
573    ProcessRecord mHomeProcess;
574
575    /**
576     * This is the process holding the activity the user last visited that
577     * is in a different process from the one they are currently in.
578     */
579    ProcessRecord mPreviousProcess;
580
581    /**
582     * The time at which the previous process was last visible.
583     */
584    long mPreviousProcessVisibleTime;
585
586    /**
587     * Which uses have been started, so are allowed to run code.
588     */
589    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
590
591    /**
592     * LRU list of history of current users.  Most recently current is at the end.
593     */
594    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
595
596    /**
597     * Constant array of the users that are currently started.
598     */
599    int[] mStartedUserArray = new int[] { 0 };
600
601    /**
602     * Registered observers of the user switching mechanics.
603     */
604    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
605            = new RemoteCallbackList<IUserSwitchObserver>();
606
607    /**
608     * Currently active user switch.
609     */
610    Object mCurUserSwitchCallback;
611
612    /**
613     * Packages that the user has asked to have run in screen size
614     * compatibility mode instead of filling the screen.
615     */
616    final CompatModePackages mCompatModePackages;
617
618    /**
619     * Set of IntentSenderRecord objects that are currently active.
620     */
621    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
622            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
623
624    /**
625     * Fingerprints (hashCode()) of stack traces that we've
626     * already logged DropBox entries for.  Guarded by itself.  If
627     * something (rogue user app) forces this over
628     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
629     */
630    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
631    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
632
633    /**
634     * Strict Mode background batched logging state.
635     *
636     * The string buffer is guarded by itself, and its lock is also
637     * used to determine if another batched write is already
638     * in-flight.
639     */
640    private final StringBuilder mStrictModeBuffer = new StringBuilder();
641
642    /**
643     * Keeps track of all IIntentReceivers that have been registered for
644     * broadcasts.  Hash keys are the receiver IBinder, hash value is
645     * a ReceiverList.
646     */
647    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
648            new HashMap<IBinder, ReceiverList>();
649
650    /**
651     * Resolver for broadcast intents to registered receivers.
652     * Holds BroadcastFilter (subclass of IntentFilter).
653     */
654    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
655            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
656        @Override
657        protected boolean allowFilterResult(
658                BroadcastFilter filter, List<BroadcastFilter> dest) {
659            IBinder target = filter.receiverList.receiver.asBinder();
660            for (int i=dest.size()-1; i>=0; i--) {
661                if (dest.get(i).receiverList.receiver.asBinder() == target) {
662                    return false;
663                }
664            }
665            return true;
666        }
667
668        @Override
669        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
670            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
671                    || userId == filter.owningUserId) {
672                return super.newResult(filter, match, userId);
673            }
674            return null;
675        }
676
677        @Override
678        protected BroadcastFilter[] newArray(int size) {
679            return new BroadcastFilter[size];
680        }
681
682        @Override
683        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
684            return packageName.equals(filter.packageName);
685        }
686    };
687
688    /**
689     * State of all active sticky broadcasts per user.  Keys are the action of the
690     * sticky Intent, values are an ArrayList of all broadcasted intents with
691     * that action (which should usually be one).  The SparseArray is keyed
692     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
693     * for stickies that are sent to all users.
694     */
695    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
696            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
697
698    final ActiveServices mServices;
699
700    /**
701     * Backup/restore process management
702     */
703    String mBackupAppName = null;
704    BackupRecord mBackupTarget = null;
705
706    final ProviderMap mProviderMap;
707
708    /**
709     * List of content providers who have clients waiting for them.  The
710     * application is currently being launched and the provider will be
711     * removed from this list once it is published.
712     */
713    final ArrayList<ContentProviderRecord> mLaunchingProviders
714            = new ArrayList<ContentProviderRecord>();
715
716    /**
717     * File storing persisted {@link #mGrantedUriPermissions}.
718     */
719    private final AtomicFile mGrantFile;
720
721    /** XML constants used in {@link #mGrantFile} */
722    private static final String TAG_URI_GRANTS = "uri-grants";
723    private static final String TAG_URI_GRANT = "uri-grant";
724    private static final String ATTR_USER_HANDLE = "userHandle";
725    private static final String ATTR_SOURCE_PKG = "sourcePkg";
726    private static final String ATTR_TARGET_PKG = "targetPkg";
727    private static final String ATTR_URI = "uri";
728    private static final String ATTR_MODE_FLAGS = "modeFlags";
729    private static final String ATTR_CREATED_TIME = "createdTime";
730    private static final String ATTR_PREFIX = "prefix";
731
732    /**
733     * Global set of specific {@link Uri} permissions that have been granted.
734     * This optimized lookup structure maps from {@link UriPermission#targetUid}
735     * to {@link UriPermission#uri} to {@link UriPermission}.
736     */
737    @GuardedBy("this")
738    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
739            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
740
741    public static class GrantUri {
742        public final Uri uri;
743        public final boolean prefix;
744
745        public GrantUri(Uri uri, boolean prefix) {
746            this.uri = uri;
747            this.prefix = prefix;
748        }
749
750        @Override
751        public int hashCode() {
752            return toString().hashCode();
753        }
754
755        @Override
756        public boolean equals(Object o) {
757            if (o instanceof GrantUri) {
758                GrantUri other = (GrantUri) o;
759                return uri.equals(other.uri) && prefix == other.prefix;
760            }
761            return false;
762        }
763
764        @Override
765        public String toString() {
766            if (prefix) {
767                return uri.toString() + " [prefix]";
768            } else {
769                return uri.toString();
770            }
771        }
772    }
773
774    CoreSettingsObserver mCoreSettingsObserver;
775
776    /**
777     * Thread-local storage used to carry caller permissions over through
778     * indirect content-provider access.
779     */
780    private class Identity {
781        public int pid;
782        public int uid;
783
784        Identity(int _pid, int _uid) {
785            pid = _pid;
786            uid = _uid;
787        }
788    }
789
790    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
791
792    /**
793     * All information we have collected about the runtime performance of
794     * any user id that can impact battery performance.
795     */
796    final BatteryStatsService mBatteryStatsService;
797
798    /**
799     * Information about component usage
800     */
801    final UsageStatsService mUsageStatsService;
802
803    /**
804     * Information about and control over application operations
805     */
806    final AppOpsService mAppOpsService;
807
808    /**
809     * Current configuration information.  HistoryRecord objects are given
810     * a reference to this object to indicate which configuration they are
811     * currently running in, so this object must be kept immutable.
812     */
813    Configuration mConfiguration = new Configuration();
814
815    /**
816     * Current sequencing integer of the configuration, for skipping old
817     * configurations.
818     */
819    int mConfigurationSeq = 0;
820
821    /**
822     * Hardware-reported OpenGLES version.
823     */
824    final int GL_ES_VERSION;
825
826    /**
827     * List of initialization arguments to pass to all processes when binding applications to them.
828     * For example, references to the commonly used services.
829     */
830    HashMap<String, IBinder> mAppBindArgs;
831
832    /**
833     * Temporary to avoid allocations.  Protected by main lock.
834     */
835    final StringBuilder mStringBuilder = new StringBuilder(256);
836
837    /**
838     * Used to control how we initialize the service.
839     */
840    ComponentName mTopComponent;
841    String mTopAction = Intent.ACTION_MAIN;
842    String mTopData;
843    boolean mProcessesReady = false;
844    boolean mSystemReady = false;
845    boolean mBooting = false;
846    boolean mWaitingUpdate = false;
847    boolean mDidUpdate = false;
848    boolean mOnBattery = false;
849    boolean mLaunchWarningShown = false;
850
851    Context mContext;
852
853    int mFactoryTest;
854
855    boolean mCheckedForSetup;
856
857    /**
858     * The time at which we will allow normal application switches again,
859     * after a call to {@link #stopAppSwitches()}.
860     */
861    long mAppSwitchesAllowedTime;
862
863    /**
864     * This is set to true after the first switch after mAppSwitchesAllowedTime
865     * is set; any switches after that will clear the time.
866     */
867    boolean mDidAppSwitch;
868
869    /**
870     * Last time (in realtime) at which we checked for power usage.
871     */
872    long mLastPowerCheckRealtime;
873
874    /**
875     * Last time (in uptime) at which we checked for power usage.
876     */
877    long mLastPowerCheckUptime;
878
879    /**
880     * Set while we are wanting to sleep, to prevent any
881     * activities from being started/resumed.
882     */
883    private boolean mSleeping = false;
884
885    /**
886     * Set while we are running a voice interaction.  This overrides
887     * sleeping while it is active.
888     */
889    private boolean mRunningVoice = false;
890
891    /**
892     * State of external calls telling us if the device is asleep.
893     */
894    private boolean mWentToSleep = false;
895
896    /**
897     * State of external call telling us if the lock screen is shown.
898     */
899    private boolean mLockScreenShown = false;
900
901    /**
902     * Set if we are shutting down the system, similar to sleeping.
903     */
904    boolean mShuttingDown = false;
905
906    /**
907     * Current sequence id for oom_adj computation traversal.
908     */
909    int mAdjSeq = 0;
910
911    /**
912     * Current sequence id for process LRU updating.
913     */
914    int mLruSeq = 0;
915
916    /**
917     * Keep track of the non-cached/empty process we last found, to help
918     * determine how to distribute cached/empty processes next time.
919     */
920    int mNumNonCachedProcs = 0;
921
922    /**
923     * Keep track of the number of cached hidden procs, to balance oom adj
924     * distribution between those and empty procs.
925     */
926    int mNumCachedHiddenProcs = 0;
927
928    /**
929     * Keep track of the number of service processes we last found, to
930     * determine on the next iteration which should be B services.
931     */
932    int mNumServiceProcs = 0;
933    int mNewNumAServiceProcs = 0;
934    int mNewNumServiceProcs = 0;
935
936    /**
937     * Allow the current computed overall memory level of the system to go down?
938     * This is set to false when we are killing processes for reasons other than
939     * memory management, so that the now smaller process list will not be taken as
940     * an indication that memory is tighter.
941     */
942    boolean mAllowLowerMemLevel = false;
943
944    /**
945     * The last computed memory level, for holding when we are in a state that
946     * processes are going away for other reasons.
947     */
948    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
949
950    /**
951     * The last total number of process we have, to determine if changes actually look
952     * like a shrinking number of process due to lower RAM.
953     */
954    int mLastNumProcesses;
955
956    /**
957     * The uptime of the last time we performed idle maintenance.
958     */
959    long mLastIdleTime = SystemClock.uptimeMillis();
960
961    /**
962     * Total time spent with RAM that has been added in the past since the last idle time.
963     */
964    long mLowRamTimeSinceLastIdle = 0;
965
966    /**
967     * If RAM is currently low, when that horrible situation started.
968     */
969    long mLowRamStartTime = 0;
970
971    /**
972     * For reporting to battery stats the current top application.
973     */
974    private String mCurResumedPackage = null;
975    private int mCurResumedUid = -1;
976
977    /**
978     * For reporting to battery stats the apps currently running foreground
979     * service.  The ProcessMap is package/uid tuples; each of these contain
980     * an array of the currently foreground processes.
981     */
982    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
983            = new ProcessMap<ArrayList<ProcessRecord>>();
984
985    /**
986     * This is set if we had to do a delayed dexopt of an app before launching
987     * it, to increasing the ANR timeouts in that case.
988     */
989    boolean mDidDexOpt;
990
991    /**
992     * Set if the systemServer made a call to enterSafeMode.
993     */
994    boolean mSafeMode;
995
996    String mDebugApp = null;
997    boolean mWaitForDebugger = false;
998    boolean mDebugTransient = false;
999    String mOrigDebugApp = null;
1000    boolean mOrigWaitForDebugger = false;
1001    boolean mAlwaysFinishActivities = false;
1002    IActivityController mController = null;
1003    String mProfileApp = null;
1004    ProcessRecord mProfileProc = null;
1005    String mProfileFile;
1006    ParcelFileDescriptor mProfileFd;
1007    int mProfileType = 0;
1008    boolean mAutoStopProfiler = false;
1009    String mOpenGlTraceApp = null;
1010
1011    static class ProcessChangeItem {
1012        static final int CHANGE_ACTIVITIES = 1<<0;
1013        static final int CHANGE_PROCESS_STATE = 1<<1;
1014        int changes;
1015        int uid;
1016        int pid;
1017        int processState;
1018        boolean foregroundActivities;
1019    }
1020
1021    final RemoteCallbackList<IProcessObserver> mProcessObservers
1022            = new RemoteCallbackList<IProcessObserver>();
1023    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1024
1025    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1026            = new ArrayList<ProcessChangeItem>();
1027    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1028            = new ArrayList<ProcessChangeItem>();
1029
1030    /**
1031     * Runtime CPU use collection thread.  This object's lock is used to
1032     * protect all related state.
1033     */
1034    final Thread mProcessCpuThread;
1035
1036    /**
1037     * Used to collect process stats when showing not responding dialog.
1038     * Protected by mProcessCpuThread.
1039     */
1040    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1041            MONITOR_THREAD_CPU_USAGE);
1042    final AtomicLong mLastCpuTime = new AtomicLong(0);
1043    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1044
1045    long mLastWriteTime = 0;
1046
1047    /**
1048     * Used to retain an update lock when the foreground activity is in
1049     * immersive mode.
1050     */
1051    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1052
1053    /**
1054     * Set to true after the system has finished booting.
1055     */
1056    boolean mBooted = false;
1057
1058    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1059    int mProcessLimitOverride = -1;
1060
1061    WindowManagerService mWindowManager;
1062
1063    final ActivityThread mSystemThread;
1064
1065    int mCurrentUserId = 0;
1066    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1067    private UserManagerService mUserManager;
1068
1069    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1070        final ProcessRecord mApp;
1071        final int mPid;
1072        final IApplicationThread mAppThread;
1073
1074        AppDeathRecipient(ProcessRecord app, int pid,
1075                IApplicationThread thread) {
1076            if (localLOGV) Slog.v(
1077                TAG, "New death recipient " + this
1078                + " for thread " + thread.asBinder());
1079            mApp = app;
1080            mPid = pid;
1081            mAppThread = thread;
1082        }
1083
1084        @Override
1085        public void binderDied() {
1086            if (localLOGV) Slog.v(
1087                TAG, "Death received in " + this
1088                + " for thread " + mAppThread.asBinder());
1089            synchronized(ActivityManagerService.this) {
1090                appDiedLocked(mApp, mPid, mAppThread);
1091            }
1092        }
1093    }
1094
1095    static final int SHOW_ERROR_MSG = 1;
1096    static final int SHOW_NOT_RESPONDING_MSG = 2;
1097    static final int SHOW_FACTORY_ERROR_MSG = 3;
1098    static final int UPDATE_CONFIGURATION_MSG = 4;
1099    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1100    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1101    static final int SERVICE_TIMEOUT_MSG = 12;
1102    static final int UPDATE_TIME_ZONE = 13;
1103    static final int SHOW_UID_ERROR_MSG = 14;
1104    static final int IM_FEELING_LUCKY_MSG = 15;
1105    static final int PROC_START_TIMEOUT_MSG = 20;
1106    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1107    static final int KILL_APPLICATION_MSG = 22;
1108    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1109    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1110    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1111    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1112    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1113    static final int CLEAR_DNS_CACHE_MSG = 28;
1114    static final int UPDATE_HTTP_PROXY_MSG = 29;
1115    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1116    static final int DISPATCH_PROCESSES_CHANGED = 31;
1117    static final int DISPATCH_PROCESS_DIED = 32;
1118    static final int REPORT_MEM_USAGE_MSG = 33;
1119    static final int REPORT_USER_SWITCH_MSG = 34;
1120    static final int CONTINUE_USER_SWITCH_MSG = 35;
1121    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1122    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1123    static final int PERSIST_URI_GRANTS_MSG = 38;
1124    static final int REQUEST_ALL_PSS_MSG = 39;
1125    static final int START_PROFILES_MSG = 40;
1126    static final int UPDATE_TIME = 41;
1127    static final int SYSTEM_USER_START_MSG = 42;
1128    static final int SYSTEM_USER_CURRENT_MSG = 43;
1129
1130    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1131    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1132    static final int FIRST_COMPAT_MODE_MSG = 300;
1133    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1134
1135    AlertDialog mUidAlert;
1136    CompatModeDialog mCompatModeDialog;
1137    long mLastMemUsageReportTime = 0;
1138
1139    /**
1140     * Flag whether the current user is a "monkey", i.e. whether
1141     * the UI is driven by a UI automation tool.
1142     */
1143    private boolean mUserIsMonkey;
1144
1145    final ServiceThread mHandlerThread;
1146    final MainHandler mHandler;
1147
1148    final class MainHandler extends Handler {
1149        public MainHandler(Looper looper) {
1150            super(looper, null, true);
1151        }
1152
1153        @Override
1154        public void handleMessage(Message msg) {
1155            switch (msg.what) {
1156            case SHOW_ERROR_MSG: {
1157                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1158                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1159                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1160                synchronized (ActivityManagerService.this) {
1161                    ProcessRecord proc = (ProcessRecord)data.get("app");
1162                    AppErrorResult res = (AppErrorResult) data.get("result");
1163                    if (proc != null && proc.crashDialog != null) {
1164                        Slog.e(TAG, "App already has crash dialog: " + proc);
1165                        if (res != null) {
1166                            res.set(0);
1167                        }
1168                        return;
1169                    }
1170                    if (!showBackground && UserHandle.getAppId(proc.uid)
1171                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1172                            && proc.pid != MY_PID) {
1173                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1174                        if (res != null) {
1175                            res.set(0);
1176                        }
1177                        return;
1178                    }
1179                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1180                        Dialog d = new AppErrorDialog(mContext,
1181                                ActivityManagerService.this, res, proc);
1182                        d.show();
1183                        proc.crashDialog = d;
1184                    } else {
1185                        // The device is asleep, so just pretend that the user
1186                        // saw a crash dialog and hit "force quit".
1187                        if (res != null) {
1188                            res.set(0);
1189                        }
1190                    }
1191                }
1192
1193                ensureBootCompleted();
1194            } break;
1195            case SHOW_NOT_RESPONDING_MSG: {
1196                synchronized (ActivityManagerService.this) {
1197                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1198                    ProcessRecord proc = (ProcessRecord)data.get("app");
1199                    if (proc != null && proc.anrDialog != null) {
1200                        Slog.e(TAG, "App already has anr dialog: " + proc);
1201                        return;
1202                    }
1203
1204                    Intent intent = new Intent("android.intent.action.ANR");
1205                    if (!mProcessesReady) {
1206                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1207                                | Intent.FLAG_RECEIVER_FOREGROUND);
1208                    }
1209                    broadcastIntentLocked(null, null, intent,
1210                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1211                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1212
1213                    if (mShowDialogs) {
1214                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1215                                mContext, proc, (ActivityRecord)data.get("activity"),
1216                                msg.arg1 != 0);
1217                        d.show();
1218                        proc.anrDialog = d;
1219                    } else {
1220                        // Just kill the app if there is no dialog to be shown.
1221                        killAppAtUsersRequest(proc, null);
1222                    }
1223                }
1224
1225                ensureBootCompleted();
1226            } break;
1227            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1228                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1229                synchronized (ActivityManagerService.this) {
1230                    ProcessRecord proc = (ProcessRecord) data.get("app");
1231                    if (proc == null) {
1232                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1233                        break;
1234                    }
1235                    if (proc.crashDialog != null) {
1236                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1237                        return;
1238                    }
1239                    AppErrorResult res = (AppErrorResult) data.get("result");
1240                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1241                        Dialog d = new StrictModeViolationDialog(mContext,
1242                                ActivityManagerService.this, res, proc);
1243                        d.show();
1244                        proc.crashDialog = d;
1245                    } else {
1246                        // The device is asleep, so just pretend that the user
1247                        // saw a crash dialog and hit "force quit".
1248                        res.set(0);
1249                    }
1250                }
1251                ensureBootCompleted();
1252            } break;
1253            case SHOW_FACTORY_ERROR_MSG: {
1254                Dialog d = new FactoryErrorDialog(
1255                    mContext, msg.getData().getCharSequence("msg"));
1256                d.show();
1257                ensureBootCompleted();
1258            } break;
1259            case UPDATE_CONFIGURATION_MSG: {
1260                final ContentResolver resolver = mContext.getContentResolver();
1261                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1262            } break;
1263            case GC_BACKGROUND_PROCESSES_MSG: {
1264                synchronized (ActivityManagerService.this) {
1265                    performAppGcsIfAppropriateLocked();
1266                }
1267            } break;
1268            case WAIT_FOR_DEBUGGER_MSG: {
1269                synchronized (ActivityManagerService.this) {
1270                    ProcessRecord app = (ProcessRecord)msg.obj;
1271                    if (msg.arg1 != 0) {
1272                        if (!app.waitedForDebugger) {
1273                            Dialog d = new AppWaitingForDebuggerDialog(
1274                                    ActivityManagerService.this,
1275                                    mContext, app);
1276                            app.waitDialog = d;
1277                            app.waitedForDebugger = true;
1278                            d.show();
1279                        }
1280                    } else {
1281                        if (app.waitDialog != null) {
1282                            app.waitDialog.dismiss();
1283                            app.waitDialog = null;
1284                        }
1285                    }
1286                }
1287            } break;
1288            case SERVICE_TIMEOUT_MSG: {
1289                if (mDidDexOpt) {
1290                    mDidDexOpt = false;
1291                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1292                    nmsg.obj = msg.obj;
1293                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1294                    return;
1295                }
1296                mServices.serviceTimeout((ProcessRecord)msg.obj);
1297            } break;
1298            case UPDATE_TIME_ZONE: {
1299                synchronized (ActivityManagerService.this) {
1300                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1301                        ProcessRecord r = mLruProcesses.get(i);
1302                        if (r.thread != null) {
1303                            try {
1304                                r.thread.updateTimeZone();
1305                            } catch (RemoteException ex) {
1306                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1307                            }
1308                        }
1309                    }
1310                }
1311            } break;
1312            case CLEAR_DNS_CACHE_MSG: {
1313                synchronized (ActivityManagerService.this) {
1314                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1315                        ProcessRecord r = mLruProcesses.get(i);
1316                        if (r.thread != null) {
1317                            try {
1318                                r.thread.clearDnsCache();
1319                            } catch (RemoteException ex) {
1320                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1321                            }
1322                        }
1323                    }
1324                }
1325            } break;
1326            case UPDATE_HTTP_PROXY_MSG: {
1327                ProxyProperties proxy = (ProxyProperties)msg.obj;
1328                String host = "";
1329                String port = "";
1330                String exclList = "";
1331                String pacFileUrl = null;
1332                if (proxy != null) {
1333                    host = proxy.getHost();
1334                    port = Integer.toString(proxy.getPort());
1335                    exclList = proxy.getExclusionList();
1336                    pacFileUrl = proxy.getPacFileUrl();
1337                }
1338                synchronized (ActivityManagerService.this) {
1339                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1340                        ProcessRecord r = mLruProcesses.get(i);
1341                        if (r.thread != null) {
1342                            try {
1343                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1344                            } catch (RemoteException ex) {
1345                                Slog.w(TAG, "Failed to update http proxy for: " +
1346                                        r.info.processName);
1347                            }
1348                        }
1349                    }
1350                }
1351            } break;
1352            case SHOW_UID_ERROR_MSG: {
1353                String title = "System UIDs Inconsistent";
1354                String text = "UIDs on the system are inconsistent, you need to wipe your"
1355                        + " data partition or your device will be unstable.";
1356                Log.e(TAG, title + ": " + text);
1357                if (mShowDialogs) {
1358                    // XXX This is a temporary dialog, no need to localize.
1359                    AlertDialog d = new BaseErrorDialog(mContext);
1360                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1361                    d.setCancelable(false);
1362                    d.setTitle(title);
1363                    d.setMessage(text);
1364                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1365                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1366                    mUidAlert = d;
1367                    d.show();
1368                }
1369            } break;
1370            case IM_FEELING_LUCKY_MSG: {
1371                if (mUidAlert != null) {
1372                    mUidAlert.dismiss();
1373                    mUidAlert = null;
1374                }
1375            } break;
1376            case PROC_START_TIMEOUT_MSG: {
1377                if (mDidDexOpt) {
1378                    mDidDexOpt = false;
1379                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1380                    nmsg.obj = msg.obj;
1381                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1382                    return;
1383                }
1384                ProcessRecord app = (ProcessRecord)msg.obj;
1385                synchronized (ActivityManagerService.this) {
1386                    processStartTimedOutLocked(app);
1387                }
1388            } break;
1389            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1390                synchronized (ActivityManagerService.this) {
1391                    doPendingActivityLaunchesLocked(true);
1392                }
1393            } break;
1394            case KILL_APPLICATION_MSG: {
1395                synchronized (ActivityManagerService.this) {
1396                    int appid = msg.arg1;
1397                    boolean restart = (msg.arg2 == 1);
1398                    Bundle bundle = (Bundle)msg.obj;
1399                    String pkg = bundle.getString("pkg");
1400                    String reason = bundle.getString("reason");
1401                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1402                            false, UserHandle.USER_ALL, reason);
1403                }
1404            } break;
1405            case FINALIZE_PENDING_INTENT_MSG: {
1406                ((PendingIntentRecord)msg.obj).completeFinalize();
1407            } break;
1408            case POST_HEAVY_NOTIFICATION_MSG: {
1409                INotificationManager inm = NotificationManager.getService();
1410                if (inm == null) {
1411                    return;
1412                }
1413
1414                ActivityRecord root = (ActivityRecord)msg.obj;
1415                ProcessRecord process = root.app;
1416                if (process == null) {
1417                    return;
1418                }
1419
1420                try {
1421                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1422                    String text = mContext.getString(R.string.heavy_weight_notification,
1423                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1424                    Notification notification = new Notification();
1425                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1426                    notification.when = 0;
1427                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1428                    notification.tickerText = text;
1429                    notification.defaults = 0; // please be quiet
1430                    notification.sound = null;
1431                    notification.vibrate = null;
1432                    notification.setLatestEventInfo(context, text,
1433                            mContext.getText(R.string.heavy_weight_notification_detail),
1434                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1435                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1436                                    new UserHandle(root.userId)));
1437
1438                    try {
1439                        int[] outId = new int[1];
1440                        inm.enqueueNotificationWithTag("android", "android", null,
1441                                R.string.heavy_weight_notification,
1442                                notification, outId, root.userId);
1443                    } catch (RuntimeException e) {
1444                        Slog.w(ActivityManagerService.TAG,
1445                                "Error showing notification for heavy-weight app", e);
1446                    } catch (RemoteException e) {
1447                    }
1448                } catch (NameNotFoundException e) {
1449                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1450                }
1451            } break;
1452            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1453                INotificationManager inm = NotificationManager.getService();
1454                if (inm == null) {
1455                    return;
1456                }
1457                try {
1458                    inm.cancelNotificationWithTag("android", null,
1459                            R.string.heavy_weight_notification,  msg.arg1);
1460                } catch (RuntimeException e) {
1461                    Slog.w(ActivityManagerService.TAG,
1462                            "Error canceling notification for service", e);
1463                } catch (RemoteException e) {
1464                }
1465            } break;
1466            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1467                synchronized (ActivityManagerService.this) {
1468                    checkExcessivePowerUsageLocked(true);
1469                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1470                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1471                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1472                }
1473            } break;
1474            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1475                synchronized (ActivityManagerService.this) {
1476                    ActivityRecord ar = (ActivityRecord)msg.obj;
1477                    if (mCompatModeDialog != null) {
1478                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1479                                ar.info.applicationInfo.packageName)) {
1480                            return;
1481                        }
1482                        mCompatModeDialog.dismiss();
1483                        mCompatModeDialog = null;
1484                    }
1485                    if (ar != null && false) {
1486                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1487                                ar.packageName)) {
1488                            int mode = mCompatModePackages.computeCompatModeLocked(
1489                                    ar.info.applicationInfo);
1490                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1491                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1492                                mCompatModeDialog = new CompatModeDialog(
1493                                        ActivityManagerService.this, mContext,
1494                                        ar.info.applicationInfo);
1495                                mCompatModeDialog.show();
1496                            }
1497                        }
1498                    }
1499                }
1500                break;
1501            }
1502            case DISPATCH_PROCESSES_CHANGED: {
1503                dispatchProcessesChanged();
1504                break;
1505            }
1506            case DISPATCH_PROCESS_DIED: {
1507                final int pid = msg.arg1;
1508                final int uid = msg.arg2;
1509                dispatchProcessDied(pid, uid);
1510                break;
1511            }
1512            case REPORT_MEM_USAGE_MSG: {
1513                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1514                Thread thread = new Thread() {
1515                    @Override public void run() {
1516                        final SparseArray<ProcessMemInfo> infoMap
1517                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1518                        for (int i=0, N=memInfos.size(); i<N; i++) {
1519                            ProcessMemInfo mi = memInfos.get(i);
1520                            infoMap.put(mi.pid, mi);
1521                        }
1522                        updateCpuStatsNow();
1523                        synchronized (mProcessCpuThread) {
1524                            final int N = mProcessCpuTracker.countStats();
1525                            for (int i=0; i<N; i++) {
1526                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1527                                if (st.vsize > 0) {
1528                                    long pss = Debug.getPss(st.pid, null);
1529                                    if (pss > 0) {
1530                                        if (infoMap.indexOfKey(st.pid) < 0) {
1531                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1532                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1533                                            mi.pss = pss;
1534                                            memInfos.add(mi);
1535                                        }
1536                                    }
1537                                }
1538                            }
1539                        }
1540
1541                        long totalPss = 0;
1542                        for (int i=0, N=memInfos.size(); i<N; i++) {
1543                            ProcessMemInfo mi = memInfos.get(i);
1544                            if (mi.pss == 0) {
1545                                mi.pss = Debug.getPss(mi.pid, null);
1546                            }
1547                            totalPss += mi.pss;
1548                        }
1549                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1550                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1551                                if (lhs.oomAdj != rhs.oomAdj) {
1552                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1553                                }
1554                                if (lhs.pss != rhs.pss) {
1555                                    return lhs.pss < rhs.pss ? 1 : -1;
1556                                }
1557                                return 0;
1558                            }
1559                        });
1560
1561                        StringBuilder tag = new StringBuilder(128);
1562                        StringBuilder stack = new StringBuilder(128);
1563                        tag.append("Low on memory -- ");
1564                        appendMemBucket(tag, totalPss, "total", false);
1565                        appendMemBucket(stack, totalPss, "total", true);
1566
1567                        StringBuilder logBuilder = new StringBuilder(1024);
1568                        logBuilder.append("Low on memory:\n");
1569
1570                        boolean firstLine = true;
1571                        int lastOomAdj = Integer.MIN_VALUE;
1572                        for (int i=0, N=memInfos.size(); i<N; i++) {
1573                            ProcessMemInfo mi = memInfos.get(i);
1574
1575                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1576                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1577                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1578                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1579                                if (lastOomAdj != mi.oomAdj) {
1580                                    lastOomAdj = mi.oomAdj;
1581                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1582                                        tag.append(" / ");
1583                                    }
1584                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1585                                        if (firstLine) {
1586                                            stack.append(":");
1587                                            firstLine = false;
1588                                        }
1589                                        stack.append("\n\t at ");
1590                                    } else {
1591                                        stack.append("$");
1592                                    }
1593                                } else {
1594                                    tag.append(" ");
1595                                    stack.append("$");
1596                                }
1597                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1598                                    appendMemBucket(tag, mi.pss, mi.name, false);
1599                                }
1600                                appendMemBucket(stack, mi.pss, mi.name, true);
1601                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1602                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1603                                    stack.append("(");
1604                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1605                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1606                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1607                                            stack.append(":");
1608                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1609                                        }
1610                                    }
1611                                    stack.append(")");
1612                                }
1613                            }
1614
1615                            logBuilder.append("  ");
1616                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1617                            logBuilder.append(' ');
1618                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1619                            logBuilder.append(' ');
1620                            ProcessList.appendRamKb(logBuilder, mi.pss);
1621                            logBuilder.append(" kB: ");
1622                            logBuilder.append(mi.name);
1623                            logBuilder.append(" (");
1624                            logBuilder.append(mi.pid);
1625                            logBuilder.append(") ");
1626                            logBuilder.append(mi.adjType);
1627                            logBuilder.append('\n');
1628                            if (mi.adjReason != null) {
1629                                logBuilder.append("                      ");
1630                                logBuilder.append(mi.adjReason);
1631                                logBuilder.append('\n');
1632                            }
1633                        }
1634
1635                        logBuilder.append("           ");
1636                        ProcessList.appendRamKb(logBuilder, totalPss);
1637                        logBuilder.append(" kB: TOTAL\n");
1638
1639                        long[] infos = new long[Debug.MEMINFO_COUNT];
1640                        Debug.getMemInfo(infos);
1641                        logBuilder.append("  MemInfo: ");
1642                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1643                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1644                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1645                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1646                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1647                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1648                            logBuilder.append("  ZRAM: ");
1649                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1650                            logBuilder.append(" kB RAM, ");
1651                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1652                            logBuilder.append(" kB swap total, ");
1653                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1654                            logBuilder.append(" kB swap free\n");
1655                        }
1656                        Slog.i(TAG, logBuilder.toString());
1657
1658                        StringBuilder dropBuilder = new StringBuilder(1024);
1659                        /*
1660                        StringWriter oomSw = new StringWriter();
1661                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1662                        StringWriter catSw = new StringWriter();
1663                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1664                        String[] emptyArgs = new String[] { };
1665                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1666                        oomPw.flush();
1667                        String oomString = oomSw.toString();
1668                        */
1669                        dropBuilder.append(stack);
1670                        dropBuilder.append('\n');
1671                        dropBuilder.append('\n');
1672                        dropBuilder.append(logBuilder);
1673                        dropBuilder.append('\n');
1674                        /*
1675                        dropBuilder.append(oomString);
1676                        dropBuilder.append('\n');
1677                        */
1678                        StringWriter catSw = new StringWriter();
1679                        synchronized (ActivityManagerService.this) {
1680                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1681                            String[] emptyArgs = new String[] { };
1682                            catPw.println();
1683                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1684                            catPw.println();
1685                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1686                                    false, false, null);
1687                            catPw.println();
1688                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1689                            catPw.flush();
1690                        }
1691                        dropBuilder.append(catSw.toString());
1692                        addErrorToDropBox("lowmem", null, "system_server", null,
1693                                null, tag.toString(), dropBuilder.toString(), null, null);
1694                        //Slog.i(TAG, "Sent to dropbox:");
1695                        //Slog.i(TAG, dropBuilder.toString());
1696                        synchronized (ActivityManagerService.this) {
1697                            long now = SystemClock.uptimeMillis();
1698                            if (mLastMemUsageReportTime < now) {
1699                                mLastMemUsageReportTime = now;
1700                            }
1701                        }
1702                    }
1703                };
1704                thread.start();
1705                break;
1706            }
1707            case REPORT_USER_SWITCH_MSG: {
1708                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1709                break;
1710            }
1711            case CONTINUE_USER_SWITCH_MSG: {
1712                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1713                break;
1714            }
1715            case USER_SWITCH_TIMEOUT_MSG: {
1716                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1717                break;
1718            }
1719            case IMMERSIVE_MODE_LOCK_MSG: {
1720                final boolean nextState = (msg.arg1 != 0);
1721                if (mUpdateLock.isHeld() != nextState) {
1722                    if (DEBUG_IMMERSIVE) {
1723                        final ActivityRecord r = (ActivityRecord) msg.obj;
1724                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1725                    }
1726                    if (nextState) {
1727                        mUpdateLock.acquire();
1728                    } else {
1729                        mUpdateLock.release();
1730                    }
1731                }
1732                break;
1733            }
1734            case PERSIST_URI_GRANTS_MSG: {
1735                writeGrantedUriPermissions();
1736                break;
1737            }
1738            case REQUEST_ALL_PSS_MSG: {
1739                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1740                break;
1741            }
1742            case START_PROFILES_MSG: {
1743                synchronized (ActivityManagerService.this) {
1744                    startProfilesLocked();
1745                }
1746                break;
1747            }
1748            case UPDATE_TIME: {
1749                synchronized (ActivityManagerService.this) {
1750                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1751                        ProcessRecord r = mLruProcesses.get(i);
1752                        if (r.thread != null) {
1753                            try {
1754                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1755                            } catch (RemoteException ex) {
1756                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1757                            }
1758                        }
1759                    }
1760                }
1761                break;
1762            }
1763            case SYSTEM_USER_START_MSG: {
1764                mSystemServiceManager.startUser(msg.arg1);
1765                break;
1766            }
1767            case SYSTEM_USER_CURRENT_MSG: {
1768                mSystemServiceManager.switchUser(msg.arg1);
1769                break;
1770            }
1771            }
1772        }
1773    };
1774
1775    static final int COLLECT_PSS_BG_MSG = 1;
1776
1777    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1778        @Override
1779        public void handleMessage(Message msg) {
1780            switch (msg.what) {
1781            case COLLECT_PSS_BG_MSG: {
1782                int i=0, num=0;
1783                long start = SystemClock.uptimeMillis();
1784                long[] tmp = new long[1];
1785                do {
1786                    ProcessRecord proc;
1787                    int procState;
1788                    int pid;
1789                    synchronized (ActivityManagerService.this) {
1790                        if (i >= mPendingPssProcesses.size()) {
1791                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1792                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1793                            mPendingPssProcesses.clear();
1794                            return;
1795                        }
1796                        proc = mPendingPssProcesses.get(i);
1797                        procState = proc.pssProcState;
1798                        if (proc.thread != null && procState == proc.setProcState) {
1799                            pid = proc.pid;
1800                        } else {
1801                            proc = null;
1802                            pid = 0;
1803                        }
1804                        i++;
1805                    }
1806                    if (proc != null) {
1807                        long pss = Debug.getPss(pid, tmp);
1808                        synchronized (ActivityManagerService.this) {
1809                            if (proc.thread != null && proc.setProcState == procState
1810                                    && proc.pid == pid) {
1811                                num++;
1812                                proc.lastPssTime = SystemClock.uptimeMillis();
1813                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1814                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1815                                        + ": " + pss + " lastPss=" + proc.lastPss
1816                                        + " state=" + ProcessList.makeProcStateString(procState));
1817                                if (proc.initialIdlePss == 0) {
1818                                    proc.initialIdlePss = pss;
1819                                }
1820                                proc.lastPss = pss;
1821                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1822                                    proc.lastCachedPss = pss;
1823                                }
1824                            }
1825                        }
1826                    }
1827                } while (true);
1828            }
1829            }
1830        }
1831    };
1832
1833    /**
1834     * Monitor for package changes and update our internal state.
1835     */
1836    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1837        @Override
1838        public void onPackageRemoved(String packageName, int uid) {
1839            // Remove all tasks with activities in the specified package from the list of recent tasks
1840            synchronized (ActivityManagerService.this) {
1841                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1842                    TaskRecord tr = mRecentTasks.get(i);
1843                    ComponentName cn = tr.intent.getComponent();
1844                    if (cn != null && cn.getPackageName().equals(packageName)) {
1845                        // If the package name matches, remove the task and kill the process
1846                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1847                    }
1848                }
1849            }
1850        }
1851
1852        @Override
1853        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1854            final PackageManager pm = mContext.getPackageManager();
1855            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1856                    new ArrayList<Pair<Intent, Integer>>();
1857            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1858            // Copy the list of recent tasks so that we don't hold onto the lock on
1859            // ActivityManagerService for long periods while checking if components exist.
1860            synchronized (ActivityManagerService.this) {
1861                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1862                    TaskRecord tr = mRecentTasks.get(i);
1863                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1864                }
1865            }
1866            // Check the recent tasks and filter out all tasks with components that no longer exist.
1867            Intent tmpI = new Intent();
1868            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1869                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1870                ComponentName cn = p.first.getComponent();
1871                if (cn != null && cn.getPackageName().equals(packageName)) {
1872                    try {
1873                        // Add the task to the list to remove if the component no longer exists
1874                        tmpI.setComponent(cn);
1875                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1876                            tasksToRemove.add(p.second);
1877                        }
1878                    } catch (Exception e) {}
1879                }
1880            }
1881            // Prune all the tasks with removed components from the list of recent tasks
1882            synchronized (ActivityManagerService.this) {
1883                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1884                    // Remove the task but don't kill the process (since other components in that
1885                    // package may still be running and in the background)
1886                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1887                }
1888            }
1889            return true;
1890        }
1891
1892        @Override
1893        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1894            // Force stop the specified packages
1895            if (packages != null) {
1896                for (String pkg : packages) {
1897                    synchronized (ActivityManagerService.this) {
1898                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
1899                                "finished booting")) {
1900                            return true;
1901                        }
1902                    }
1903                }
1904            }
1905            return false;
1906        }
1907    };
1908
1909    public void setSystemProcess() {
1910        try {
1911            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1912            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1913            ServiceManager.addService("meminfo", new MemBinder(this));
1914            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1915            ServiceManager.addService("dbinfo", new DbBinder(this));
1916            if (MONITOR_CPU_USAGE) {
1917                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1918            }
1919            ServiceManager.addService("permission", new PermissionController(this));
1920
1921            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1922                    "android", STOCK_PM_FLAGS);
1923            mSystemThread.installSystemApplicationInfo(info);
1924
1925            synchronized (this) {
1926                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
1927                app.persistent = true;
1928                app.pid = MY_PID;
1929                app.maxAdj = ProcessList.SYSTEM_ADJ;
1930                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1931                mProcessNames.put(app.processName, app.uid, app);
1932                synchronized (mPidsSelfLocked) {
1933                    mPidsSelfLocked.put(app.pid, app);
1934                }
1935                updateLruProcessLocked(app, false, null);
1936                updateOomAdjLocked();
1937            }
1938        } catch (PackageManager.NameNotFoundException e) {
1939            throw new RuntimeException(
1940                    "Unable to find android system package", e);
1941        }
1942    }
1943
1944    public void setWindowManager(WindowManagerService wm) {
1945        mWindowManager = wm;
1946        mStackSupervisor.setWindowManager(wm);
1947    }
1948
1949    public void startObservingNativeCrashes() {
1950        final NativeCrashListener ncl = new NativeCrashListener(this);
1951        ncl.start();
1952    }
1953
1954    public IAppOpsService getAppOpsService() {
1955        return mAppOpsService;
1956    }
1957
1958    static class MemBinder extends Binder {
1959        ActivityManagerService mActivityManagerService;
1960        MemBinder(ActivityManagerService activityManagerService) {
1961            mActivityManagerService = activityManagerService;
1962        }
1963
1964        @Override
1965        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1966            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1967                    != PackageManager.PERMISSION_GRANTED) {
1968                pw.println("Permission Denial: can't dump meminfo from from pid="
1969                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1970                        + " without permission " + android.Manifest.permission.DUMP);
1971                return;
1972            }
1973
1974            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1975        }
1976    }
1977
1978    static class GraphicsBinder extends Binder {
1979        ActivityManagerService mActivityManagerService;
1980        GraphicsBinder(ActivityManagerService activityManagerService) {
1981            mActivityManagerService = activityManagerService;
1982        }
1983
1984        @Override
1985        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1986            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1987                    != PackageManager.PERMISSION_GRANTED) {
1988                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1989                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1990                        + " without permission " + android.Manifest.permission.DUMP);
1991                return;
1992            }
1993
1994            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1995        }
1996    }
1997
1998    static class DbBinder extends Binder {
1999        ActivityManagerService mActivityManagerService;
2000        DbBinder(ActivityManagerService activityManagerService) {
2001            mActivityManagerService = activityManagerService;
2002        }
2003
2004        @Override
2005        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2006            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2007                    != PackageManager.PERMISSION_GRANTED) {
2008                pw.println("Permission Denial: can't dump dbinfo from from pid="
2009                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2010                        + " without permission " + android.Manifest.permission.DUMP);
2011                return;
2012            }
2013
2014            mActivityManagerService.dumpDbInfo(fd, pw, args);
2015        }
2016    }
2017
2018    static class CpuBinder extends Binder {
2019        ActivityManagerService mActivityManagerService;
2020        CpuBinder(ActivityManagerService activityManagerService) {
2021            mActivityManagerService = activityManagerService;
2022        }
2023
2024        @Override
2025        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2026            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2027                    != PackageManager.PERMISSION_GRANTED) {
2028                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2029                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2030                        + " without permission " + android.Manifest.permission.DUMP);
2031                return;
2032            }
2033
2034            synchronized (mActivityManagerService.mProcessCpuThread) {
2035                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2036                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2037                        SystemClock.uptimeMillis()));
2038            }
2039        }
2040    }
2041
2042    public static final class Lifecycle extends SystemService {
2043        private final ActivityManagerService mService;
2044
2045        public Lifecycle(Context context) {
2046            super(context);
2047            mService = new ActivityManagerService(context);
2048        }
2049
2050        @Override
2051        public void onStart() {
2052            mService.start();
2053        }
2054
2055        public ActivityManagerService getService() {
2056            return mService;
2057        }
2058    }
2059
2060    // Note: This method is invoked on the main thread but may need to attach various
2061    // handlers to other threads.  So take care to be explicit about the looper.
2062    public ActivityManagerService(Context systemContext) {
2063        mContext = systemContext;
2064        mFactoryTest = FactoryTest.getMode();
2065        mSystemThread = ActivityThread.currentActivityThread();
2066
2067        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2068
2069        mHandlerThread = new ServiceThread(TAG,
2070                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2071        mHandlerThread.start();
2072        mHandler = new MainHandler(mHandlerThread.getLooper());
2073
2074        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2075                "foreground", BROADCAST_FG_TIMEOUT, false);
2076        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2077                "background", BROADCAST_BG_TIMEOUT, true);
2078        mBroadcastQueues[0] = mFgBroadcastQueue;
2079        mBroadcastQueues[1] = mBgBroadcastQueue;
2080
2081        mServices = new ActiveServices(this);
2082        mProviderMap = new ProviderMap(this);
2083
2084        // TODO: Move creation of battery stats service outside of activity manager service.
2085        File dataDir = Environment.getDataDirectory();
2086        File systemDir = new File(dataDir, "system");
2087        systemDir.mkdirs();
2088        mBatteryStatsService = new BatteryStatsService(new File(
2089                systemDir, "batterystats.bin").toString(), mHandler);
2090        mBatteryStatsService.getActiveStatistics().readLocked();
2091        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2092        mOnBattery = DEBUG_POWER ? true
2093                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2094        mBatteryStatsService.getActiveStatistics().setCallback(this);
2095
2096        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2097
2098        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
2099        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2100
2101        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2102
2103        // User 0 is the first and only user that runs at boot.
2104        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2105        mUserLru.add(Integer.valueOf(0));
2106        updateStartedUserArrayLocked();
2107
2108        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2109            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2110
2111        mConfiguration.setToDefaults();
2112        mConfiguration.setLocale(Locale.getDefault());
2113
2114        mConfigurationSeq = mConfiguration.seq = 1;
2115        mProcessCpuTracker.init();
2116
2117        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2118        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2119        mStackSupervisor = new ActivityStackSupervisor(this);
2120
2121        mProcessCpuThread = new Thread("CpuTracker") {
2122            @Override
2123            public void run() {
2124                while (true) {
2125                    try {
2126                        try {
2127                            synchronized(this) {
2128                                final long now = SystemClock.uptimeMillis();
2129                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2130                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2131                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2132                                //        + ", write delay=" + nextWriteDelay);
2133                                if (nextWriteDelay < nextCpuDelay) {
2134                                    nextCpuDelay = nextWriteDelay;
2135                                }
2136                                if (nextCpuDelay > 0) {
2137                                    mProcessCpuMutexFree.set(true);
2138                                    this.wait(nextCpuDelay);
2139                                }
2140                            }
2141                        } catch (InterruptedException e) {
2142                        }
2143                        updateCpuStatsNow();
2144                    } catch (Exception e) {
2145                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2146                    }
2147                }
2148            }
2149        };
2150
2151        Watchdog.getInstance().addMonitor(this);
2152        Watchdog.getInstance().addThread(mHandler);
2153    }
2154
2155    public void setSystemServiceManager(SystemServiceManager mgr) {
2156        mSystemServiceManager = mgr;
2157    }
2158
2159    private void start() {
2160        mProcessCpuThread.start();
2161
2162        mBatteryStatsService.publish(mContext);
2163        mUsageStatsService.publish(mContext);
2164        mAppOpsService.publish(mContext);
2165
2166        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2167    }
2168
2169    @Override
2170    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2171            throws RemoteException {
2172        if (code == SYSPROPS_TRANSACTION) {
2173            // We need to tell all apps about the system property change.
2174            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2175            synchronized(this) {
2176                final int NP = mProcessNames.getMap().size();
2177                for (int ip=0; ip<NP; ip++) {
2178                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2179                    final int NA = apps.size();
2180                    for (int ia=0; ia<NA; ia++) {
2181                        ProcessRecord app = apps.valueAt(ia);
2182                        if (app.thread != null) {
2183                            procs.add(app.thread.asBinder());
2184                        }
2185                    }
2186                }
2187            }
2188
2189            int N = procs.size();
2190            for (int i=0; i<N; i++) {
2191                Parcel data2 = Parcel.obtain();
2192                try {
2193                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2194                } catch (RemoteException e) {
2195                }
2196                data2.recycle();
2197            }
2198        }
2199        try {
2200            return super.onTransact(code, data, reply, flags);
2201        } catch (RuntimeException e) {
2202            // The activity manager only throws security exceptions, so let's
2203            // log all others.
2204            if (!(e instanceof SecurityException)) {
2205                Slog.wtf(TAG, "Activity Manager Crash", e);
2206            }
2207            throw e;
2208        }
2209    }
2210
2211    void updateCpuStats() {
2212        final long now = SystemClock.uptimeMillis();
2213        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2214            return;
2215        }
2216        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2217            synchronized (mProcessCpuThread) {
2218                mProcessCpuThread.notify();
2219            }
2220        }
2221    }
2222
2223    void updateCpuStatsNow() {
2224        synchronized (mProcessCpuThread) {
2225            mProcessCpuMutexFree.set(false);
2226            final long now = SystemClock.uptimeMillis();
2227            boolean haveNewCpuStats = false;
2228
2229            if (MONITOR_CPU_USAGE &&
2230                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2231                mLastCpuTime.set(now);
2232                haveNewCpuStats = true;
2233                mProcessCpuTracker.update();
2234                //Slog.i(TAG, mProcessCpu.printCurrentState());
2235                //Slog.i(TAG, "Total CPU usage: "
2236                //        + mProcessCpu.getTotalCpuPercent() + "%");
2237
2238                // Slog the cpu usage if the property is set.
2239                if ("true".equals(SystemProperties.get("events.cpu"))) {
2240                    int user = mProcessCpuTracker.getLastUserTime();
2241                    int system = mProcessCpuTracker.getLastSystemTime();
2242                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2243                    int irq = mProcessCpuTracker.getLastIrqTime();
2244                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2245                    int idle = mProcessCpuTracker.getLastIdleTime();
2246
2247                    int total = user + system + iowait + irq + softIrq + idle;
2248                    if (total == 0) total = 1;
2249
2250                    EventLog.writeEvent(EventLogTags.CPU,
2251                            ((user+system+iowait+irq+softIrq) * 100) / total,
2252                            (user * 100) / total,
2253                            (system * 100) / total,
2254                            (iowait * 100) / total,
2255                            (irq * 100) / total,
2256                            (softIrq * 100) / total);
2257                }
2258            }
2259
2260            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2261            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2262            synchronized(bstats) {
2263                synchronized(mPidsSelfLocked) {
2264                    if (haveNewCpuStats) {
2265                        if (mOnBattery) {
2266                            int perc = bstats.startAddingCpuLocked();
2267                            int totalUTime = 0;
2268                            int totalSTime = 0;
2269                            final int N = mProcessCpuTracker.countStats();
2270                            for (int i=0; i<N; i++) {
2271                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2272                                if (!st.working) {
2273                                    continue;
2274                                }
2275                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2276                                int otherUTime = (st.rel_utime*perc)/100;
2277                                int otherSTime = (st.rel_stime*perc)/100;
2278                                totalUTime += otherUTime;
2279                                totalSTime += otherSTime;
2280                                if (pr != null) {
2281                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2282                                    if (ps == null || !ps.isActive()) {
2283                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2284                                                pr.info.uid, pr.processName);
2285                                    }
2286                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2287                                            st.rel_stime-otherSTime);
2288                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2289                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2290                                } else {
2291                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2292                                    if (ps == null || !ps.isActive()) {
2293                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2294                                                bstats.mapUid(st.uid), st.name);
2295                                    }
2296                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2297                                            st.rel_stime-otherSTime);
2298                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2299                                }
2300                            }
2301                            bstats.finishAddingCpuLocked(perc, totalUTime,
2302                                    totalSTime, cpuSpeedTimes);
2303                        }
2304                    }
2305                }
2306
2307                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2308                    mLastWriteTime = now;
2309                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2310                }
2311            }
2312        }
2313    }
2314
2315    @Override
2316    public void batteryNeedsCpuUpdate() {
2317        updateCpuStatsNow();
2318    }
2319
2320    @Override
2321    public void batteryPowerChanged(boolean onBattery) {
2322        // When plugging in, update the CPU stats first before changing
2323        // the plug state.
2324        updateCpuStatsNow();
2325        synchronized (this) {
2326            synchronized(mPidsSelfLocked) {
2327                mOnBattery = DEBUG_POWER ? true : onBattery;
2328            }
2329        }
2330    }
2331
2332    /**
2333     * Initialize the application bind args. These are passed to each
2334     * process when the bindApplication() IPC is sent to the process. They're
2335     * lazily setup to make sure the services are running when they're asked for.
2336     */
2337    private HashMap<String, IBinder> getCommonServicesLocked() {
2338        if (mAppBindArgs == null) {
2339            mAppBindArgs = new HashMap<String, IBinder>();
2340
2341            // Setup the application init args
2342            mAppBindArgs.put("package", ServiceManager.getService("package"));
2343            mAppBindArgs.put("window", ServiceManager.getService("window"));
2344            mAppBindArgs.put(Context.ALARM_SERVICE,
2345                    ServiceManager.getService(Context.ALARM_SERVICE));
2346        }
2347        return mAppBindArgs;
2348    }
2349
2350    final void setFocusedActivityLocked(ActivityRecord r) {
2351        if (mFocusedActivity != r) {
2352            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2353            mFocusedActivity = r;
2354            if (r.task != null && r.task.voiceInteractor != null) {
2355                startRunningVoiceLocked();
2356            } else {
2357                finishRunningVoiceLocked();
2358            }
2359            mStackSupervisor.setFocusedStack(r);
2360            if (r != null) {
2361                mWindowManager.setFocusedApp(r.appToken, true);
2362            }
2363            applyUpdateLockStateLocked(r);
2364        }
2365    }
2366
2367    final void clearFocusedActivity(ActivityRecord r) {
2368        if (mFocusedActivity == r) {
2369            mFocusedActivity = null;
2370        }
2371    }
2372
2373    @Override
2374    public void setFocusedStack(int stackId) {
2375        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2376        synchronized (ActivityManagerService.this) {
2377            ActivityStack stack = mStackSupervisor.getStack(stackId);
2378            if (stack != null) {
2379                ActivityRecord r = stack.topRunningActivityLocked(null);
2380                if (r != null) {
2381                    setFocusedActivityLocked(r);
2382                }
2383            }
2384        }
2385    }
2386
2387    @Override
2388    public void notifyActivityDrawn(IBinder token) {
2389        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2390        synchronized (this) {
2391            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2392            if (r != null) {
2393                r.task.stack.notifyActivityDrawnLocked(r);
2394            }
2395        }
2396    }
2397
2398    final void applyUpdateLockStateLocked(ActivityRecord r) {
2399        // Modifications to the UpdateLock state are done on our handler, outside
2400        // the activity manager's locks.  The new state is determined based on the
2401        // state *now* of the relevant activity record.  The object is passed to
2402        // the handler solely for logging detail, not to be consulted/modified.
2403        final boolean nextState = r != null && r.immersive;
2404        mHandler.sendMessage(
2405                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2406    }
2407
2408    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2409        Message msg = Message.obtain();
2410        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2411        msg.obj = r.task.askedCompatMode ? null : r;
2412        mHandler.sendMessage(msg);
2413    }
2414
2415    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2416            String what, Object obj, ProcessRecord srcApp) {
2417        app.lastActivityTime = now;
2418
2419        if (app.activities.size() > 0) {
2420            // Don't want to touch dependent processes that are hosting activities.
2421            return index;
2422        }
2423
2424        int lrui = mLruProcesses.lastIndexOf(app);
2425        if (lrui < 0) {
2426            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2427                    + what + " " + obj + " from " + srcApp);
2428            return index;
2429        }
2430
2431        if (lrui >= index) {
2432            // Don't want to cause this to move dependent processes *back* in the
2433            // list as if they were less frequently used.
2434            return index;
2435        }
2436
2437        if (lrui >= mLruProcessActivityStart) {
2438            // Don't want to touch dependent processes that are hosting activities.
2439            return index;
2440        }
2441
2442        mLruProcesses.remove(lrui);
2443        if (index > 0) {
2444            index--;
2445        }
2446        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2447                + " in LRU list: " + app);
2448        mLruProcesses.add(index, app);
2449        return index;
2450    }
2451
2452    final void removeLruProcessLocked(ProcessRecord app) {
2453        int lrui = mLruProcesses.lastIndexOf(app);
2454        if (lrui >= 0) {
2455            if (lrui <= mLruProcessActivityStart) {
2456                mLruProcessActivityStart--;
2457            }
2458            if (lrui <= mLruProcessServiceStart) {
2459                mLruProcessServiceStart--;
2460            }
2461            mLruProcesses.remove(lrui);
2462        }
2463    }
2464
2465    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2466            ProcessRecord client) {
2467        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2468                || app.treatLikeActivity;
2469        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2470        if (!activityChange && hasActivity) {
2471            // The process has activities, so we are only allowing activity-based adjustments
2472            // to move it.  It should be kept in the front of the list with other
2473            // processes that have activities, and we don't want those to change their
2474            // order except due to activity operations.
2475            return;
2476        }
2477
2478        mLruSeq++;
2479        final long now = SystemClock.uptimeMillis();
2480        app.lastActivityTime = now;
2481
2482        // First a quick reject: if the app is already at the position we will
2483        // put it, then there is nothing to do.
2484        if (hasActivity) {
2485            final int N = mLruProcesses.size();
2486            if (N > 0 && mLruProcesses.get(N-1) == app) {
2487                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2488                return;
2489            }
2490        } else {
2491            if (mLruProcessServiceStart > 0
2492                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2493                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2494                return;
2495            }
2496        }
2497
2498        int lrui = mLruProcesses.lastIndexOf(app);
2499
2500        if (app.persistent && lrui >= 0) {
2501            // We don't care about the position of persistent processes, as long as
2502            // they are in the list.
2503            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2504            return;
2505        }
2506
2507        /* In progress: compute new position first, so we can avoid doing work
2508           if the process is not actually going to move.  Not yet working.
2509        int addIndex;
2510        int nextIndex;
2511        boolean inActivity = false, inService = false;
2512        if (hasActivity) {
2513            // Process has activities, put it at the very tipsy-top.
2514            addIndex = mLruProcesses.size();
2515            nextIndex = mLruProcessServiceStart;
2516            inActivity = true;
2517        } else if (hasService) {
2518            // Process has services, put it at the top of the service list.
2519            addIndex = mLruProcessActivityStart;
2520            nextIndex = mLruProcessServiceStart;
2521            inActivity = true;
2522            inService = true;
2523        } else  {
2524            // Process not otherwise of interest, it goes to the top of the non-service area.
2525            addIndex = mLruProcessServiceStart;
2526            if (client != null) {
2527                int clientIndex = mLruProcesses.lastIndexOf(client);
2528                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2529                        + app);
2530                if (clientIndex >= 0 && addIndex > clientIndex) {
2531                    addIndex = clientIndex;
2532                }
2533            }
2534            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2535        }
2536
2537        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2538                + mLruProcessActivityStart + "): " + app);
2539        */
2540
2541        if (lrui >= 0) {
2542            if (lrui < mLruProcessActivityStart) {
2543                mLruProcessActivityStart--;
2544            }
2545            if (lrui < mLruProcessServiceStart) {
2546                mLruProcessServiceStart--;
2547            }
2548            /*
2549            if (addIndex > lrui) {
2550                addIndex--;
2551            }
2552            if (nextIndex > lrui) {
2553                nextIndex--;
2554            }
2555            */
2556            mLruProcesses.remove(lrui);
2557        }
2558
2559        /*
2560        mLruProcesses.add(addIndex, app);
2561        if (inActivity) {
2562            mLruProcessActivityStart++;
2563        }
2564        if (inService) {
2565            mLruProcessActivityStart++;
2566        }
2567        */
2568
2569        int nextIndex;
2570        if (hasActivity) {
2571            final int N = mLruProcesses.size();
2572            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2573                // Process doesn't have activities, but has clients with
2574                // activities...  move it up, but one below the top (the top
2575                // should always have a real activity).
2576                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2577                mLruProcesses.add(N-1, app);
2578                // To keep it from spamming the LRU list (by making a bunch of clients),
2579                // we will push down any other entries owned by the app.
2580                final int uid = app.info.uid;
2581                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2582                    ProcessRecord subProc = mLruProcesses.get(i);
2583                    if (subProc.info.uid == uid) {
2584                        // We want to push this one down the list.  If the process after
2585                        // it is for the same uid, however, don't do so, because we don't
2586                        // want them internally to be re-ordered.
2587                        if (mLruProcesses.get(i-1).info.uid != uid) {
2588                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2589                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2590                            ProcessRecord tmp = mLruProcesses.get(i);
2591                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2592                            mLruProcesses.set(i-1, tmp);
2593                            i--;
2594                        }
2595                    } else {
2596                        // A gap, we can stop here.
2597                        break;
2598                    }
2599                }
2600            } else {
2601                // Process has activities, put it at the very tipsy-top.
2602                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2603                mLruProcesses.add(app);
2604            }
2605            nextIndex = mLruProcessServiceStart;
2606        } else if (hasService) {
2607            // Process has services, put it at the top of the service list.
2608            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2609            mLruProcesses.add(mLruProcessActivityStart, app);
2610            nextIndex = mLruProcessServiceStart;
2611            mLruProcessActivityStart++;
2612        } else  {
2613            // Process not otherwise of interest, it goes to the top of the non-service area.
2614            int index = mLruProcessServiceStart;
2615            if (client != null) {
2616                // If there is a client, don't allow the process to be moved up higher
2617                // in the list than that client.
2618                int clientIndex = mLruProcesses.lastIndexOf(client);
2619                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2620                        + " when updating " + app);
2621                if (clientIndex <= lrui) {
2622                    // Don't allow the client index restriction to push it down farther in the
2623                    // list than it already is.
2624                    clientIndex = lrui;
2625                }
2626                if (clientIndex >= 0 && index > clientIndex) {
2627                    index = clientIndex;
2628                }
2629            }
2630            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2631            mLruProcesses.add(index, app);
2632            nextIndex = index-1;
2633            mLruProcessActivityStart++;
2634            mLruProcessServiceStart++;
2635        }
2636
2637        // If the app is currently using a content provider or service,
2638        // bump those processes as well.
2639        for (int j=app.connections.size()-1; j>=0; j--) {
2640            ConnectionRecord cr = app.connections.valueAt(j);
2641            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2642                    && cr.binding.service.app != null
2643                    && cr.binding.service.app.lruSeq != mLruSeq
2644                    && !cr.binding.service.app.persistent) {
2645                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2646                        "service connection", cr, app);
2647            }
2648        }
2649        for (int j=app.conProviders.size()-1; j>=0; j--) {
2650            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2651            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2652                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2653                        "provider reference", cpr, app);
2654            }
2655        }
2656    }
2657
2658    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2659        if (uid == Process.SYSTEM_UID) {
2660            // The system gets to run in any process.  If there are multiple
2661            // processes with the same uid, just pick the first (this
2662            // should never happen).
2663            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2664            if (procs == null) return null;
2665            final int N = procs.size();
2666            for (int i = 0; i < N; i++) {
2667                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2668            }
2669        }
2670        ProcessRecord proc = mProcessNames.get(processName, uid);
2671        if (false && proc != null && !keepIfLarge
2672                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2673                && proc.lastCachedPss >= 4000) {
2674            // Turn this condition on to cause killing to happen regularly, for testing.
2675            if (proc.baseProcessTracker != null) {
2676                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2677            }
2678            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2679                    + "k from cached");
2680        } else if (proc != null && !keepIfLarge
2681                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2682                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2683            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2684            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2685                if (proc.baseProcessTracker != null) {
2686                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2687                }
2688                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2689                        + "k from cached");
2690            }
2691        }
2692        return proc;
2693    }
2694
2695    void ensurePackageDexOpt(String packageName) {
2696        IPackageManager pm = AppGlobals.getPackageManager();
2697        try {
2698            if (pm.performDexOpt(packageName)) {
2699                mDidDexOpt = true;
2700            }
2701        } catch (RemoteException e) {
2702        }
2703    }
2704
2705    boolean isNextTransitionForward() {
2706        int transit = mWindowManager.getPendingAppTransition();
2707        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2708                || transit == AppTransition.TRANSIT_TASK_OPEN
2709                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2710    }
2711
2712    final ProcessRecord startProcessLocked(String processName,
2713            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2714            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2715            boolean isolated, boolean keepIfLarge) {
2716        ProcessRecord app;
2717        if (!isolated) {
2718            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2719        } else {
2720            // If this is an isolated process, it can't re-use an existing process.
2721            app = null;
2722        }
2723        // We don't have to do anything more if:
2724        // (1) There is an existing application record; and
2725        // (2) The caller doesn't think it is dead, OR there is no thread
2726        //     object attached to it so we know it couldn't have crashed; and
2727        // (3) There is a pid assigned to it, so it is either starting or
2728        //     already running.
2729        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2730                + " app=" + app + " knownToBeDead=" + knownToBeDead
2731                + " thread=" + (app != null ? app.thread : null)
2732                + " pid=" + (app != null ? app.pid : -1));
2733        if (app != null && app.pid > 0) {
2734            if (!knownToBeDead || app.thread == null) {
2735                // We already have the app running, or are waiting for it to
2736                // come up (we have a pid but not yet its thread), so keep it.
2737                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2738                // If this is a new package in the process, add the package to the list
2739                app.addPackage(info.packageName, mProcessStats);
2740                return app;
2741            }
2742
2743            // An application record is attached to a previous process,
2744            // clean it up now.
2745            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2746            handleAppDiedLocked(app, true, true);
2747        }
2748
2749        String hostingNameStr = hostingName != null
2750                ? hostingName.flattenToShortString() : null;
2751
2752        if (!isolated) {
2753            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2754                // If we are in the background, then check to see if this process
2755                // is bad.  If so, we will just silently fail.
2756                if (mBadProcesses.get(info.processName, info.uid) != null) {
2757                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2758                            + "/" + info.processName);
2759                    return null;
2760                }
2761            } else {
2762                // When the user is explicitly starting a process, then clear its
2763                // crash count so that we won't make it bad until they see at
2764                // least one crash dialog again, and make the process good again
2765                // if it had been bad.
2766                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2767                        + "/" + info.processName);
2768                mProcessCrashTimes.remove(info.processName, info.uid);
2769                if (mBadProcesses.get(info.processName, info.uid) != null) {
2770                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2771                            UserHandle.getUserId(info.uid), info.uid,
2772                            info.processName);
2773                    mBadProcesses.remove(info.processName, info.uid);
2774                    if (app != null) {
2775                        app.bad = false;
2776                    }
2777                }
2778            }
2779        }
2780
2781        if (app == null) {
2782            app = newProcessRecordLocked(info, processName, isolated);
2783            if (app == null) {
2784                Slog.w(TAG, "Failed making new process record for "
2785                        + processName + "/" + info.uid + " isolated=" + isolated);
2786                return null;
2787            }
2788            mProcessNames.put(processName, app.uid, app);
2789            if (isolated) {
2790                mIsolatedProcesses.put(app.uid, app);
2791            }
2792        } else {
2793            // If this is a new package in the process, add the package to the list
2794            app.addPackage(info.packageName, mProcessStats);
2795        }
2796
2797        // If the system is not ready yet, then hold off on starting this
2798        // process until it is.
2799        if (!mProcessesReady
2800                && !isAllowedWhileBooting(info)
2801                && !allowWhileBooting) {
2802            if (!mProcessesOnHold.contains(app)) {
2803                mProcessesOnHold.add(app);
2804            }
2805            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2806            return app;
2807        }
2808
2809        startProcessLocked(app, hostingType, hostingNameStr);
2810        return (app.pid != 0) ? app : null;
2811    }
2812
2813    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2814        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2815    }
2816
2817    private final void startProcessLocked(ProcessRecord app,
2818            String hostingType, String hostingNameStr) {
2819        if (app.pid > 0 && app.pid != MY_PID) {
2820            synchronized (mPidsSelfLocked) {
2821                mPidsSelfLocked.remove(app.pid);
2822                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2823            }
2824            app.setPid(0);
2825        }
2826
2827        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2828                "startProcessLocked removing on hold: " + app);
2829        mProcessesOnHold.remove(app);
2830
2831        updateCpuStats();
2832
2833        try {
2834            int uid = app.uid;
2835
2836            int[] gids = null;
2837            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2838            if (!app.isolated) {
2839                int[] permGids = null;
2840                try {
2841                    final PackageManager pm = mContext.getPackageManager();
2842                    permGids = pm.getPackageGids(app.info.packageName);
2843
2844                    if (Environment.isExternalStorageEmulated()) {
2845                        if (pm.checkPermission(
2846                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2847                                app.info.packageName) == PERMISSION_GRANTED) {
2848                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2849                        } else {
2850                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2851                        }
2852                    }
2853                } catch (PackageManager.NameNotFoundException e) {
2854                    Slog.w(TAG, "Unable to retrieve gids", e);
2855                }
2856
2857                /*
2858                 * Add shared application GID so applications can share some
2859                 * resources like shared libraries
2860                 */
2861                if (permGids == null) {
2862                    gids = new int[1];
2863                } else {
2864                    gids = new int[permGids.length + 1];
2865                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2866                }
2867                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2868            }
2869            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2870                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2871                        && mTopComponent != null
2872                        && app.processName.equals(mTopComponent.getPackageName())) {
2873                    uid = 0;
2874                }
2875                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2876                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2877                    uid = 0;
2878                }
2879            }
2880            int debugFlags = 0;
2881            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2882                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2883                // Also turn on CheckJNI for debuggable apps. It's quite
2884                // awkward to turn on otherwise.
2885                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2886            }
2887            // Run the app in safe mode if its manifest requests so or the
2888            // system is booted in safe mode.
2889            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2890                mSafeMode == true) {
2891                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2892            }
2893            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2894                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2895            }
2896            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2897                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2898            }
2899            if ("1".equals(SystemProperties.get("debug.assert"))) {
2900                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2901            }
2902
2903            String requiredAbi = app.info.requiredCpuAbi;
2904            if (requiredAbi == null) {
2905                requiredAbi = Build.SUPPORTED_ABIS[0];
2906            }
2907
2908            // Start the process.  It will either succeed and return a result containing
2909            // the PID of the new process, or else throw a RuntimeException.
2910            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2911                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2912                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
2913
2914            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2915            synchronized (bs) {
2916                if (bs.isOnBattery()) {
2917                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2918                }
2919            }
2920
2921            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2922                    UserHandle.getUserId(uid), startResult.pid, uid,
2923                    app.processName, hostingType,
2924                    hostingNameStr != null ? hostingNameStr : "");
2925
2926            if (app.persistent) {
2927                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2928            }
2929
2930            StringBuilder buf = mStringBuilder;
2931            buf.setLength(0);
2932            buf.append("Start proc ");
2933            buf.append(app.processName);
2934            buf.append(" for ");
2935            buf.append(hostingType);
2936            if (hostingNameStr != null) {
2937                buf.append(" ");
2938                buf.append(hostingNameStr);
2939            }
2940            buf.append(": pid=");
2941            buf.append(startResult.pid);
2942            buf.append(" uid=");
2943            buf.append(uid);
2944            buf.append(" gids={");
2945            if (gids != null) {
2946                for (int gi=0; gi<gids.length; gi++) {
2947                    if (gi != 0) buf.append(", ");
2948                    buf.append(gids[gi]);
2949
2950                }
2951            }
2952            buf.append("}");
2953            Slog.i(TAG, buf.toString());
2954            app.setPid(startResult.pid);
2955            app.usingWrapper = startResult.usingWrapper;
2956            app.removed = false;
2957            synchronized (mPidsSelfLocked) {
2958                this.mPidsSelfLocked.put(startResult.pid, app);
2959                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2960                msg.obj = app;
2961                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2962                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2963            }
2964            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
2965                    app.processName, app.info.uid);
2966            if (app.isolated) {
2967                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2968            }
2969        } catch (RuntimeException e) {
2970            // XXX do better error recovery.
2971            app.setPid(0);
2972            Slog.e(TAG, "Failure starting process " + app.processName, e);
2973        }
2974    }
2975
2976    void updateUsageStats(ActivityRecord component, boolean resumed) {
2977        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
2978        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2979        if (resumed) {
2980            mUsageStatsService.noteResumeComponent(component.realActivity);
2981            synchronized (stats) {
2982                stats.noteActivityResumedLocked(component.app.uid);
2983            }
2984        } else {
2985            mUsageStatsService.notePauseComponent(component.realActivity);
2986            synchronized (stats) {
2987                stats.noteActivityPausedLocked(component.app.uid);
2988            }
2989        }
2990    }
2991
2992    Intent getHomeIntent() {
2993        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
2994        intent.setComponent(mTopComponent);
2995        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
2996            intent.addCategory(Intent.CATEGORY_HOME);
2997        }
2998        return intent;
2999    }
3000
3001    boolean startHomeActivityLocked(int userId) {
3002        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3003                && mTopAction == null) {
3004            // We are running in factory test mode, but unable to find
3005            // the factory test app, so just sit around displaying the
3006            // error message and don't try to start anything.
3007            return false;
3008        }
3009        Intent intent = getHomeIntent();
3010        ActivityInfo aInfo =
3011            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3012        if (aInfo != null) {
3013            intent.setComponent(new ComponentName(
3014                    aInfo.applicationInfo.packageName, aInfo.name));
3015            // Don't do this if the home app is currently being
3016            // instrumented.
3017            aInfo = new ActivityInfo(aInfo);
3018            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3019            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3020                    aInfo.applicationInfo.uid, true);
3021            if (app == null || app.instrumentationClass == null) {
3022                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3023                mStackSupervisor.startHomeActivity(intent, aInfo);
3024            }
3025        }
3026
3027        return true;
3028    }
3029
3030    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3031        ActivityInfo ai = null;
3032        ComponentName comp = intent.getComponent();
3033        try {
3034            if (comp != null) {
3035                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3036            } else {
3037                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3038                        intent,
3039                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3040                            flags, userId);
3041
3042                if (info != null) {
3043                    ai = info.activityInfo;
3044                }
3045            }
3046        } catch (RemoteException e) {
3047            // ignore
3048        }
3049
3050        return ai;
3051    }
3052
3053    /**
3054     * Starts the "new version setup screen" if appropriate.
3055     */
3056    void startSetupActivityLocked() {
3057        // Only do this once per boot.
3058        if (mCheckedForSetup) {
3059            return;
3060        }
3061
3062        // We will show this screen if the current one is a different
3063        // version than the last one shown, and we are not running in
3064        // low-level factory test mode.
3065        final ContentResolver resolver = mContext.getContentResolver();
3066        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3067                Settings.Global.getInt(resolver,
3068                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3069            mCheckedForSetup = true;
3070
3071            // See if we should be showing the platform update setup UI.
3072            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3073            List<ResolveInfo> ris = mContext.getPackageManager()
3074                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3075
3076            // We don't allow third party apps to replace this.
3077            ResolveInfo ri = null;
3078            for (int i=0; ris != null && i<ris.size(); i++) {
3079                if ((ris.get(i).activityInfo.applicationInfo.flags
3080                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3081                    ri = ris.get(i);
3082                    break;
3083                }
3084            }
3085
3086            if (ri != null) {
3087                String vers = ri.activityInfo.metaData != null
3088                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3089                        : null;
3090                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3091                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3092                            Intent.METADATA_SETUP_VERSION);
3093                }
3094                String lastVers = Settings.Secure.getString(
3095                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3096                if (vers != null && !vers.equals(lastVers)) {
3097                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3098                    intent.setComponent(new ComponentName(
3099                            ri.activityInfo.packageName, ri.activityInfo.name));
3100                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3101                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3102                }
3103            }
3104        }
3105    }
3106
3107    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3108        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3109    }
3110
3111    void enforceNotIsolatedCaller(String caller) {
3112        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3113            throw new SecurityException("Isolated process not allowed to call " + caller);
3114        }
3115    }
3116
3117    @Override
3118    public int getFrontActivityScreenCompatMode() {
3119        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3120        synchronized (this) {
3121            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3122        }
3123    }
3124
3125    @Override
3126    public void setFrontActivityScreenCompatMode(int mode) {
3127        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3128                "setFrontActivityScreenCompatMode");
3129        synchronized (this) {
3130            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3131        }
3132    }
3133
3134    @Override
3135    public int getPackageScreenCompatMode(String packageName) {
3136        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3137        synchronized (this) {
3138            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3139        }
3140    }
3141
3142    @Override
3143    public void setPackageScreenCompatMode(String packageName, int mode) {
3144        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3145                "setPackageScreenCompatMode");
3146        synchronized (this) {
3147            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3148        }
3149    }
3150
3151    @Override
3152    public boolean getPackageAskScreenCompat(String packageName) {
3153        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3154        synchronized (this) {
3155            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3156        }
3157    }
3158
3159    @Override
3160    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3161        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3162                "setPackageAskScreenCompat");
3163        synchronized (this) {
3164            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3165        }
3166    }
3167
3168    private void dispatchProcessesChanged() {
3169        int N;
3170        synchronized (this) {
3171            N = mPendingProcessChanges.size();
3172            if (mActiveProcessChanges.length < N) {
3173                mActiveProcessChanges = new ProcessChangeItem[N];
3174            }
3175            mPendingProcessChanges.toArray(mActiveProcessChanges);
3176            mAvailProcessChanges.addAll(mPendingProcessChanges);
3177            mPendingProcessChanges.clear();
3178            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3179        }
3180
3181        int i = mProcessObservers.beginBroadcast();
3182        while (i > 0) {
3183            i--;
3184            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3185            if (observer != null) {
3186                try {
3187                    for (int j=0; j<N; j++) {
3188                        ProcessChangeItem item = mActiveProcessChanges[j];
3189                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3190                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3191                                    + item.pid + " uid=" + item.uid + ": "
3192                                    + item.foregroundActivities);
3193                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3194                                    item.foregroundActivities);
3195                        }
3196                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3197                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3198                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3199                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3200                        }
3201                    }
3202                } catch (RemoteException e) {
3203                }
3204            }
3205        }
3206        mProcessObservers.finishBroadcast();
3207    }
3208
3209    private void dispatchProcessDied(int pid, int uid) {
3210        int i = mProcessObservers.beginBroadcast();
3211        while (i > 0) {
3212            i--;
3213            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3214            if (observer != null) {
3215                try {
3216                    observer.onProcessDied(pid, uid);
3217                } catch (RemoteException e) {
3218                }
3219            }
3220        }
3221        mProcessObservers.finishBroadcast();
3222    }
3223
3224    final void doPendingActivityLaunchesLocked(boolean doResume) {
3225        final int N = mPendingActivityLaunches.size();
3226        if (N <= 0) {
3227            return;
3228        }
3229        for (int i=0; i<N; i++) {
3230            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3231            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
3232                    doResume && i == (N-1), null);
3233        }
3234        mPendingActivityLaunches.clear();
3235    }
3236
3237    @Override
3238    public final int startActivity(IApplicationThread caller, String callingPackage,
3239            Intent intent, String resolvedType, IBinder resultTo,
3240            String resultWho, int requestCode, int startFlags,
3241            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3242        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3243                resultWho, requestCode,
3244                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3245    }
3246
3247    @Override
3248    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3249            Intent intent, String resolvedType, IBinder resultTo,
3250            String resultWho, int requestCode, int startFlags,
3251            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3252        enforceNotIsolatedCaller("startActivity");
3253        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3254                false, true, "startActivity", null);
3255        // TODO: Switch to user app stacks here.
3256        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3257                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3258                null, null, options, userId, null);
3259    }
3260
3261    @Override
3262    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3263            Intent intent, String resolvedType, IBinder resultTo,
3264            String resultWho, int requestCode, int startFlags, String profileFile,
3265            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3266        enforceNotIsolatedCaller("startActivityAndWait");
3267        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3268                false, true, "startActivityAndWait", null);
3269        WaitResult res = new WaitResult();
3270        // TODO: Switch to user app stacks here.
3271        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3272                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3273                res, null, options, UserHandle.getCallingUserId(), null);
3274        return res;
3275    }
3276
3277    @Override
3278    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3279            Intent intent, String resolvedType, IBinder resultTo,
3280            String resultWho, int requestCode, int startFlags, Configuration config,
3281            Bundle options, int userId) {
3282        enforceNotIsolatedCaller("startActivityWithConfig");
3283        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3284                false, true, "startActivityWithConfig", null);
3285        // TODO: Switch to user app stacks here.
3286        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3287                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3288                null, null, null, config, options, userId, null);
3289        return ret;
3290    }
3291
3292    @Override
3293    public int startActivityIntentSender(IApplicationThread caller,
3294            IntentSender intent, Intent fillInIntent, String resolvedType,
3295            IBinder resultTo, String resultWho, int requestCode,
3296            int flagsMask, int flagsValues, Bundle options) {
3297        enforceNotIsolatedCaller("startActivityIntentSender");
3298        // Refuse possible leaked file descriptors
3299        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3300            throw new IllegalArgumentException("File descriptors passed in Intent");
3301        }
3302
3303        IIntentSender sender = intent.getTarget();
3304        if (!(sender instanceof PendingIntentRecord)) {
3305            throw new IllegalArgumentException("Bad PendingIntent object");
3306        }
3307
3308        PendingIntentRecord pir = (PendingIntentRecord)sender;
3309
3310        synchronized (this) {
3311            // If this is coming from the currently resumed activity, it is
3312            // effectively saying that app switches are allowed at this point.
3313            final ActivityStack stack = getFocusedStack();
3314            if (stack.mResumedActivity != null &&
3315                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3316                mAppSwitchesAllowedTime = 0;
3317            }
3318        }
3319        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3320                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3321        return ret;
3322    }
3323
3324    @Override
3325    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3326            Intent intent, String resolvedType, IVoiceInteractionSession session,
3327            IVoiceInteractor interactor, int startFlags, String profileFile,
3328            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3329        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3330                != PackageManager.PERMISSION_GRANTED) {
3331            String msg = "Permission Denial: startVoiceActivity() from pid="
3332                    + Binder.getCallingPid()
3333                    + ", uid=" + Binder.getCallingUid()
3334                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3335            Slog.w(TAG, msg);
3336            throw new SecurityException(msg);
3337        }
3338        if (session == null || interactor == null) {
3339            throw new NullPointerException("null session or interactor");
3340        }
3341        userId = handleIncomingUser(callingPid, callingUid, userId,
3342                false, true, "startVoiceActivity", null);
3343        // TODO: Switch to user app stacks here.
3344        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3345                resolvedType, session, interactor, null, null, 0, startFlags,
3346                profileFile, profileFd, null, null, options, userId, null);
3347    }
3348
3349    @Override
3350    public boolean startNextMatchingActivity(IBinder callingActivity,
3351            Intent intent, Bundle options) {
3352        // Refuse possible leaked file descriptors
3353        if (intent != null && intent.hasFileDescriptors() == true) {
3354            throw new IllegalArgumentException("File descriptors passed in Intent");
3355        }
3356
3357        synchronized (this) {
3358            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3359            if (r == null) {
3360                ActivityOptions.abort(options);
3361                return false;
3362            }
3363            if (r.app == null || r.app.thread == null) {
3364                // The caller is not running...  d'oh!
3365                ActivityOptions.abort(options);
3366                return false;
3367            }
3368            intent = new Intent(intent);
3369            // The caller is not allowed to change the data.
3370            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3371            // And we are resetting to find the next component...
3372            intent.setComponent(null);
3373
3374            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3375
3376            ActivityInfo aInfo = null;
3377            try {
3378                List<ResolveInfo> resolves =
3379                    AppGlobals.getPackageManager().queryIntentActivities(
3380                            intent, r.resolvedType,
3381                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3382                            UserHandle.getCallingUserId());
3383
3384                // Look for the original activity in the list...
3385                final int N = resolves != null ? resolves.size() : 0;
3386                for (int i=0; i<N; i++) {
3387                    ResolveInfo rInfo = resolves.get(i);
3388                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3389                            && rInfo.activityInfo.name.equals(r.info.name)) {
3390                        // We found the current one...  the next matching is
3391                        // after it.
3392                        i++;
3393                        if (i<N) {
3394                            aInfo = resolves.get(i).activityInfo;
3395                        }
3396                        if (debug) {
3397                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3398                                    + "/" + r.info.name);
3399                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3400                                    + "/" + aInfo.name);
3401                        }
3402                        break;
3403                    }
3404                }
3405            } catch (RemoteException e) {
3406            }
3407
3408            if (aInfo == null) {
3409                // Nobody who is next!
3410                ActivityOptions.abort(options);
3411                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3412                return false;
3413            }
3414
3415            intent.setComponent(new ComponentName(
3416                    aInfo.applicationInfo.packageName, aInfo.name));
3417            intent.setFlags(intent.getFlags()&~(
3418                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3419                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3420                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3421                    Intent.FLAG_ACTIVITY_NEW_TASK));
3422
3423            // Okay now we need to start the new activity, replacing the
3424            // currently running activity.  This is a little tricky because
3425            // we want to start the new one as if the current one is finished,
3426            // but not finish the current one first so that there is no flicker.
3427            // And thus...
3428            final boolean wasFinishing = r.finishing;
3429            r.finishing = true;
3430
3431            // Propagate reply information over to the new activity.
3432            final ActivityRecord resultTo = r.resultTo;
3433            final String resultWho = r.resultWho;
3434            final int requestCode = r.requestCode;
3435            r.resultTo = null;
3436            if (resultTo != null) {
3437                resultTo.removeResultsLocked(r, resultWho, requestCode);
3438            }
3439
3440            final long origId = Binder.clearCallingIdentity();
3441            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3442                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3443                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3444                    options, false, null, null);
3445            Binder.restoreCallingIdentity(origId);
3446
3447            r.finishing = wasFinishing;
3448            if (res != ActivityManager.START_SUCCESS) {
3449                return false;
3450            }
3451            return true;
3452        }
3453    }
3454
3455    final int startActivityInPackage(int uid, String callingPackage,
3456            Intent intent, String resolvedType, IBinder resultTo,
3457            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3458                    IActivityContainer container) {
3459
3460        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3461                false, true, "startActivityInPackage", null);
3462
3463        // TODO: Switch to user app stacks here.
3464        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3465                null, null, resultTo, resultWho, requestCode, startFlags,
3466                null, null, null, null, options, userId, container);
3467        return ret;
3468    }
3469
3470    @Override
3471    public final int startActivities(IApplicationThread caller, String callingPackage,
3472            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3473            int userId) {
3474        enforceNotIsolatedCaller("startActivities");
3475        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3476                false, true, "startActivity", null);
3477        // TODO: Switch to user app stacks here.
3478        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3479                resolvedTypes, resultTo, options, userId);
3480        return ret;
3481    }
3482
3483    final int startActivitiesInPackage(int uid, String callingPackage,
3484            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3485            Bundle options, int userId) {
3486
3487        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3488                false, true, "startActivityInPackage", null);
3489        // TODO: Switch to user app stacks here.
3490        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3491                resultTo, options, userId);
3492        return ret;
3493    }
3494
3495    final void addRecentTaskLocked(TaskRecord task) {
3496        int N = mRecentTasks.size();
3497        // Quick case: check if the top-most recent task is the same.
3498        if (N > 0 && mRecentTasks.get(0) == task) {
3499            return;
3500        }
3501        // Another quick case: never add voice sessions.
3502        if (task.voiceSession != null) {
3503            return;
3504        }
3505        // Remove any existing entries that are the same kind of task.
3506        final Intent intent = task.intent;
3507        final boolean document = intent != null && intent.isDocument();
3508        for (int i=0; i<N; i++) {
3509            TaskRecord tr = mRecentTasks.get(i);
3510            if (task != tr) {
3511                if (task.userId != tr.userId) {
3512                    continue;
3513                }
3514                final Intent trIntent = tr.intent;
3515                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3516                    (intent == null || !intent.filterEquals(trIntent))) {
3517                    continue;
3518                }
3519                if (document || trIntent != null && trIntent.isDocument()) {
3520                    // Document tasks do not match other tasks.
3521                    continue;
3522                }
3523            }
3524
3525            // Either task and tr are the same or, their affinities match or their intents match
3526            // and neither of them is a document.
3527            tr.disposeThumbnail();
3528            mRecentTasks.remove(i);
3529            i--;
3530            N--;
3531            if (task.intent == null) {
3532                // If the new recent task we are adding is not fully
3533                // specified, then replace it with the existing recent task.
3534                task = tr;
3535            }
3536        }
3537        if (N >= MAX_RECENT_TASKS) {
3538            mRecentTasks.remove(N-1).disposeThumbnail();
3539        }
3540        mRecentTasks.add(0, task);
3541    }
3542
3543    @Override
3544    public void reportActivityFullyDrawn(IBinder token) {
3545        synchronized (this) {
3546            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3547            if (r == null) {
3548                return;
3549            }
3550            r.reportFullyDrawnLocked();
3551        }
3552    }
3553
3554    @Override
3555    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3556        synchronized (this) {
3557            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3558            if (r == null) {
3559                return;
3560            }
3561            final long origId = Binder.clearCallingIdentity();
3562            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3563            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3564                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3565            if (config != null) {
3566                r.frozenBeforeDestroy = true;
3567                if (!updateConfigurationLocked(config, r, false, false)) {
3568                    mStackSupervisor.resumeTopActivitiesLocked();
3569                }
3570            }
3571            Binder.restoreCallingIdentity(origId);
3572        }
3573    }
3574
3575    @Override
3576    public int getRequestedOrientation(IBinder token) {
3577        synchronized (this) {
3578            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3579            if (r == null) {
3580                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3581            }
3582            return mWindowManager.getAppOrientation(r.appToken);
3583        }
3584    }
3585
3586    /**
3587     * This is the internal entry point for handling Activity.finish().
3588     *
3589     * @param token The Binder token referencing the Activity we want to finish.
3590     * @param resultCode Result code, if any, from this Activity.
3591     * @param resultData Result data (Intent), if any, from this Activity.
3592     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3593     *            the root Activity in the task.
3594     *
3595     * @return Returns true if the activity successfully finished, or false if it is still running.
3596     */
3597    @Override
3598    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3599            boolean finishTask) {
3600        // Refuse possible leaked file descriptors
3601        if (resultData != null && resultData.hasFileDescriptors() == true) {
3602            throw new IllegalArgumentException("File descriptors passed in Intent");
3603        }
3604
3605        synchronized(this) {
3606            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3607            if (r == null) {
3608                return true;
3609            }
3610            // Keep track of the root activity of the task before we finish it
3611            TaskRecord tr = r.task;
3612            ActivityRecord rootR = tr.getRootActivity();
3613            if (mController != null) {
3614                // Find the first activity that is not finishing.
3615                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3616                if (next != null) {
3617                    // ask watcher if this is allowed
3618                    boolean resumeOK = true;
3619                    try {
3620                        resumeOK = mController.activityResuming(next.packageName);
3621                    } catch (RemoteException e) {
3622                        mController = null;
3623                        Watchdog.getInstance().setActivityController(null);
3624                    }
3625
3626                    if (!resumeOK) {
3627                        return false;
3628                    }
3629                }
3630            }
3631            final long origId = Binder.clearCallingIdentity();
3632            try {
3633                boolean res;
3634                if (finishTask && r == rootR) {
3635                    // If requested, remove the task that is associated to this activity only if it
3636                    // was the root activity in the task.  The result code and data is ignored because
3637                    // we don't support returning them across task boundaries.
3638                    res = removeTaskByIdLocked(tr.taskId, 0);
3639                } else {
3640                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3641                            resultData, "app-request", true);
3642                }
3643                return res;
3644            } finally {
3645                Binder.restoreCallingIdentity(origId);
3646            }
3647        }
3648    }
3649
3650    @Override
3651    public final void finishHeavyWeightApp() {
3652        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3653                != PackageManager.PERMISSION_GRANTED) {
3654            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3655                    + Binder.getCallingPid()
3656                    + ", uid=" + Binder.getCallingUid()
3657                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3658            Slog.w(TAG, msg);
3659            throw new SecurityException(msg);
3660        }
3661
3662        synchronized(this) {
3663            if (mHeavyWeightProcess == null) {
3664                return;
3665            }
3666
3667            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3668                    mHeavyWeightProcess.activities);
3669            for (int i=0; i<activities.size(); i++) {
3670                ActivityRecord r = activities.get(i);
3671                if (!r.finishing) {
3672                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3673                            null, "finish-heavy", true);
3674                }
3675            }
3676
3677            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3678                    mHeavyWeightProcess.userId, 0));
3679            mHeavyWeightProcess = null;
3680        }
3681    }
3682
3683    @Override
3684    public void crashApplication(int uid, int initialPid, String packageName,
3685            String message) {
3686        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3687                != PackageManager.PERMISSION_GRANTED) {
3688            String msg = "Permission Denial: crashApplication() from pid="
3689                    + Binder.getCallingPid()
3690                    + ", uid=" + Binder.getCallingUid()
3691                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3692            Slog.w(TAG, msg);
3693            throw new SecurityException(msg);
3694        }
3695
3696        synchronized(this) {
3697            ProcessRecord proc = null;
3698
3699            // Figure out which process to kill.  We don't trust that initialPid
3700            // still has any relation to current pids, so must scan through the
3701            // list.
3702            synchronized (mPidsSelfLocked) {
3703                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3704                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3705                    if (p.uid != uid) {
3706                        continue;
3707                    }
3708                    if (p.pid == initialPid) {
3709                        proc = p;
3710                        break;
3711                    }
3712                    if (p.pkgList.containsKey(packageName)) {
3713                        proc = p;
3714                    }
3715                }
3716            }
3717
3718            if (proc == null) {
3719                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3720                        + " initialPid=" + initialPid
3721                        + " packageName=" + packageName);
3722                return;
3723            }
3724
3725            if (proc.thread != null) {
3726                if (proc.pid == Process.myPid()) {
3727                    Log.w(TAG, "crashApplication: trying to crash self!");
3728                    return;
3729                }
3730                long ident = Binder.clearCallingIdentity();
3731                try {
3732                    proc.thread.scheduleCrash(message);
3733                } catch (RemoteException e) {
3734                }
3735                Binder.restoreCallingIdentity(ident);
3736            }
3737        }
3738    }
3739
3740    @Override
3741    public final void finishSubActivity(IBinder token, String resultWho,
3742            int requestCode) {
3743        synchronized(this) {
3744            final long origId = Binder.clearCallingIdentity();
3745            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3746            if (r != null) {
3747                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3748            }
3749            Binder.restoreCallingIdentity(origId);
3750        }
3751    }
3752
3753    @Override
3754    public boolean finishActivityAffinity(IBinder token) {
3755        synchronized(this) {
3756            final long origId = Binder.clearCallingIdentity();
3757            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3758            boolean res = false;
3759            if (r != null) {
3760                res = r.task.stack.finishActivityAffinityLocked(r);
3761            }
3762            Binder.restoreCallingIdentity(origId);
3763            return res;
3764        }
3765    }
3766
3767    @Override
3768    public boolean willActivityBeVisible(IBinder token) {
3769        synchronized(this) {
3770            ActivityStack stack = ActivityRecord.getStackLocked(token);
3771            if (stack != null) {
3772                return stack.willActivityBeVisibleLocked(token);
3773            }
3774            return false;
3775        }
3776    }
3777
3778    @Override
3779    public void overridePendingTransition(IBinder token, String packageName,
3780            int enterAnim, int exitAnim) {
3781        synchronized(this) {
3782            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3783            if (self == null) {
3784                return;
3785            }
3786
3787            final long origId = Binder.clearCallingIdentity();
3788
3789            if (self.state == ActivityState.RESUMED
3790                    || self.state == ActivityState.PAUSING) {
3791                mWindowManager.overridePendingAppTransition(packageName,
3792                        enterAnim, exitAnim, null);
3793            }
3794
3795            Binder.restoreCallingIdentity(origId);
3796        }
3797    }
3798
3799    /**
3800     * Main function for removing an existing process from the activity manager
3801     * as a result of that process going away.  Clears out all connections
3802     * to the process.
3803     */
3804    private final void handleAppDiedLocked(ProcessRecord app,
3805            boolean restarting, boolean allowRestart) {
3806        int pid = app.pid;
3807        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3808        if (!restarting) {
3809            removeLruProcessLocked(app);
3810            if (pid > 0) {
3811                ProcessList.remove(pid);
3812            }
3813        }
3814
3815        if (mProfileProc == app) {
3816            clearProfilerLocked();
3817        }
3818
3819        // Remove this application's activities from active lists.
3820        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3821
3822        app.activities.clear();
3823
3824        if (app.instrumentationClass != null) {
3825            Slog.w(TAG, "Crash of app " + app.processName
3826                  + " running instrumentation " + app.instrumentationClass);
3827            Bundle info = new Bundle();
3828            info.putString("shortMsg", "Process crashed.");
3829            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3830        }
3831
3832        if (!restarting) {
3833            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3834                // If there was nothing to resume, and we are not already
3835                // restarting this process, but there is a visible activity that
3836                // is hosted by the process...  then make sure all visible
3837                // activities are running, taking care of restarting this
3838                // process.
3839                if (hasVisibleActivities) {
3840                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3841                }
3842            }
3843        }
3844    }
3845
3846    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3847        IBinder threadBinder = thread.asBinder();
3848        // Find the application record.
3849        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3850            ProcessRecord rec = mLruProcesses.get(i);
3851            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3852                return i;
3853            }
3854        }
3855        return -1;
3856    }
3857
3858    final ProcessRecord getRecordForAppLocked(
3859            IApplicationThread thread) {
3860        if (thread == null) {
3861            return null;
3862        }
3863
3864        int appIndex = getLRURecordIndexForAppLocked(thread);
3865        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3866    }
3867
3868    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3869        // If there are no longer any background processes running,
3870        // and the app that died was not running instrumentation,
3871        // then tell everyone we are now low on memory.
3872        boolean haveBg = false;
3873        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3874            ProcessRecord rec = mLruProcesses.get(i);
3875            if (rec.thread != null
3876                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3877                haveBg = true;
3878                break;
3879            }
3880        }
3881
3882        if (!haveBg) {
3883            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3884            if (doReport) {
3885                long now = SystemClock.uptimeMillis();
3886                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3887                    doReport = false;
3888                } else {
3889                    mLastMemUsageReportTime = now;
3890                }
3891            }
3892            final ArrayList<ProcessMemInfo> memInfos
3893                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3894            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3895            long now = SystemClock.uptimeMillis();
3896            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3897                ProcessRecord rec = mLruProcesses.get(i);
3898                if (rec == dyingProc || rec.thread == null) {
3899                    continue;
3900                }
3901                if (doReport) {
3902                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3903                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3904                }
3905                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3906                    // The low memory report is overriding any current
3907                    // state for a GC request.  Make sure to do
3908                    // heavy/important/visible/foreground processes first.
3909                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3910                        rec.lastRequestedGc = 0;
3911                    } else {
3912                        rec.lastRequestedGc = rec.lastLowMemory;
3913                    }
3914                    rec.reportLowMemory = true;
3915                    rec.lastLowMemory = now;
3916                    mProcessesToGc.remove(rec);
3917                    addProcessToGcListLocked(rec);
3918                }
3919            }
3920            if (doReport) {
3921                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3922                mHandler.sendMessage(msg);
3923            }
3924            scheduleAppGcsLocked();
3925        }
3926    }
3927
3928    final void appDiedLocked(ProcessRecord app, int pid,
3929            IApplicationThread thread) {
3930
3931        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3932        synchronized (stats) {
3933            stats.noteProcessDiedLocked(app.info.uid, pid);
3934        }
3935
3936        // Clean up already done if the process has been re-started.
3937        if (app.pid == pid && app.thread != null &&
3938                app.thread.asBinder() == thread.asBinder()) {
3939            boolean doLowMem = app.instrumentationClass == null;
3940            boolean doOomAdj = doLowMem;
3941            if (!app.killedByAm) {
3942                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3943                        + ") has died.");
3944                mAllowLowerMemLevel = true;
3945            } else {
3946                // Note that we always want to do oom adj to update our state with the
3947                // new number of procs.
3948                mAllowLowerMemLevel = false;
3949                doLowMem = false;
3950            }
3951            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3952            if (DEBUG_CLEANUP) Slog.v(
3953                TAG, "Dying app: " + app + ", pid: " + pid
3954                + ", thread: " + thread.asBinder());
3955            handleAppDiedLocked(app, false, true);
3956
3957            if (doOomAdj) {
3958                updateOomAdjLocked();
3959            }
3960            if (doLowMem) {
3961                doLowMemReportIfNeededLocked(app);
3962            }
3963        } else if (app.pid != pid) {
3964            // A new process has already been started.
3965            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3966                    + ") has died and restarted (pid " + app.pid + ").");
3967            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3968        } else if (DEBUG_PROCESSES) {
3969            Slog.d(TAG, "Received spurious death notification for thread "
3970                    + thread.asBinder());
3971        }
3972    }
3973
3974    /**
3975     * If a stack trace dump file is configured, dump process stack traces.
3976     * @param clearTraces causes the dump file to be erased prior to the new
3977     *    traces being written, if true; when false, the new traces will be
3978     *    appended to any existing file content.
3979     * @param firstPids of dalvik VM processes to dump stack traces for first
3980     * @param lastPids of dalvik VM processes to dump stack traces for last
3981     * @param nativeProcs optional list of native process names to dump stack crawls
3982     * @return file containing stack traces, or null if no dump file is configured
3983     */
3984    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3985            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3986        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3987        if (tracesPath == null || tracesPath.length() == 0) {
3988            return null;
3989        }
3990
3991        File tracesFile = new File(tracesPath);
3992        try {
3993            File tracesDir = tracesFile.getParentFile();
3994            if (!tracesDir.exists()) {
3995                tracesFile.mkdirs();
3996                if (!SELinux.restorecon(tracesDir)) {
3997                    return null;
3998                }
3999            }
4000            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4001
4002            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4003            tracesFile.createNewFile();
4004            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4005        } catch (IOException e) {
4006            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4007            return null;
4008        }
4009
4010        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4011        return tracesFile;
4012    }
4013
4014    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4015            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4016        // Use a FileObserver to detect when traces finish writing.
4017        // The order of traces is considered important to maintain for legibility.
4018        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4019            @Override
4020            public synchronized void onEvent(int event, String path) { notify(); }
4021        };
4022
4023        try {
4024            observer.startWatching();
4025
4026            // First collect all of the stacks of the most important pids.
4027            if (firstPids != null) {
4028                try {
4029                    int num = firstPids.size();
4030                    for (int i = 0; i < num; i++) {
4031                        synchronized (observer) {
4032                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4033                            observer.wait(200);  // Wait for write-close, give up after 200msec
4034                        }
4035                    }
4036                } catch (InterruptedException e) {
4037                    Log.wtf(TAG, e);
4038                }
4039            }
4040
4041            // Next collect the stacks of the native pids
4042            if (nativeProcs != null) {
4043                int[] pids = Process.getPidsForCommands(nativeProcs);
4044                if (pids != null) {
4045                    for (int pid : pids) {
4046                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4047                    }
4048                }
4049            }
4050
4051            // Lastly, measure CPU usage.
4052            if (processCpuTracker != null) {
4053                processCpuTracker.init();
4054                System.gc();
4055                processCpuTracker.update();
4056                try {
4057                    synchronized (processCpuTracker) {
4058                        processCpuTracker.wait(500); // measure over 1/2 second.
4059                    }
4060                } catch (InterruptedException e) {
4061                }
4062                processCpuTracker.update();
4063
4064                // We'll take the stack crawls of just the top apps using CPU.
4065                final int N = processCpuTracker.countWorkingStats();
4066                int numProcs = 0;
4067                for (int i=0; i<N && numProcs<5; i++) {
4068                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4069                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4070                        numProcs++;
4071                        try {
4072                            synchronized (observer) {
4073                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4074                                observer.wait(200);  // Wait for write-close, give up after 200msec
4075                            }
4076                        } catch (InterruptedException e) {
4077                            Log.wtf(TAG, e);
4078                        }
4079
4080                    }
4081                }
4082            }
4083        } finally {
4084            observer.stopWatching();
4085        }
4086    }
4087
4088    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4089        if (true || IS_USER_BUILD) {
4090            return;
4091        }
4092        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4093        if (tracesPath == null || tracesPath.length() == 0) {
4094            return;
4095        }
4096
4097        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4098        StrictMode.allowThreadDiskWrites();
4099        try {
4100            final File tracesFile = new File(tracesPath);
4101            final File tracesDir = tracesFile.getParentFile();
4102            final File tracesTmp = new File(tracesDir, "__tmp__");
4103            try {
4104                if (!tracesDir.exists()) {
4105                    tracesFile.mkdirs();
4106                    if (!SELinux.restorecon(tracesDir.getPath())) {
4107                        return;
4108                    }
4109                }
4110                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4111
4112                if (tracesFile.exists()) {
4113                    tracesTmp.delete();
4114                    tracesFile.renameTo(tracesTmp);
4115                }
4116                StringBuilder sb = new StringBuilder();
4117                Time tobj = new Time();
4118                tobj.set(System.currentTimeMillis());
4119                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4120                sb.append(": ");
4121                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4122                sb.append(" since ");
4123                sb.append(msg);
4124                FileOutputStream fos = new FileOutputStream(tracesFile);
4125                fos.write(sb.toString().getBytes());
4126                if (app == null) {
4127                    fos.write("\n*** No application process!".getBytes());
4128                }
4129                fos.close();
4130                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4131            } catch (IOException e) {
4132                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4133                return;
4134            }
4135
4136            if (app != null) {
4137                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4138                firstPids.add(app.pid);
4139                dumpStackTraces(tracesPath, firstPids, null, null, null);
4140            }
4141
4142            File lastTracesFile = null;
4143            File curTracesFile = null;
4144            for (int i=9; i>=0; i--) {
4145                String name = String.format(Locale.US, "slow%02d.txt", i);
4146                curTracesFile = new File(tracesDir, name);
4147                if (curTracesFile.exists()) {
4148                    if (lastTracesFile != null) {
4149                        curTracesFile.renameTo(lastTracesFile);
4150                    } else {
4151                        curTracesFile.delete();
4152                    }
4153                }
4154                lastTracesFile = curTracesFile;
4155            }
4156            tracesFile.renameTo(curTracesFile);
4157            if (tracesTmp.exists()) {
4158                tracesTmp.renameTo(tracesFile);
4159            }
4160        } finally {
4161            StrictMode.setThreadPolicy(oldPolicy);
4162        }
4163    }
4164
4165    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4166            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4167        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4168        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4169
4170        if (mController != null) {
4171            try {
4172                // 0 == continue, -1 = kill process immediately
4173                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4174                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
4175            } catch (RemoteException e) {
4176                mController = null;
4177                Watchdog.getInstance().setActivityController(null);
4178            }
4179        }
4180
4181        long anrTime = SystemClock.uptimeMillis();
4182        if (MONITOR_CPU_USAGE) {
4183            updateCpuStatsNow();
4184        }
4185
4186        synchronized (this) {
4187            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4188            if (mShuttingDown) {
4189                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4190                return;
4191            } else if (app.notResponding) {
4192                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4193                return;
4194            } else if (app.crashing) {
4195                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4196                return;
4197            }
4198
4199            // In case we come through here for the same app before completing
4200            // this one, mark as anring now so we will bail out.
4201            app.notResponding = true;
4202
4203            // Log the ANR to the event log.
4204            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4205                    app.processName, app.info.flags, annotation);
4206
4207            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4208            firstPids.add(app.pid);
4209
4210            int parentPid = app.pid;
4211            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4212            if (parentPid != app.pid) firstPids.add(parentPid);
4213
4214            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4215
4216            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4217                ProcessRecord r = mLruProcesses.get(i);
4218                if (r != null && r.thread != null) {
4219                    int pid = r.pid;
4220                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4221                        if (r.persistent) {
4222                            firstPids.add(pid);
4223                        } else {
4224                            lastPids.put(pid, Boolean.TRUE);
4225                        }
4226                    }
4227                }
4228            }
4229        }
4230
4231        // Log the ANR to the main log.
4232        StringBuilder info = new StringBuilder();
4233        info.setLength(0);
4234        info.append("ANR in ").append(app.processName);
4235        if (activity != null && activity.shortComponentName != null) {
4236            info.append(" (").append(activity.shortComponentName).append(")");
4237        }
4238        info.append("\n");
4239        info.append("PID: ").append(app.pid).append("\n");
4240        if (annotation != null) {
4241            info.append("Reason: ").append(annotation).append("\n");
4242        }
4243        if (parent != null && parent != activity) {
4244            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4245        }
4246
4247        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4248
4249        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4250                NATIVE_STACKS_OF_INTEREST);
4251
4252        String cpuInfo = null;
4253        if (MONITOR_CPU_USAGE) {
4254            updateCpuStatsNow();
4255            synchronized (mProcessCpuThread) {
4256                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4257            }
4258            info.append(processCpuTracker.printCurrentLoad());
4259            info.append(cpuInfo);
4260        }
4261
4262        info.append(processCpuTracker.printCurrentState(anrTime));
4263
4264        Slog.e(TAG, info.toString());
4265        if (tracesFile == null) {
4266            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4267            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4268        }
4269
4270        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4271                cpuInfo, tracesFile, null);
4272
4273        if (mController != null) {
4274            try {
4275                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4276                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4277                if (res != 0) {
4278                    if (res < 0 && app.pid != MY_PID) {
4279                        Process.killProcess(app.pid);
4280                    } else {
4281                        synchronized (this) {
4282                            mServices.scheduleServiceTimeoutLocked(app);
4283                        }
4284                    }
4285                    return;
4286                }
4287            } catch (RemoteException e) {
4288                mController = null;
4289                Watchdog.getInstance().setActivityController(null);
4290            }
4291        }
4292
4293        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4294        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4295                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4296
4297        synchronized (this) {
4298            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4299                killUnneededProcessLocked(app, "background ANR");
4300                return;
4301            }
4302
4303            // Set the app's notResponding state, and look up the errorReportReceiver
4304            makeAppNotRespondingLocked(app,
4305                    activity != null ? activity.shortComponentName : null,
4306                    annotation != null ? "ANR " + annotation : "ANR",
4307                    info.toString());
4308
4309            // Bring up the infamous App Not Responding dialog
4310            Message msg = Message.obtain();
4311            HashMap<String, Object> map = new HashMap<String, Object>();
4312            msg.what = SHOW_NOT_RESPONDING_MSG;
4313            msg.obj = map;
4314            msg.arg1 = aboveSystem ? 1 : 0;
4315            map.put("app", app);
4316            if (activity != null) {
4317                map.put("activity", activity);
4318            }
4319
4320            mHandler.sendMessage(msg);
4321        }
4322    }
4323
4324    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4325        if (!mLaunchWarningShown) {
4326            mLaunchWarningShown = true;
4327            mHandler.post(new Runnable() {
4328                @Override
4329                public void run() {
4330                    synchronized (ActivityManagerService.this) {
4331                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4332                        d.show();
4333                        mHandler.postDelayed(new Runnable() {
4334                            @Override
4335                            public void run() {
4336                                synchronized (ActivityManagerService.this) {
4337                                    d.dismiss();
4338                                    mLaunchWarningShown = false;
4339                                }
4340                            }
4341                        }, 4000);
4342                    }
4343                }
4344            });
4345        }
4346    }
4347
4348    @Override
4349    public boolean clearApplicationUserData(final String packageName,
4350            final IPackageDataObserver observer, int userId) {
4351        enforceNotIsolatedCaller("clearApplicationUserData");
4352        int uid = Binder.getCallingUid();
4353        int pid = Binder.getCallingPid();
4354        userId = handleIncomingUser(pid, uid,
4355                userId, false, true, "clearApplicationUserData", null);
4356        long callingId = Binder.clearCallingIdentity();
4357        try {
4358            IPackageManager pm = AppGlobals.getPackageManager();
4359            int pkgUid = -1;
4360            synchronized(this) {
4361                try {
4362                    pkgUid = pm.getPackageUid(packageName, userId);
4363                } catch (RemoteException e) {
4364                }
4365                if (pkgUid == -1) {
4366                    Slog.w(TAG, "Invalid packageName: " + packageName);
4367                    if (observer != null) {
4368                        try {
4369                            observer.onRemoveCompleted(packageName, false);
4370                        } catch (RemoteException e) {
4371                            Slog.i(TAG, "Observer no longer exists.");
4372                        }
4373                    }
4374                    return false;
4375                }
4376                if (uid == pkgUid || checkComponentPermission(
4377                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4378                        pid, uid, -1, true)
4379                        == PackageManager.PERMISSION_GRANTED) {
4380                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4381                } else {
4382                    throw new SecurityException("PID " + pid + " does not have permission "
4383                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4384                                    + " of package " + packageName);
4385                }
4386            }
4387
4388            try {
4389                // Clear application user data
4390                pm.clearApplicationUserData(packageName, observer, userId);
4391
4392                // Remove all permissions granted from/to this package
4393                removeUriPermissionsForPackageLocked(packageName, userId, true);
4394
4395                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4396                        Uri.fromParts("package", packageName, null));
4397                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4398                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4399                        null, null, 0, null, null, null, false, false, userId);
4400            } catch (RemoteException e) {
4401            }
4402        } finally {
4403            Binder.restoreCallingIdentity(callingId);
4404        }
4405        return true;
4406    }
4407
4408    @Override
4409    public void killBackgroundProcesses(final String packageName, int userId) {
4410        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4411                != PackageManager.PERMISSION_GRANTED &&
4412                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4413                        != PackageManager.PERMISSION_GRANTED) {
4414            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4415                    + Binder.getCallingPid()
4416                    + ", uid=" + Binder.getCallingUid()
4417                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4418            Slog.w(TAG, msg);
4419            throw new SecurityException(msg);
4420        }
4421
4422        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4423                userId, true, true, "killBackgroundProcesses", null);
4424        long callingId = Binder.clearCallingIdentity();
4425        try {
4426            IPackageManager pm = AppGlobals.getPackageManager();
4427            synchronized(this) {
4428                int appId = -1;
4429                try {
4430                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4431                } catch (RemoteException e) {
4432                }
4433                if (appId == -1) {
4434                    Slog.w(TAG, "Invalid packageName: " + packageName);
4435                    return;
4436                }
4437                killPackageProcessesLocked(packageName, appId, userId,
4438                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4439            }
4440        } finally {
4441            Binder.restoreCallingIdentity(callingId);
4442        }
4443    }
4444
4445    @Override
4446    public void killAllBackgroundProcesses() {
4447        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4448                != PackageManager.PERMISSION_GRANTED) {
4449            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4450                    + Binder.getCallingPid()
4451                    + ", uid=" + Binder.getCallingUid()
4452                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4453            Slog.w(TAG, msg);
4454            throw new SecurityException(msg);
4455        }
4456
4457        long callingId = Binder.clearCallingIdentity();
4458        try {
4459            synchronized(this) {
4460                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4461                final int NP = mProcessNames.getMap().size();
4462                for (int ip=0; ip<NP; ip++) {
4463                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4464                    final int NA = apps.size();
4465                    for (int ia=0; ia<NA; ia++) {
4466                        ProcessRecord app = apps.valueAt(ia);
4467                        if (app.persistent) {
4468                            // we don't kill persistent processes
4469                            continue;
4470                        }
4471                        if (app.removed) {
4472                            procs.add(app);
4473                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4474                            app.removed = true;
4475                            procs.add(app);
4476                        }
4477                    }
4478                }
4479
4480                int N = procs.size();
4481                for (int i=0; i<N; i++) {
4482                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4483                }
4484                mAllowLowerMemLevel = true;
4485                updateOomAdjLocked();
4486                doLowMemReportIfNeededLocked(null);
4487            }
4488        } finally {
4489            Binder.restoreCallingIdentity(callingId);
4490        }
4491    }
4492
4493    @Override
4494    public void forceStopPackage(final String packageName, int userId) {
4495        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4496                != PackageManager.PERMISSION_GRANTED) {
4497            String msg = "Permission Denial: forceStopPackage() from pid="
4498                    + Binder.getCallingPid()
4499                    + ", uid=" + Binder.getCallingUid()
4500                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4501            Slog.w(TAG, msg);
4502            throw new SecurityException(msg);
4503        }
4504        final int callingPid = Binder.getCallingPid();
4505        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4506                userId, true, true, "forceStopPackage", null);
4507        long callingId = Binder.clearCallingIdentity();
4508        try {
4509            IPackageManager pm = AppGlobals.getPackageManager();
4510            synchronized(this) {
4511                int[] users = userId == UserHandle.USER_ALL
4512                        ? getUsersLocked() : new int[] { userId };
4513                for (int user : users) {
4514                    int pkgUid = -1;
4515                    try {
4516                        pkgUid = pm.getPackageUid(packageName, user);
4517                    } catch (RemoteException e) {
4518                    }
4519                    if (pkgUid == -1) {
4520                        Slog.w(TAG, "Invalid packageName: " + packageName);
4521                        continue;
4522                    }
4523                    try {
4524                        pm.setPackageStoppedState(packageName, true, user);
4525                    } catch (RemoteException e) {
4526                    } catch (IllegalArgumentException e) {
4527                        Slog.w(TAG, "Failed trying to unstop package "
4528                                + packageName + ": " + e);
4529                    }
4530                    if (isUserRunningLocked(user, false)) {
4531                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4532                    }
4533                }
4534            }
4535        } finally {
4536            Binder.restoreCallingIdentity(callingId);
4537        }
4538    }
4539
4540    /*
4541     * The pkg name and app id have to be specified.
4542     */
4543    @Override
4544    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4545        if (pkg == null) {
4546            return;
4547        }
4548        // Make sure the uid is valid.
4549        if (appid < 0) {
4550            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4551            return;
4552        }
4553        int callerUid = Binder.getCallingUid();
4554        // Only the system server can kill an application
4555        if (callerUid == Process.SYSTEM_UID) {
4556            // Post an aysnc message to kill the application
4557            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4558            msg.arg1 = appid;
4559            msg.arg2 = 0;
4560            Bundle bundle = new Bundle();
4561            bundle.putString("pkg", pkg);
4562            bundle.putString("reason", reason);
4563            msg.obj = bundle;
4564            mHandler.sendMessage(msg);
4565        } else {
4566            throw new SecurityException(callerUid + " cannot kill pkg: " +
4567                    pkg);
4568        }
4569    }
4570
4571    @Override
4572    public void closeSystemDialogs(String reason) {
4573        enforceNotIsolatedCaller("closeSystemDialogs");
4574
4575        final int pid = Binder.getCallingPid();
4576        final int uid = Binder.getCallingUid();
4577        final long origId = Binder.clearCallingIdentity();
4578        try {
4579            synchronized (this) {
4580                // Only allow this from foreground processes, so that background
4581                // applications can't abuse it to prevent system UI from being shown.
4582                if (uid >= Process.FIRST_APPLICATION_UID) {
4583                    ProcessRecord proc;
4584                    synchronized (mPidsSelfLocked) {
4585                        proc = mPidsSelfLocked.get(pid);
4586                    }
4587                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4588                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4589                                + " from background process " + proc);
4590                        return;
4591                    }
4592                }
4593                closeSystemDialogsLocked(reason);
4594            }
4595        } finally {
4596            Binder.restoreCallingIdentity(origId);
4597        }
4598    }
4599
4600    void closeSystemDialogsLocked(String reason) {
4601        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4602        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4603                | Intent.FLAG_RECEIVER_FOREGROUND);
4604        if (reason != null) {
4605            intent.putExtra("reason", reason);
4606        }
4607        mWindowManager.closeSystemDialogs(reason);
4608
4609        mStackSupervisor.closeSystemDialogsLocked();
4610
4611        broadcastIntentLocked(null, null, intent, null,
4612                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4613                Process.SYSTEM_UID, UserHandle.USER_ALL);
4614    }
4615
4616    @Override
4617    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4618        enforceNotIsolatedCaller("getProcessMemoryInfo");
4619        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4620        for (int i=pids.length-1; i>=0; i--) {
4621            ProcessRecord proc;
4622            int oomAdj;
4623            synchronized (this) {
4624                synchronized (mPidsSelfLocked) {
4625                    proc = mPidsSelfLocked.get(pids[i]);
4626                    oomAdj = proc != null ? proc.setAdj : 0;
4627                }
4628            }
4629            infos[i] = new Debug.MemoryInfo();
4630            Debug.getMemoryInfo(pids[i], infos[i]);
4631            if (proc != null) {
4632                synchronized (this) {
4633                    if (proc.thread != null && proc.setAdj == oomAdj) {
4634                        // Record this for posterity if the process has been stable.
4635                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4636                                infos[i].getTotalUss(), false, proc.pkgList);
4637                    }
4638                }
4639            }
4640        }
4641        return infos;
4642    }
4643
4644    @Override
4645    public long[] getProcessPss(int[] pids) {
4646        enforceNotIsolatedCaller("getProcessPss");
4647        long[] pss = new long[pids.length];
4648        for (int i=pids.length-1; i>=0; i--) {
4649            ProcessRecord proc;
4650            int oomAdj;
4651            synchronized (this) {
4652                synchronized (mPidsSelfLocked) {
4653                    proc = mPidsSelfLocked.get(pids[i]);
4654                    oomAdj = proc != null ? proc.setAdj : 0;
4655                }
4656            }
4657            long[] tmpUss = new long[1];
4658            pss[i] = Debug.getPss(pids[i], tmpUss);
4659            if (proc != null) {
4660                synchronized (this) {
4661                    if (proc.thread != null && proc.setAdj == oomAdj) {
4662                        // Record this for posterity if the process has been stable.
4663                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4664                    }
4665                }
4666            }
4667        }
4668        return pss;
4669    }
4670
4671    @Override
4672    public void killApplicationProcess(String processName, int uid) {
4673        if (processName == null) {
4674            return;
4675        }
4676
4677        int callerUid = Binder.getCallingUid();
4678        // Only the system server can kill an application
4679        if (callerUid == Process.SYSTEM_UID) {
4680            synchronized (this) {
4681                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4682                if (app != null && app.thread != null) {
4683                    try {
4684                        app.thread.scheduleSuicide();
4685                    } catch (RemoteException e) {
4686                        // If the other end already died, then our work here is done.
4687                    }
4688                } else {
4689                    Slog.w(TAG, "Process/uid not found attempting kill of "
4690                            + processName + " / " + uid);
4691                }
4692            }
4693        } else {
4694            throw new SecurityException(callerUid + " cannot kill app process: " +
4695                    processName);
4696        }
4697    }
4698
4699    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4700        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4701                false, true, false, false, UserHandle.getUserId(uid), reason);
4702        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4703                Uri.fromParts("package", packageName, null));
4704        if (!mProcessesReady) {
4705            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4706                    | Intent.FLAG_RECEIVER_FOREGROUND);
4707        }
4708        intent.putExtra(Intent.EXTRA_UID, uid);
4709        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4710        broadcastIntentLocked(null, null, intent,
4711                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4712                false, false,
4713                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4714    }
4715
4716    private void forceStopUserLocked(int userId, String reason) {
4717        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4718        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4719        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4720                | Intent.FLAG_RECEIVER_FOREGROUND);
4721        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4722        broadcastIntentLocked(null, null, intent,
4723                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4724                false, false,
4725                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4726    }
4727
4728    private final boolean killPackageProcessesLocked(String packageName, int appId,
4729            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4730            boolean doit, boolean evenPersistent, String reason) {
4731        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4732
4733        // Remove all processes this package may have touched: all with the
4734        // same UID (except for the system or root user), and all whose name
4735        // matches the package name.
4736        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4737        final int NP = mProcessNames.getMap().size();
4738        for (int ip=0; ip<NP; ip++) {
4739            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4740            final int NA = apps.size();
4741            for (int ia=0; ia<NA; ia++) {
4742                ProcessRecord app = apps.valueAt(ia);
4743                if (app.persistent && !evenPersistent) {
4744                    // we don't kill persistent processes
4745                    continue;
4746                }
4747                if (app.removed) {
4748                    if (doit) {
4749                        procs.add(app);
4750                    }
4751                    continue;
4752                }
4753
4754                // Skip process if it doesn't meet our oom adj requirement.
4755                if (app.setAdj < minOomAdj) {
4756                    continue;
4757                }
4758
4759                // If no package is specified, we call all processes under the
4760                // give user id.
4761                if (packageName == null) {
4762                    if (app.userId != userId) {
4763                        continue;
4764                    }
4765                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4766                        continue;
4767                    }
4768                // Package has been specified, we want to hit all processes
4769                // that match it.  We need to qualify this by the processes
4770                // that are running under the specified app and user ID.
4771                } else {
4772                    if (UserHandle.getAppId(app.uid) != appId) {
4773                        continue;
4774                    }
4775                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4776                        continue;
4777                    }
4778                    if (!app.pkgList.containsKey(packageName)) {
4779                        continue;
4780                    }
4781                }
4782
4783                // Process has passed all conditions, kill it!
4784                if (!doit) {
4785                    return true;
4786                }
4787                app.removed = true;
4788                procs.add(app);
4789            }
4790        }
4791
4792        int N = procs.size();
4793        for (int i=0; i<N; i++) {
4794            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4795        }
4796        updateOomAdjLocked();
4797        return N > 0;
4798    }
4799
4800    private final boolean forceStopPackageLocked(String name, int appId,
4801            boolean callerWillRestart, boolean purgeCache, boolean doit,
4802            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4803        int i;
4804        int N;
4805
4806        if (userId == UserHandle.USER_ALL && name == null) {
4807            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4808        }
4809
4810        if (appId < 0 && name != null) {
4811            try {
4812                appId = UserHandle.getAppId(
4813                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4814            } catch (RemoteException e) {
4815            }
4816        }
4817
4818        if (doit) {
4819            if (name != null) {
4820                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4821                        + " user=" + userId + ": " + reason);
4822            } else {
4823                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4824            }
4825
4826            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4827            for (int ip=pmap.size()-1; ip>=0; ip--) {
4828                SparseArray<Long> ba = pmap.valueAt(ip);
4829                for (i=ba.size()-1; i>=0; i--) {
4830                    boolean remove = false;
4831                    final int entUid = ba.keyAt(i);
4832                    if (name != null) {
4833                        if (userId == UserHandle.USER_ALL) {
4834                            if (UserHandle.getAppId(entUid) == appId) {
4835                                remove = true;
4836                            }
4837                        } else {
4838                            if (entUid == UserHandle.getUid(userId, appId)) {
4839                                remove = true;
4840                            }
4841                        }
4842                    } else if (UserHandle.getUserId(entUid) == userId) {
4843                        remove = true;
4844                    }
4845                    if (remove) {
4846                        ba.removeAt(i);
4847                    }
4848                }
4849                if (ba.size() == 0) {
4850                    pmap.removeAt(ip);
4851                }
4852            }
4853        }
4854
4855        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4856                -100, callerWillRestart, true, doit, evenPersistent,
4857                name == null ? ("stop user " + userId) : ("stop " + name));
4858
4859        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4860            if (!doit) {
4861                return true;
4862            }
4863            didSomething = true;
4864        }
4865
4866        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4867            if (!doit) {
4868                return true;
4869            }
4870            didSomething = true;
4871        }
4872
4873        if (name == null) {
4874            // Remove all sticky broadcasts from this user.
4875            mStickyBroadcasts.remove(userId);
4876        }
4877
4878        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4879        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4880                userId, providers)) {
4881            if (!doit) {
4882                return true;
4883            }
4884            didSomething = true;
4885        }
4886        N = providers.size();
4887        for (i=0; i<N; i++) {
4888            removeDyingProviderLocked(null, providers.get(i), true);
4889        }
4890
4891        // Remove transient permissions granted from/to this package/user
4892        removeUriPermissionsForPackageLocked(name, userId, false);
4893
4894        if (name == null || uninstalling) {
4895            // Remove pending intents.  For now we only do this when force
4896            // stopping users, because we have some problems when doing this
4897            // for packages -- app widgets are not currently cleaned up for
4898            // such packages, so they can be left with bad pending intents.
4899            if (mIntentSenderRecords.size() > 0) {
4900                Iterator<WeakReference<PendingIntentRecord>> it
4901                        = mIntentSenderRecords.values().iterator();
4902                while (it.hasNext()) {
4903                    WeakReference<PendingIntentRecord> wpir = it.next();
4904                    if (wpir == null) {
4905                        it.remove();
4906                        continue;
4907                    }
4908                    PendingIntentRecord pir = wpir.get();
4909                    if (pir == null) {
4910                        it.remove();
4911                        continue;
4912                    }
4913                    if (name == null) {
4914                        // Stopping user, remove all objects for the user.
4915                        if (pir.key.userId != userId) {
4916                            // Not the same user, skip it.
4917                            continue;
4918                        }
4919                    } else {
4920                        if (UserHandle.getAppId(pir.uid) != appId) {
4921                            // Different app id, skip it.
4922                            continue;
4923                        }
4924                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4925                            // Different user, skip it.
4926                            continue;
4927                        }
4928                        if (!pir.key.packageName.equals(name)) {
4929                            // Different package, skip it.
4930                            continue;
4931                        }
4932                    }
4933                    if (!doit) {
4934                        return true;
4935                    }
4936                    didSomething = true;
4937                    it.remove();
4938                    pir.canceled = true;
4939                    if (pir.key.activity != null) {
4940                        pir.key.activity.pendingResults.remove(pir.ref);
4941                    }
4942                }
4943            }
4944        }
4945
4946        if (doit) {
4947            if (purgeCache && name != null) {
4948                AttributeCache ac = AttributeCache.instance();
4949                if (ac != null) {
4950                    ac.removePackage(name);
4951                }
4952            }
4953            if (mBooted) {
4954                mStackSupervisor.resumeTopActivitiesLocked();
4955                mStackSupervisor.scheduleIdleLocked();
4956            }
4957        }
4958
4959        return didSomething;
4960    }
4961
4962    private final boolean removeProcessLocked(ProcessRecord app,
4963            boolean callerWillRestart, boolean allowRestart, String reason) {
4964        final String name = app.processName;
4965        final int uid = app.uid;
4966        if (DEBUG_PROCESSES) Slog.d(
4967            TAG, "Force removing proc " + app.toShortString() + " (" + name
4968            + "/" + uid + ")");
4969
4970        mProcessNames.remove(name, uid);
4971        mIsolatedProcesses.remove(app.uid);
4972        if (mHeavyWeightProcess == app) {
4973            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4974                    mHeavyWeightProcess.userId, 0));
4975            mHeavyWeightProcess = null;
4976        }
4977        boolean needRestart = false;
4978        if (app.pid > 0 && app.pid != MY_PID) {
4979            int pid = app.pid;
4980            synchronized (mPidsSelfLocked) {
4981                mPidsSelfLocked.remove(pid);
4982                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4983            }
4984            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
4985                    app.processName, app.info.uid);
4986            if (app.isolated) {
4987                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
4988            }
4989            killUnneededProcessLocked(app, reason);
4990            handleAppDiedLocked(app, true, allowRestart);
4991            removeLruProcessLocked(app);
4992
4993            if (app.persistent && !app.isolated) {
4994                if (!callerWillRestart) {
4995                    addAppLocked(app.info, false);
4996                } else {
4997                    needRestart = true;
4998                }
4999            }
5000        } else {
5001            mRemovedProcesses.add(app);
5002        }
5003
5004        return needRestart;
5005    }
5006
5007    private final void processStartTimedOutLocked(ProcessRecord app) {
5008        final int pid = app.pid;
5009        boolean gone = false;
5010        synchronized (mPidsSelfLocked) {
5011            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5012            if (knownApp != null && knownApp.thread == null) {
5013                mPidsSelfLocked.remove(pid);
5014                gone = true;
5015            }
5016        }
5017
5018        if (gone) {
5019            Slog.w(TAG, "Process " + app + " failed to attach");
5020            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5021                    pid, app.uid, app.processName);
5022            mProcessNames.remove(app.processName, app.uid);
5023            mIsolatedProcesses.remove(app.uid);
5024            if (mHeavyWeightProcess == app) {
5025                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5026                        mHeavyWeightProcess.userId, 0));
5027                mHeavyWeightProcess = null;
5028            }
5029            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5030                    app.processName, app.info.uid);
5031            if (app.isolated) {
5032                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5033            }
5034            // Take care of any launching providers waiting for this process.
5035            checkAppInLaunchingProvidersLocked(app, true);
5036            // Take care of any services that are waiting for the process.
5037            mServices.processStartTimedOutLocked(app);
5038            killUnneededProcessLocked(app, "start timeout");
5039            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5040                Slog.w(TAG, "Unattached app died before backup, skipping");
5041                try {
5042                    IBackupManager bm = IBackupManager.Stub.asInterface(
5043                            ServiceManager.getService(Context.BACKUP_SERVICE));
5044                    bm.agentDisconnected(app.info.packageName);
5045                } catch (RemoteException e) {
5046                    // Can't happen; the backup manager is local
5047                }
5048            }
5049            if (isPendingBroadcastProcessLocked(pid)) {
5050                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5051                skipPendingBroadcastLocked(pid);
5052            }
5053        } else {
5054            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5055        }
5056    }
5057
5058    private final boolean attachApplicationLocked(IApplicationThread thread,
5059            int pid) {
5060
5061        // Find the application record that is being attached...  either via
5062        // the pid if we are running in multiple processes, or just pull the
5063        // next app record if we are emulating process with anonymous threads.
5064        ProcessRecord app;
5065        if (pid != MY_PID && pid >= 0) {
5066            synchronized (mPidsSelfLocked) {
5067                app = mPidsSelfLocked.get(pid);
5068            }
5069        } else {
5070            app = null;
5071        }
5072
5073        if (app == null) {
5074            Slog.w(TAG, "No pending application record for pid " + pid
5075                    + " (IApplicationThread " + thread + "); dropping process");
5076            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5077            if (pid > 0 && pid != MY_PID) {
5078                Process.killProcessQuiet(pid);
5079            } else {
5080                try {
5081                    thread.scheduleExit();
5082                } catch (Exception e) {
5083                    // Ignore exceptions.
5084                }
5085            }
5086            return false;
5087        }
5088
5089        // If this application record is still attached to a previous
5090        // process, clean it up now.
5091        if (app.thread != null) {
5092            handleAppDiedLocked(app, true, true);
5093        }
5094
5095        // Tell the process all about itself.
5096
5097        if (localLOGV) Slog.v(
5098                TAG, "Binding process pid " + pid + " to record " + app);
5099
5100        final String processName = app.processName;
5101        try {
5102            AppDeathRecipient adr = new AppDeathRecipient(
5103                    app, pid, thread);
5104            thread.asBinder().linkToDeath(adr, 0);
5105            app.deathRecipient = adr;
5106        } catch (RemoteException e) {
5107            app.resetPackageList(mProcessStats);
5108            startProcessLocked(app, "link fail", processName);
5109            return false;
5110        }
5111
5112        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5113
5114        app.makeActive(thread, mProcessStats);
5115        app.curAdj = app.setAdj = -100;
5116        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5117        app.forcingToForeground = null;
5118        updateProcessForegroundLocked(app, false, false);
5119        app.hasShownUi = false;
5120        app.debugging = false;
5121        app.cached = false;
5122
5123        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5124
5125        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5126        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5127
5128        if (!normalMode) {
5129            Slog.i(TAG, "Launching preboot mode app: " + app);
5130        }
5131
5132        if (localLOGV) Slog.v(
5133            TAG, "New app record " + app
5134            + " thread=" + thread.asBinder() + " pid=" + pid);
5135        try {
5136            int testMode = IApplicationThread.DEBUG_OFF;
5137            if (mDebugApp != null && mDebugApp.equals(processName)) {
5138                testMode = mWaitForDebugger
5139                    ? IApplicationThread.DEBUG_WAIT
5140                    : IApplicationThread.DEBUG_ON;
5141                app.debugging = true;
5142                if (mDebugTransient) {
5143                    mDebugApp = mOrigDebugApp;
5144                    mWaitForDebugger = mOrigWaitForDebugger;
5145                }
5146            }
5147            String profileFile = app.instrumentationProfileFile;
5148            ParcelFileDescriptor profileFd = null;
5149            boolean profileAutoStop = false;
5150            if (mProfileApp != null && mProfileApp.equals(processName)) {
5151                mProfileProc = app;
5152                profileFile = mProfileFile;
5153                profileFd = mProfileFd;
5154                profileAutoStop = mAutoStopProfiler;
5155            }
5156            boolean enableOpenGlTrace = false;
5157            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5158                enableOpenGlTrace = true;
5159                mOpenGlTraceApp = null;
5160            }
5161
5162            // If the app is being launched for restore or full backup, set it up specially
5163            boolean isRestrictedBackupMode = false;
5164            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5165                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5166                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5167                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5168            }
5169
5170            ensurePackageDexOpt(app.instrumentationInfo != null
5171                    ? app.instrumentationInfo.packageName
5172                    : app.info.packageName);
5173            if (app.instrumentationClass != null) {
5174                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5175            }
5176            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5177                    + processName + " with config " + mConfiguration);
5178            ApplicationInfo appInfo = app.instrumentationInfo != null
5179                    ? app.instrumentationInfo : app.info;
5180            app.compat = compatibilityInfoForPackageLocked(appInfo);
5181            if (profileFd != null) {
5182                profileFd = profileFd.dup();
5183            }
5184            thread.bindApplication(processName, appInfo, providers,
5185                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5186                    app.instrumentationArguments, app.instrumentationWatcher,
5187                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5188                    isRestrictedBackupMode || !normalMode, app.persistent,
5189                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5190                    mCoreSettingsObserver.getCoreSettingsLocked());
5191            updateLruProcessLocked(app, false, null);
5192            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5193        } catch (Exception e) {
5194            // todo: Yikes!  What should we do?  For now we will try to
5195            // start another process, but that could easily get us in
5196            // an infinite loop of restarting processes...
5197            Slog.w(TAG, "Exception thrown during bind!", e);
5198
5199            app.resetPackageList(mProcessStats);
5200            app.unlinkDeathRecipient();
5201            startProcessLocked(app, "bind fail", processName);
5202            return false;
5203        }
5204
5205        // Remove this record from the list of starting applications.
5206        mPersistentStartingProcesses.remove(app);
5207        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5208                "Attach application locked removing on hold: " + app);
5209        mProcessesOnHold.remove(app);
5210
5211        boolean badApp = false;
5212        boolean didSomething = false;
5213
5214        // See if the top visible activity is waiting to run in this process...
5215        if (normalMode) {
5216            try {
5217                if (mStackSupervisor.attachApplicationLocked(app)) {
5218                    didSomething = true;
5219                }
5220            } catch (Exception e) {
5221                badApp = true;
5222            }
5223        }
5224
5225        // Find any services that should be running in this process...
5226        if (!badApp) {
5227            try {
5228                didSomething |= mServices.attachApplicationLocked(app, processName);
5229            } catch (Exception e) {
5230                badApp = true;
5231            }
5232        }
5233
5234        // Check if a next-broadcast receiver is in this process...
5235        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5236            try {
5237                didSomething |= sendPendingBroadcastsLocked(app);
5238            } catch (Exception e) {
5239                // If the app died trying to launch the receiver we declare it 'bad'
5240                badApp = true;
5241            }
5242        }
5243
5244        // Check whether the next backup agent is in this process...
5245        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5246            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5247            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5248            try {
5249                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5250                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5251                        mBackupTarget.backupMode);
5252            } catch (Exception e) {
5253                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5254                e.printStackTrace();
5255            }
5256        }
5257
5258        if (badApp) {
5259            // todo: Also need to kill application to deal with all
5260            // kinds of exceptions.
5261            handleAppDiedLocked(app, false, true);
5262            return false;
5263        }
5264
5265        if (!didSomething) {
5266            updateOomAdjLocked();
5267        }
5268
5269        return true;
5270    }
5271
5272    @Override
5273    public final void attachApplication(IApplicationThread thread) {
5274        synchronized (this) {
5275            int callingPid = Binder.getCallingPid();
5276            final long origId = Binder.clearCallingIdentity();
5277            attachApplicationLocked(thread, callingPid);
5278            Binder.restoreCallingIdentity(origId);
5279        }
5280    }
5281
5282    @Override
5283    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5284        final long origId = Binder.clearCallingIdentity();
5285        synchronized (this) {
5286            ActivityStack stack = ActivityRecord.getStackLocked(token);
5287            if (stack != null) {
5288                ActivityRecord r =
5289                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5290                if (stopProfiling) {
5291                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5292                        try {
5293                            mProfileFd.close();
5294                        } catch (IOException e) {
5295                        }
5296                        clearProfilerLocked();
5297                    }
5298                }
5299            }
5300        }
5301        Binder.restoreCallingIdentity(origId);
5302    }
5303
5304    void enableScreenAfterBoot() {
5305        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5306                SystemClock.uptimeMillis());
5307        mWindowManager.enableScreenAfterBoot();
5308
5309        synchronized (this) {
5310            updateEventDispatchingLocked();
5311        }
5312    }
5313
5314    @Override
5315    public void showBootMessage(final CharSequence msg, final boolean always) {
5316        enforceNotIsolatedCaller("showBootMessage");
5317        mWindowManager.showBootMessage(msg, always);
5318    }
5319
5320    @Override
5321    public void dismissKeyguardOnNextActivity() {
5322        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5323        final long token = Binder.clearCallingIdentity();
5324        try {
5325            synchronized (this) {
5326                if (DEBUG_LOCKSCREEN) logLockScreen("");
5327                if (mLockScreenShown) {
5328                    mLockScreenShown = false;
5329                    comeOutOfSleepIfNeededLocked();
5330                }
5331                mStackSupervisor.setDismissKeyguard(true);
5332            }
5333        } finally {
5334            Binder.restoreCallingIdentity(token);
5335        }
5336    }
5337
5338    final void finishBooting() {
5339        // Register receivers to handle package update events
5340        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5341
5342        synchronized (this) {
5343            // Ensure that any processes we had put on hold are now started
5344            // up.
5345            final int NP = mProcessesOnHold.size();
5346            if (NP > 0) {
5347                ArrayList<ProcessRecord> procs =
5348                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5349                for (int ip=0; ip<NP; ip++) {
5350                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5351                            + procs.get(ip));
5352                    startProcessLocked(procs.get(ip), "on-hold", null);
5353                }
5354            }
5355
5356            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5357                // Start looking for apps that are abusing wake locks.
5358                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5359                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5360                // Tell anyone interested that we are done booting!
5361                SystemProperties.set("sys.boot_completed", "1");
5362                SystemProperties.set("dev.bootcomplete", "1");
5363                for (int i=0; i<mStartedUsers.size(); i++) {
5364                    UserStartedState uss = mStartedUsers.valueAt(i);
5365                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5366                        uss.mState = UserStartedState.STATE_RUNNING;
5367                        final int userId = mStartedUsers.keyAt(i);
5368                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5369                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5370                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5371                        broadcastIntentLocked(null, null, intent, null,
5372                                new IIntentReceiver.Stub() {
5373                                    @Override
5374                                    public void performReceive(Intent intent, int resultCode,
5375                                            String data, Bundle extras, boolean ordered,
5376                                            boolean sticky, int sendingUser) {
5377                                        synchronized (ActivityManagerService.this) {
5378                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5379                                                    true, false);
5380                                        }
5381                                    }
5382                                },
5383                                0, null, null,
5384                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5385                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5386                                userId);
5387                    }
5388                }
5389                scheduleStartProfilesLocked();
5390            }
5391        }
5392    }
5393
5394    final void ensureBootCompleted() {
5395        boolean booting;
5396        boolean enableScreen;
5397        synchronized (this) {
5398            booting = mBooting;
5399            mBooting = false;
5400            enableScreen = !mBooted;
5401            mBooted = true;
5402        }
5403
5404        if (booting) {
5405            finishBooting();
5406        }
5407
5408        if (enableScreen) {
5409            enableScreenAfterBoot();
5410        }
5411    }
5412
5413    @Override
5414    public final void activityResumed(IBinder token) {
5415        final long origId = Binder.clearCallingIdentity();
5416        synchronized(this) {
5417            ActivityStack stack = ActivityRecord.getStackLocked(token);
5418            if (stack != null) {
5419                ActivityRecord.activityResumedLocked(token);
5420            }
5421        }
5422        Binder.restoreCallingIdentity(origId);
5423    }
5424
5425    @Override
5426    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5427        final long origId = Binder.clearCallingIdentity();
5428        synchronized(this) {
5429            ActivityStack stack = ActivityRecord.getStackLocked(token);
5430            if (stack != null) {
5431                stack.activityPausedLocked(token, false, persistentState);
5432            }
5433        }
5434        Binder.restoreCallingIdentity(origId);
5435    }
5436
5437    @Override
5438    public final void activityStopped(IBinder token, Bundle icicle,
5439            PersistableBundle persistentState, CharSequence description) {
5440        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5441
5442        // Refuse possible leaked file descriptors
5443        if (icicle != null && icicle.hasFileDescriptors()) {
5444            throw new IllegalArgumentException("File descriptors passed in Bundle");
5445        }
5446
5447        final long origId = Binder.clearCallingIdentity();
5448
5449        synchronized (this) {
5450            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5451            if (r != null) {
5452                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5453            }
5454        }
5455
5456        trimApplications();
5457
5458        Binder.restoreCallingIdentity(origId);
5459    }
5460
5461    @Override
5462    public final void activityDestroyed(IBinder token) {
5463        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5464        synchronized (this) {
5465            ActivityStack stack = ActivityRecord.getStackLocked(token);
5466            if (stack != null) {
5467                stack.activityDestroyedLocked(token);
5468            }
5469        }
5470    }
5471
5472    @Override
5473    public String getCallingPackage(IBinder token) {
5474        synchronized (this) {
5475            ActivityRecord r = getCallingRecordLocked(token);
5476            return r != null ? r.info.packageName : null;
5477        }
5478    }
5479
5480    @Override
5481    public ComponentName getCallingActivity(IBinder token) {
5482        synchronized (this) {
5483            ActivityRecord r = getCallingRecordLocked(token);
5484            return r != null ? r.intent.getComponent() : null;
5485        }
5486    }
5487
5488    private ActivityRecord getCallingRecordLocked(IBinder token) {
5489        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5490        if (r == null) {
5491            return null;
5492        }
5493        return r.resultTo;
5494    }
5495
5496    @Override
5497    public ComponentName getActivityClassForToken(IBinder token) {
5498        synchronized(this) {
5499            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5500            if (r == null) {
5501                return null;
5502            }
5503            return r.intent.getComponent();
5504        }
5505    }
5506
5507    @Override
5508    public String getPackageForToken(IBinder token) {
5509        synchronized(this) {
5510            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5511            if (r == null) {
5512                return null;
5513            }
5514            return r.packageName;
5515        }
5516    }
5517
5518    @Override
5519    public IIntentSender getIntentSender(int type,
5520            String packageName, IBinder token, String resultWho,
5521            int requestCode, Intent[] intents, String[] resolvedTypes,
5522            int flags, Bundle options, int userId) {
5523        enforceNotIsolatedCaller("getIntentSender");
5524        // Refuse possible leaked file descriptors
5525        if (intents != null) {
5526            if (intents.length < 1) {
5527                throw new IllegalArgumentException("Intents array length must be >= 1");
5528            }
5529            for (int i=0; i<intents.length; i++) {
5530                Intent intent = intents[i];
5531                if (intent != null) {
5532                    if (intent.hasFileDescriptors()) {
5533                        throw new IllegalArgumentException("File descriptors passed in Intent");
5534                    }
5535                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5536                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5537                        throw new IllegalArgumentException(
5538                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5539                    }
5540                    intents[i] = new Intent(intent);
5541                }
5542            }
5543            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5544                throw new IllegalArgumentException(
5545                        "Intent array length does not match resolvedTypes length");
5546            }
5547        }
5548        if (options != null) {
5549            if (options.hasFileDescriptors()) {
5550                throw new IllegalArgumentException("File descriptors passed in options");
5551            }
5552        }
5553
5554        synchronized(this) {
5555            int callingUid = Binder.getCallingUid();
5556            int origUserId = userId;
5557            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5558                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5559                    "getIntentSender", null);
5560            if (origUserId == UserHandle.USER_CURRENT) {
5561                // We don't want to evaluate this until the pending intent is
5562                // actually executed.  However, we do want to always do the
5563                // security checking for it above.
5564                userId = UserHandle.USER_CURRENT;
5565            }
5566            try {
5567                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5568                    int uid = AppGlobals.getPackageManager()
5569                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5570                    if (!UserHandle.isSameApp(callingUid, uid)) {
5571                        String msg = "Permission Denial: getIntentSender() from pid="
5572                            + Binder.getCallingPid()
5573                            + ", uid=" + Binder.getCallingUid()
5574                            + ", (need uid=" + uid + ")"
5575                            + " is not allowed to send as package " + packageName;
5576                        Slog.w(TAG, msg);
5577                        throw new SecurityException(msg);
5578                    }
5579                }
5580
5581                return getIntentSenderLocked(type, packageName, callingUid, userId,
5582                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5583
5584            } catch (RemoteException e) {
5585                throw new SecurityException(e);
5586            }
5587        }
5588    }
5589
5590    IIntentSender getIntentSenderLocked(int type, String packageName,
5591            int callingUid, int userId, IBinder token, String resultWho,
5592            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5593            Bundle options) {
5594        if (DEBUG_MU)
5595            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5596        ActivityRecord activity = null;
5597        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5598            activity = ActivityRecord.isInStackLocked(token);
5599            if (activity == null) {
5600                return null;
5601            }
5602            if (activity.finishing) {
5603                return null;
5604            }
5605        }
5606
5607        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5608        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5609        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5610        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5611                |PendingIntent.FLAG_UPDATE_CURRENT);
5612
5613        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5614                type, packageName, activity, resultWho,
5615                requestCode, intents, resolvedTypes, flags, options, userId);
5616        WeakReference<PendingIntentRecord> ref;
5617        ref = mIntentSenderRecords.get(key);
5618        PendingIntentRecord rec = ref != null ? ref.get() : null;
5619        if (rec != null) {
5620            if (!cancelCurrent) {
5621                if (updateCurrent) {
5622                    if (rec.key.requestIntent != null) {
5623                        rec.key.requestIntent.replaceExtras(intents != null ?
5624                                intents[intents.length - 1] : null);
5625                    }
5626                    if (intents != null) {
5627                        intents[intents.length-1] = rec.key.requestIntent;
5628                        rec.key.allIntents = intents;
5629                        rec.key.allResolvedTypes = resolvedTypes;
5630                    } else {
5631                        rec.key.allIntents = null;
5632                        rec.key.allResolvedTypes = null;
5633                    }
5634                }
5635                return rec;
5636            }
5637            rec.canceled = true;
5638            mIntentSenderRecords.remove(key);
5639        }
5640        if (noCreate) {
5641            return rec;
5642        }
5643        rec = new PendingIntentRecord(this, key, callingUid);
5644        mIntentSenderRecords.put(key, rec.ref);
5645        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5646            if (activity.pendingResults == null) {
5647                activity.pendingResults
5648                        = new HashSet<WeakReference<PendingIntentRecord>>();
5649            }
5650            activity.pendingResults.add(rec.ref);
5651        }
5652        return rec;
5653    }
5654
5655    @Override
5656    public void cancelIntentSender(IIntentSender sender) {
5657        if (!(sender instanceof PendingIntentRecord)) {
5658            return;
5659        }
5660        synchronized(this) {
5661            PendingIntentRecord rec = (PendingIntentRecord)sender;
5662            try {
5663                int uid = AppGlobals.getPackageManager()
5664                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5665                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5666                    String msg = "Permission Denial: cancelIntentSender() from pid="
5667                        + Binder.getCallingPid()
5668                        + ", uid=" + Binder.getCallingUid()
5669                        + " is not allowed to cancel packges "
5670                        + rec.key.packageName;
5671                    Slog.w(TAG, msg);
5672                    throw new SecurityException(msg);
5673                }
5674            } catch (RemoteException e) {
5675                throw new SecurityException(e);
5676            }
5677            cancelIntentSenderLocked(rec, true);
5678        }
5679    }
5680
5681    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5682        rec.canceled = true;
5683        mIntentSenderRecords.remove(rec.key);
5684        if (cleanActivity && rec.key.activity != null) {
5685            rec.key.activity.pendingResults.remove(rec.ref);
5686        }
5687    }
5688
5689    @Override
5690    public String getPackageForIntentSender(IIntentSender pendingResult) {
5691        if (!(pendingResult instanceof PendingIntentRecord)) {
5692            return null;
5693        }
5694        try {
5695            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5696            return res.key.packageName;
5697        } catch (ClassCastException e) {
5698        }
5699        return null;
5700    }
5701
5702    @Override
5703    public int getUidForIntentSender(IIntentSender sender) {
5704        if (sender instanceof PendingIntentRecord) {
5705            try {
5706                PendingIntentRecord res = (PendingIntentRecord)sender;
5707                return res.uid;
5708            } catch (ClassCastException e) {
5709            }
5710        }
5711        return -1;
5712    }
5713
5714    @Override
5715    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5716        if (!(pendingResult instanceof PendingIntentRecord)) {
5717            return false;
5718        }
5719        try {
5720            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5721            if (res.key.allIntents == null) {
5722                return false;
5723            }
5724            for (int i=0; i<res.key.allIntents.length; i++) {
5725                Intent intent = res.key.allIntents[i];
5726                if (intent.getPackage() != null && intent.getComponent() != null) {
5727                    return false;
5728                }
5729            }
5730            return true;
5731        } catch (ClassCastException e) {
5732        }
5733        return false;
5734    }
5735
5736    @Override
5737    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5738        if (!(pendingResult instanceof PendingIntentRecord)) {
5739            return false;
5740        }
5741        try {
5742            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5743            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5744                return true;
5745            }
5746            return false;
5747        } catch (ClassCastException e) {
5748        }
5749        return false;
5750    }
5751
5752    @Override
5753    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5754        if (!(pendingResult instanceof PendingIntentRecord)) {
5755            return null;
5756        }
5757        try {
5758            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5759            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5760        } catch (ClassCastException e) {
5761        }
5762        return null;
5763    }
5764
5765    @Override
5766    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5767        if (!(pendingResult instanceof PendingIntentRecord)) {
5768            return null;
5769        }
5770        try {
5771            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5772            Intent intent = res.key.requestIntent;
5773            if (intent != null) {
5774                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5775                        || res.lastTagPrefix.equals(prefix))) {
5776                    return res.lastTag;
5777                }
5778                res.lastTagPrefix = prefix;
5779                StringBuilder sb = new StringBuilder(128);
5780                if (prefix != null) {
5781                    sb.append(prefix);
5782                }
5783                if (intent.getAction() != null) {
5784                    sb.append(intent.getAction());
5785                } else if (intent.getComponent() != null) {
5786                    intent.getComponent().appendShortString(sb);
5787                } else {
5788                    sb.append("?");
5789                }
5790                return res.lastTag = sb.toString();
5791            }
5792        } catch (ClassCastException e) {
5793        }
5794        return null;
5795    }
5796
5797    @Override
5798    public void setProcessLimit(int max) {
5799        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5800                "setProcessLimit()");
5801        synchronized (this) {
5802            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5803            mProcessLimitOverride = max;
5804        }
5805        trimApplications();
5806    }
5807
5808    @Override
5809    public int getProcessLimit() {
5810        synchronized (this) {
5811            return mProcessLimitOverride;
5812        }
5813    }
5814
5815    void foregroundTokenDied(ForegroundToken token) {
5816        synchronized (ActivityManagerService.this) {
5817            synchronized (mPidsSelfLocked) {
5818                ForegroundToken cur
5819                    = mForegroundProcesses.get(token.pid);
5820                if (cur != token) {
5821                    return;
5822                }
5823                mForegroundProcesses.remove(token.pid);
5824                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5825                if (pr == null) {
5826                    return;
5827                }
5828                pr.forcingToForeground = null;
5829                updateProcessForegroundLocked(pr, false, false);
5830            }
5831            updateOomAdjLocked();
5832        }
5833    }
5834
5835    @Override
5836    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5837        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5838                "setProcessForeground()");
5839        synchronized(this) {
5840            boolean changed = false;
5841
5842            synchronized (mPidsSelfLocked) {
5843                ProcessRecord pr = mPidsSelfLocked.get(pid);
5844                if (pr == null && isForeground) {
5845                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5846                    return;
5847                }
5848                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5849                if (oldToken != null) {
5850                    oldToken.token.unlinkToDeath(oldToken, 0);
5851                    mForegroundProcesses.remove(pid);
5852                    if (pr != null) {
5853                        pr.forcingToForeground = null;
5854                    }
5855                    changed = true;
5856                }
5857                if (isForeground && token != null) {
5858                    ForegroundToken newToken = new ForegroundToken() {
5859                        @Override
5860                        public void binderDied() {
5861                            foregroundTokenDied(this);
5862                        }
5863                    };
5864                    newToken.pid = pid;
5865                    newToken.token = token;
5866                    try {
5867                        token.linkToDeath(newToken, 0);
5868                        mForegroundProcesses.put(pid, newToken);
5869                        pr.forcingToForeground = token;
5870                        changed = true;
5871                    } catch (RemoteException e) {
5872                        // If the process died while doing this, we will later
5873                        // do the cleanup with the process death link.
5874                    }
5875                }
5876            }
5877
5878            if (changed) {
5879                updateOomAdjLocked();
5880            }
5881        }
5882    }
5883
5884    // =========================================================
5885    // PERMISSIONS
5886    // =========================================================
5887
5888    static class PermissionController extends IPermissionController.Stub {
5889        ActivityManagerService mActivityManagerService;
5890        PermissionController(ActivityManagerService activityManagerService) {
5891            mActivityManagerService = activityManagerService;
5892        }
5893
5894        @Override
5895        public boolean checkPermission(String permission, int pid, int uid) {
5896            return mActivityManagerService.checkPermission(permission, pid,
5897                    uid) == PackageManager.PERMISSION_GRANTED;
5898        }
5899    }
5900
5901    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5902        @Override
5903        public int checkComponentPermission(String permission, int pid, int uid,
5904                int owningUid, boolean exported) {
5905            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5906                    owningUid, exported);
5907        }
5908
5909        @Override
5910        public Object getAMSLock() {
5911            return ActivityManagerService.this;
5912        }
5913    }
5914
5915    /**
5916     * This can be called with or without the global lock held.
5917     */
5918    int checkComponentPermission(String permission, int pid, int uid,
5919            int owningUid, boolean exported) {
5920        // We might be performing an operation on behalf of an indirect binder
5921        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5922        // client identity accordingly before proceeding.
5923        Identity tlsIdentity = sCallerIdentity.get();
5924        if (tlsIdentity != null) {
5925            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5926                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5927            uid = tlsIdentity.uid;
5928            pid = tlsIdentity.pid;
5929        }
5930
5931        if (pid == MY_PID) {
5932            return PackageManager.PERMISSION_GRANTED;
5933        }
5934
5935        return ActivityManager.checkComponentPermission(permission, uid,
5936                owningUid, exported);
5937    }
5938
5939    /**
5940     * As the only public entry point for permissions checking, this method
5941     * can enforce the semantic that requesting a check on a null global
5942     * permission is automatically denied.  (Internally a null permission
5943     * string is used when calling {@link #checkComponentPermission} in cases
5944     * when only uid-based security is needed.)
5945     *
5946     * This can be called with or without the global lock held.
5947     */
5948    @Override
5949    public int checkPermission(String permission, int pid, int uid) {
5950        if (permission == null) {
5951            return PackageManager.PERMISSION_DENIED;
5952        }
5953        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5954    }
5955
5956    /**
5957     * Binder IPC calls go through the public entry point.
5958     * This can be called with or without the global lock held.
5959     */
5960    int checkCallingPermission(String permission) {
5961        return checkPermission(permission,
5962                Binder.getCallingPid(),
5963                UserHandle.getAppId(Binder.getCallingUid()));
5964    }
5965
5966    /**
5967     * This can be called with or without the global lock held.
5968     */
5969    void enforceCallingPermission(String permission, String func) {
5970        if (checkCallingPermission(permission)
5971                == PackageManager.PERMISSION_GRANTED) {
5972            return;
5973        }
5974
5975        String msg = "Permission Denial: " + func + " from pid="
5976                + Binder.getCallingPid()
5977                + ", uid=" + Binder.getCallingUid()
5978                + " requires " + permission;
5979        Slog.w(TAG, msg);
5980        throw new SecurityException(msg);
5981    }
5982
5983    /**
5984     * Determine if UID is holding permissions required to access {@link Uri} in
5985     * the given {@link ProviderInfo}. Final permission checking is always done
5986     * in {@link ContentProvider}.
5987     */
5988    private final boolean checkHoldingPermissionsLocked(
5989            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, final int modeFlags) {
5990        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5991                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
5992
5993        if (pi.applicationInfo.uid == uid) {
5994            return true;
5995        } else if (!pi.exported) {
5996            return false;
5997        }
5998
5999        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6000        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6001        try {
6002            // check if target holds top-level <provider> permissions
6003            if (!readMet && pi.readPermission != null
6004                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6005                readMet = true;
6006            }
6007            if (!writeMet && pi.writePermission != null
6008                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6009                writeMet = true;
6010            }
6011
6012            // track if unprotected read/write is allowed; any denied
6013            // <path-permission> below removes this ability
6014            boolean allowDefaultRead = pi.readPermission == null;
6015            boolean allowDefaultWrite = pi.writePermission == null;
6016
6017            // check if target holds any <path-permission> that match uri
6018            final PathPermission[] pps = pi.pathPermissions;
6019            if (pps != null) {
6020                final String path = uri.getPath();
6021                int i = pps.length;
6022                while (i > 0 && (!readMet || !writeMet)) {
6023                    i--;
6024                    PathPermission pp = pps[i];
6025                    if (pp.match(path)) {
6026                        if (!readMet) {
6027                            final String pprperm = pp.getReadPermission();
6028                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6029                                    + pprperm + " for " + pp.getPath()
6030                                    + ": match=" + pp.match(path)
6031                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6032                            if (pprperm != null) {
6033                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
6034                                    readMet = true;
6035                                } else {
6036                                    allowDefaultRead = false;
6037                                }
6038                            }
6039                        }
6040                        if (!writeMet) {
6041                            final String ppwperm = pp.getWritePermission();
6042                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6043                                    + ppwperm + " for " + pp.getPath()
6044                                    + ": match=" + pp.match(path)
6045                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6046                            if (ppwperm != null) {
6047                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
6048                                    writeMet = true;
6049                                } else {
6050                                    allowDefaultWrite = false;
6051                                }
6052                            }
6053                        }
6054                    }
6055                }
6056            }
6057
6058            // grant unprotected <provider> read/write, if not blocked by
6059            // <path-permission> above
6060            if (allowDefaultRead) readMet = true;
6061            if (allowDefaultWrite) writeMet = true;
6062
6063        } catch (RemoteException e) {
6064            return false;
6065        }
6066
6067        return readMet && writeMet;
6068    }
6069
6070    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6071        ProviderInfo pi = null;
6072        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6073        if (cpr != null) {
6074            pi = cpr.info;
6075        } else {
6076            try {
6077                pi = AppGlobals.getPackageManager().resolveContentProvider(
6078                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6079            } catch (RemoteException ex) {
6080            }
6081        }
6082        return pi;
6083    }
6084
6085    private UriPermission findUriPermissionLocked(int targetUid, GrantUri uri) {
6086        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6087        if (targetUris != null) {
6088            return targetUris.get(uri);
6089        }
6090        return null;
6091    }
6092
6093    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6094            String targetPkg, int targetUid, GrantUri uri) {
6095        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6096        if (targetUris == null) {
6097            targetUris = Maps.newArrayMap();
6098            mGrantedUriPermissions.put(targetUid, targetUris);
6099        }
6100
6101        UriPermission perm = targetUris.get(uri);
6102        if (perm == null) {
6103            perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri);
6104            targetUris.put(uri, perm);
6105        }
6106
6107        return perm;
6108    }
6109
6110    private final boolean checkUriPermissionLocked(Uri uri, int uid, final int modeFlags) {
6111        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6112        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6113                : UriPermission.STRENGTH_OWNED;
6114
6115        // Root gets to do everything.
6116        if (uid == 0) {
6117            return true;
6118        }
6119
6120        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6121        if (perms == null) return false;
6122
6123        // First look for exact match
6124        final UriPermission exactPerm = perms.get(new GrantUri(uri, false));
6125        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6126            return true;
6127        }
6128
6129        // No exact match, look for prefixes
6130        final int N = perms.size();
6131        for (int i = 0; i < N; i++) {
6132            final UriPermission perm = perms.valueAt(i);
6133            if (perm.uri.prefix && uri.isPathPrefixMatch(perm.uri.uri)
6134                    && perm.getStrength(modeFlags) >= minStrength) {
6135                return true;
6136            }
6137        }
6138
6139        return false;
6140    }
6141
6142    @Override
6143    public int checkUriPermission(Uri uri, int pid, int uid, final int modeFlags) {
6144        enforceNotIsolatedCaller("checkUriPermission");
6145
6146        // Another redirected-binder-call permissions check as in
6147        // {@link checkComponentPermission}.
6148        Identity tlsIdentity = sCallerIdentity.get();
6149        if (tlsIdentity != null) {
6150            uid = tlsIdentity.uid;
6151            pid = tlsIdentity.pid;
6152        }
6153
6154        // Our own process gets to do everything.
6155        if (pid == MY_PID) {
6156            return PackageManager.PERMISSION_GRANTED;
6157        }
6158        synchronized (this) {
6159            return checkUriPermissionLocked(uri, uid, modeFlags)
6160                    ? PackageManager.PERMISSION_GRANTED
6161                    : PackageManager.PERMISSION_DENIED;
6162        }
6163    }
6164
6165    /**
6166     * Check if the targetPkg can be granted permission to access uri by
6167     * the callingUid using the given modeFlags.  Throws a security exception
6168     * if callingUid is not allowed to do this.  Returns the uid of the target
6169     * if the URI permission grant should be performed; returns -1 if it is not
6170     * needed (for example targetPkg already has permission to access the URI).
6171     * If you already know the uid of the target, you can supply it in
6172     * lastTargetUid else set that to -1.
6173     */
6174    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
6175            Uri uri, final int modeFlags, int lastTargetUid) {
6176        if (!Intent.isAccessUriMode(modeFlags)) {
6177            return -1;
6178        }
6179
6180        if (targetPkg != null) {
6181            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6182                    "Checking grant " + targetPkg + " permission to " + uri);
6183        }
6184
6185        final IPackageManager pm = AppGlobals.getPackageManager();
6186
6187        // If this is not a content: uri, we can't do anything with it.
6188        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
6189            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6190                    "Can't grant URI permission for non-content URI: " + uri);
6191            return -1;
6192        }
6193
6194        final String authority = uri.getAuthority();
6195        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6196        if (pi == null) {
6197            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
6198            return -1;
6199        }
6200
6201        int targetUid = lastTargetUid;
6202        if (targetUid < 0 && targetPkg != null) {
6203            try {
6204                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6205                if (targetUid < 0) {
6206                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6207                            "Can't grant URI permission no uid for: " + targetPkg);
6208                    return -1;
6209                }
6210            } catch (RemoteException ex) {
6211                return -1;
6212            }
6213        }
6214
6215        if (targetUid >= 0) {
6216            // First...  does the target actually need this permission?
6217            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
6218                // No need to grant the target this permission.
6219                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6220                        "Target " + targetPkg + " already has full permission to " + uri);
6221                return -1;
6222            }
6223        } else {
6224            // First...  there is no target package, so can anyone access it?
6225            boolean allowed = pi.exported;
6226            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6227                if (pi.readPermission != null) {
6228                    allowed = false;
6229                }
6230            }
6231            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6232                if (pi.writePermission != null) {
6233                    allowed = false;
6234                }
6235            }
6236            if (allowed) {
6237                return -1;
6238            }
6239        }
6240
6241        // Second...  is the provider allowing granting of URI permissions?
6242        if (!pi.grantUriPermissions) {
6243            throw new SecurityException("Provider " + pi.packageName
6244                    + "/" + pi.name
6245                    + " does not allow granting of Uri permissions (uri "
6246                    + uri + ")");
6247        }
6248        if (pi.uriPermissionPatterns != null) {
6249            final int N = pi.uriPermissionPatterns.length;
6250            boolean allowed = false;
6251            for (int i=0; i<N; i++) {
6252                if (pi.uriPermissionPatterns[i] != null
6253                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
6254                    allowed = true;
6255                    break;
6256                }
6257            }
6258            if (!allowed) {
6259                throw new SecurityException("Provider " + pi.packageName
6260                        + "/" + pi.name
6261                        + " does not allow granting of permission to path of Uri "
6262                        + uri);
6263            }
6264        }
6265
6266        // Third...  does the caller itself have permission to access
6267        // this uri?
6268        if (callingUid != Process.myUid()) {
6269            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6270                // Require they hold a strong enough Uri permission
6271                if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6272                    throw new SecurityException("Uid " + callingUid
6273                            + " does not have permission to uri " + uri);
6274                }
6275            }
6276        }
6277
6278        return targetUid;
6279    }
6280
6281    @Override
6282    public int checkGrantUriPermission(int callingUid, String targetPkg,
6283            Uri uri, final int modeFlags) {
6284        enforceNotIsolatedCaller("checkGrantUriPermission");
6285        synchronized(this) {
6286            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6287        }
6288    }
6289
6290    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, Uri uri,
6291            final int modeFlags, UriPermissionOwner owner) {
6292        if (!Intent.isAccessUriMode(modeFlags)) {
6293            return;
6294        }
6295
6296        // So here we are: the caller has the assumed permission
6297        // to the uri, and the target doesn't.  Let's now give this to
6298        // the target.
6299
6300        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6301                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
6302
6303        final String authority = uri.getAuthority();
6304        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid));
6305        if (pi == null) {
6306            Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString());
6307            return;
6308        }
6309
6310        final boolean prefix = (modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
6311        final UriPermission perm = findOrCreateUriPermissionLocked(
6312                pi.packageName, targetPkg, targetUid, new GrantUri(uri, prefix));
6313        perm.grantModes(modeFlags, owner);
6314    }
6315
6316    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
6317            final int modeFlags, UriPermissionOwner owner) {
6318        if (targetPkg == null) {
6319            throw new NullPointerException("targetPkg");
6320        }
6321
6322        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6323        if (targetUid < 0) {
6324            return;
6325        }
6326
6327        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
6328    }
6329
6330    static class NeededUriGrants extends ArrayList<Uri> {
6331        final String targetPkg;
6332        final int targetUid;
6333        final int flags;
6334
6335        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6336            this.targetPkg = targetPkg;
6337            this.targetUid = targetUid;
6338            this.flags = flags;
6339        }
6340    }
6341
6342    /**
6343     * Like checkGrantUriPermissionLocked, but takes an Intent.
6344     */
6345    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6346            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6347        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6348                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6349                + " clip=" + (intent != null ? intent.getClipData() : null)
6350                + " from " + intent + "; flags=0x"
6351                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6352
6353        if (targetPkg == null) {
6354            throw new NullPointerException("targetPkg");
6355        }
6356
6357        if (intent == null) {
6358            return null;
6359        }
6360        Uri data = intent.getData();
6361        ClipData clip = intent.getClipData();
6362        if (data == null && clip == null) {
6363            return null;
6364        }
6365
6366        if (data != null) {
6367            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
6368                mode, needed != null ? needed.targetUid : -1);
6369            if (targetUid > 0) {
6370                if (needed == null) {
6371                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6372                }
6373                needed.add(data);
6374            }
6375        }
6376        if (clip != null) {
6377            for (int i=0; i<clip.getItemCount(); i++) {
6378                Uri uri = clip.getItemAt(i).getUri();
6379                if (uri != null) {
6380                    int targetUid = -1;
6381                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
6382                            mode, needed != null ? needed.targetUid : -1);
6383                    if (targetUid > 0) {
6384                        if (needed == null) {
6385                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6386                        }
6387                        needed.add(uri);
6388                    }
6389                } else {
6390                    Intent clipIntent = clip.getItemAt(i).getIntent();
6391                    if (clipIntent != null) {
6392                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6393                                callingUid, targetPkg, clipIntent, mode, needed);
6394                        if (newNeeded != null) {
6395                            needed = newNeeded;
6396                        }
6397                    }
6398                }
6399            }
6400        }
6401
6402        return needed;
6403    }
6404
6405    /**
6406     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6407     */
6408    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6409            UriPermissionOwner owner) {
6410        if (needed != null) {
6411            for (int i=0; i<needed.size(); i++) {
6412                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6413                        needed.get(i), needed.flags, owner);
6414            }
6415        }
6416    }
6417
6418    void grantUriPermissionFromIntentLocked(int callingUid,
6419            String targetPkg, Intent intent, UriPermissionOwner owner) {
6420        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6421                intent, intent != null ? intent.getFlags() : 0, null);
6422        if (needed == null) {
6423            return;
6424        }
6425
6426        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6427    }
6428
6429    @Override
6430    public void grantUriPermission(IApplicationThread caller, String targetPkg,
6431            Uri uri, final int modeFlags) {
6432        enforceNotIsolatedCaller("grantUriPermission");
6433        synchronized(this) {
6434            final ProcessRecord r = getRecordForAppLocked(caller);
6435            if (r == null) {
6436                throw new SecurityException("Unable to find app for caller "
6437                        + caller
6438                        + " when granting permission to uri " + uri);
6439            }
6440            if (targetPkg == null) {
6441                throw new IllegalArgumentException("null target");
6442            }
6443            if (uri == null) {
6444                throw new IllegalArgumentException("null uri");
6445            }
6446
6447            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6448                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6449                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6450                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6451
6452            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, null);
6453        }
6454    }
6455
6456    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6457        if (perm.modeFlags == 0) {
6458            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6459                    perm.targetUid);
6460            if (perms != null) {
6461                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6462                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6463
6464                perms.remove(perm.uri);
6465                if (perms.isEmpty()) {
6466                    mGrantedUriPermissions.remove(perm.targetUid);
6467                }
6468            }
6469        }
6470    }
6471
6472    private void revokeUriPermissionLocked(int callingUid, Uri uri, final int modeFlags) {
6473        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri);
6474
6475        final IPackageManager pm = AppGlobals.getPackageManager();
6476        final String authority = uri.getAuthority();
6477        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6478        if (pi == null) {
6479            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
6480            return;
6481        }
6482
6483        // Does the caller have this permission on the URI?
6484        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6485            // Right now, if you are not the original owner of the permission,
6486            // you are not allowed to revoke it.
6487            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6488                throw new SecurityException("Uid " + callingUid
6489                        + " does not have permission to uri " + uri);
6490            //}
6491        }
6492
6493        boolean persistChanged = false;
6494
6495        // Go through all of the permissions and remove any that match.
6496        int N = mGrantedUriPermissions.size();
6497        for (int i = 0; i < N; i++) {
6498            final int targetUid = mGrantedUriPermissions.keyAt(i);
6499            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6500
6501            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6502                final UriPermission perm = it.next();
6503                if (perm.uri.uri.isPathPrefixMatch(uri)) {
6504                    if (DEBUG_URI_PERMISSION)
6505                        Slog.v(TAG,
6506                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6507                    persistChanged |= perm.revokeModes(
6508                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6509                    if (perm.modeFlags == 0) {
6510                        it.remove();
6511                    }
6512                }
6513            }
6514
6515            if (perms.isEmpty()) {
6516                mGrantedUriPermissions.remove(targetUid);
6517                N--;
6518                i--;
6519            }
6520        }
6521
6522        if (persistChanged) {
6523            schedulePersistUriGrants();
6524        }
6525    }
6526
6527    @Override
6528    public void revokeUriPermission(IApplicationThread caller, Uri uri,
6529            final int modeFlags) {
6530        enforceNotIsolatedCaller("revokeUriPermission");
6531        synchronized(this) {
6532            final ProcessRecord r = getRecordForAppLocked(caller);
6533            if (r == null) {
6534                throw new SecurityException("Unable to find app for caller "
6535                        + caller
6536                        + " when revoking permission to uri " + uri);
6537            }
6538            if (uri == null) {
6539                Slog.w(TAG, "revokeUriPermission: null uri");
6540                return;
6541            }
6542
6543            if (!Intent.isAccessUriMode(modeFlags)) {
6544                return;
6545            }
6546
6547            final IPackageManager pm = AppGlobals.getPackageManager();
6548            final String authority = uri.getAuthority();
6549            final ProviderInfo pi = getProviderInfoLocked(authority, r.userId);
6550            if (pi == null) {
6551                Slog.w(TAG, "No content provider found for permission revoke: "
6552                        + uri.toSafeString());
6553                return;
6554            }
6555
6556            revokeUriPermissionLocked(r.uid, uri, modeFlags);
6557        }
6558    }
6559
6560    /**
6561     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6562     * given package.
6563     *
6564     * @param packageName Package name to match, or {@code null} to apply to all
6565     *            packages.
6566     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6567     *            to all users.
6568     * @param persistable If persistable grants should be removed.
6569     */
6570    private void removeUriPermissionsForPackageLocked(
6571            String packageName, int userHandle, boolean persistable) {
6572        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6573            throw new IllegalArgumentException("Must narrow by either package or user");
6574        }
6575
6576        boolean persistChanged = false;
6577
6578        int N = mGrantedUriPermissions.size();
6579        for (int i = 0; i < N; i++) {
6580            final int targetUid = mGrantedUriPermissions.keyAt(i);
6581            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6582
6583            // Only inspect grants matching user
6584            if (userHandle == UserHandle.USER_ALL
6585                    || userHandle == UserHandle.getUserId(targetUid)) {
6586                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6587                    final UriPermission perm = it.next();
6588
6589                    // Only inspect grants matching package
6590                    if (packageName == null || perm.sourcePkg.equals(packageName)
6591                            || perm.targetPkg.equals(packageName)) {
6592                        persistChanged |= perm.revokeModes(
6593                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6594
6595                        // Only remove when no modes remain; any persisted grants
6596                        // will keep this alive.
6597                        if (perm.modeFlags == 0) {
6598                            it.remove();
6599                        }
6600                    }
6601                }
6602
6603                if (perms.isEmpty()) {
6604                    mGrantedUriPermissions.remove(targetUid);
6605                    N--;
6606                    i--;
6607                }
6608            }
6609        }
6610
6611        if (persistChanged) {
6612            schedulePersistUriGrants();
6613        }
6614    }
6615
6616    @Override
6617    public IBinder newUriPermissionOwner(String name) {
6618        enforceNotIsolatedCaller("newUriPermissionOwner");
6619        synchronized(this) {
6620            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6621            return owner.getExternalTokenLocked();
6622        }
6623    }
6624
6625    @Override
6626    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
6627            Uri uri, final int modeFlags) {
6628        synchronized(this) {
6629            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6630            if (owner == null) {
6631                throw new IllegalArgumentException("Unknown owner: " + token);
6632            }
6633            if (fromUid != Binder.getCallingUid()) {
6634                if (Binder.getCallingUid() != Process.myUid()) {
6635                    // Only system code can grant URI permissions on behalf
6636                    // of other users.
6637                    throw new SecurityException("nice try");
6638                }
6639            }
6640            if (targetPkg == null) {
6641                throw new IllegalArgumentException("null target");
6642            }
6643            if (uri == null) {
6644                throw new IllegalArgumentException("null uri");
6645            }
6646
6647            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
6648        }
6649    }
6650
6651    @Override
6652    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
6653        synchronized(this) {
6654            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6655            if (owner == null) {
6656                throw new IllegalArgumentException("Unknown owner: " + token);
6657            }
6658
6659            if (uri == null) {
6660                owner.removeUriPermissionsLocked(mode);
6661            } else {
6662                owner.removeUriPermissionLocked(uri, mode);
6663            }
6664        }
6665    }
6666
6667    private void schedulePersistUriGrants() {
6668        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6669            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6670                    10 * DateUtils.SECOND_IN_MILLIS);
6671        }
6672    }
6673
6674    private void writeGrantedUriPermissions() {
6675        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6676
6677        // Snapshot permissions so we can persist without lock
6678        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6679        synchronized (this) {
6680            final int size = mGrantedUriPermissions.size();
6681            for (int i = 0; i < size; i++) {
6682                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6683                for (UriPermission perm : perms.values()) {
6684                    if (perm.persistedModeFlags != 0) {
6685                        persist.add(perm.snapshot());
6686                    }
6687                }
6688            }
6689        }
6690
6691        FileOutputStream fos = null;
6692        try {
6693            fos = mGrantFile.startWrite();
6694
6695            XmlSerializer out = new FastXmlSerializer();
6696            out.setOutput(fos, "utf-8");
6697            out.startDocument(null, true);
6698            out.startTag(null, TAG_URI_GRANTS);
6699            for (UriPermission.Snapshot perm : persist) {
6700                out.startTag(null, TAG_URI_GRANT);
6701                writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle);
6702                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6703                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6704                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6705                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6706                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6707                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6708                out.endTag(null, TAG_URI_GRANT);
6709            }
6710            out.endTag(null, TAG_URI_GRANTS);
6711            out.endDocument();
6712
6713            mGrantFile.finishWrite(fos);
6714        } catch (IOException e) {
6715            if (fos != null) {
6716                mGrantFile.failWrite(fos);
6717            }
6718        }
6719    }
6720
6721    private void readGrantedUriPermissionsLocked() {
6722        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6723
6724        final long now = System.currentTimeMillis();
6725
6726        FileInputStream fis = null;
6727        try {
6728            fis = mGrantFile.openRead();
6729            final XmlPullParser in = Xml.newPullParser();
6730            in.setInput(fis, null);
6731
6732            int type;
6733            while ((type = in.next()) != END_DOCUMENT) {
6734                final String tag = in.getName();
6735                if (type == START_TAG) {
6736                    if (TAG_URI_GRANT.equals(tag)) {
6737                        final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE);
6738                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6739                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6740                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6741                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
6742                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6743                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6744
6745                        // Sanity check that provider still belongs to source package
6746                        final ProviderInfo pi = getProviderInfoLocked(
6747                                uri.getAuthority(), userHandle);
6748                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6749                            int targetUid = -1;
6750                            try {
6751                                targetUid = AppGlobals.getPackageManager()
6752                                        .getPackageUid(targetPkg, userHandle);
6753                            } catch (RemoteException e) {
6754                            }
6755                            if (targetUid != -1) {
6756                                final UriPermission perm = findOrCreateUriPermissionLocked(
6757                                        sourcePkg, targetPkg, targetUid, new GrantUri(uri, prefix));
6758                                perm.initPersistedModes(modeFlags, createdTime);
6759                            }
6760                        } else {
6761                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6762                                    + " but instead found " + pi);
6763                        }
6764                    }
6765                }
6766            }
6767        } catch (FileNotFoundException e) {
6768            // Missing grants is okay
6769        } catch (IOException e) {
6770            Log.wtf(TAG, "Failed reading Uri grants", e);
6771        } catch (XmlPullParserException e) {
6772            Log.wtf(TAG, "Failed reading Uri grants", e);
6773        } finally {
6774            IoUtils.closeQuietly(fis);
6775        }
6776    }
6777
6778    @Override
6779    public void takePersistableUriPermission(Uri uri, final int modeFlags) {
6780        enforceNotIsolatedCaller("takePersistableUriPermission");
6781
6782        Preconditions.checkFlagsArgument(modeFlags,
6783                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6784
6785        synchronized (this) {
6786            final int callingUid = Binder.getCallingUid();
6787            boolean persistChanged = false;
6788
6789            UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false));
6790            UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true));
6791
6792            final boolean exactValid = (exactPerm != null)
6793                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
6794            final boolean prefixValid = (prefixPerm != null)
6795                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
6796
6797            if (!(exactValid || prefixValid)) {
6798                throw new SecurityException("No persistable permission grants found for UID "
6799                        + callingUid + " and Uri " + uri.toSafeString());
6800            }
6801
6802            if (exactValid) {
6803                persistChanged |= exactPerm.takePersistableModes(modeFlags);
6804            }
6805            if (prefixValid) {
6806                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
6807            }
6808
6809            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6810
6811            if (persistChanged) {
6812                schedulePersistUriGrants();
6813            }
6814        }
6815    }
6816
6817    @Override
6818    public void releasePersistableUriPermission(Uri uri, final int modeFlags) {
6819        enforceNotIsolatedCaller("releasePersistableUriPermission");
6820
6821        Preconditions.checkFlagsArgument(modeFlags,
6822                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6823
6824        synchronized (this) {
6825            final int callingUid = Binder.getCallingUid();
6826            boolean persistChanged = false;
6827
6828            UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false));
6829            UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true));
6830            if (exactPerm == null && prefixPerm == null) {
6831                throw new SecurityException("No permission grants found for UID " + callingUid
6832                        + " and Uri " + uri.toSafeString());
6833            }
6834
6835            if (exactPerm != null) {
6836                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
6837                removeUriPermissionIfNeededLocked(exactPerm);
6838            }
6839            if (prefixPerm != null) {
6840                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
6841                removeUriPermissionIfNeededLocked(prefixPerm);
6842            }
6843
6844            if (persistChanged) {
6845                schedulePersistUriGrants();
6846            }
6847        }
6848    }
6849
6850    /**
6851     * Prune any older {@link UriPermission} for the given UID until outstanding
6852     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6853     *
6854     * @return if any mutations occured that require persisting.
6855     */
6856    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6857        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6858        if (perms == null) return false;
6859        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6860
6861        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6862        for (UriPermission perm : perms.values()) {
6863            if (perm.persistedModeFlags != 0) {
6864                persisted.add(perm);
6865            }
6866        }
6867
6868        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6869        if (trimCount <= 0) return false;
6870
6871        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6872        for (int i = 0; i < trimCount; i++) {
6873            final UriPermission perm = persisted.get(i);
6874
6875            if (DEBUG_URI_PERMISSION) {
6876                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6877            }
6878
6879            perm.releasePersistableModes(~0);
6880            removeUriPermissionIfNeededLocked(perm);
6881        }
6882
6883        return true;
6884    }
6885
6886    @Override
6887    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6888            String packageName, boolean incoming) {
6889        enforceNotIsolatedCaller("getPersistedUriPermissions");
6890        Preconditions.checkNotNull(packageName, "packageName");
6891
6892        final int callingUid = Binder.getCallingUid();
6893        final IPackageManager pm = AppGlobals.getPackageManager();
6894        try {
6895            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6896            if (packageUid != callingUid) {
6897                throw new SecurityException(
6898                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6899            }
6900        } catch (RemoteException e) {
6901            throw new SecurityException("Failed to verify package name ownership");
6902        }
6903
6904        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6905        synchronized (this) {
6906            if (incoming) {
6907                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6908                        callingUid);
6909                if (perms == null) {
6910                    Slog.w(TAG, "No permission grants found for " + packageName);
6911                } else {
6912                    for (UriPermission perm : perms.values()) {
6913                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6914                            result.add(perm.buildPersistedPublicApiObject());
6915                        }
6916                    }
6917                }
6918            } else {
6919                final int size = mGrantedUriPermissions.size();
6920                for (int i = 0; i < size; i++) {
6921                    final ArrayMap<GrantUri, UriPermission> perms =
6922                            mGrantedUriPermissions.valueAt(i);
6923                    for (UriPermission perm : perms.values()) {
6924                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6925                            result.add(perm.buildPersistedPublicApiObject());
6926                        }
6927                    }
6928                }
6929            }
6930        }
6931        return new ParceledListSlice<android.content.UriPermission>(result);
6932    }
6933
6934    @Override
6935    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6936        synchronized (this) {
6937            ProcessRecord app =
6938                who != null ? getRecordForAppLocked(who) : null;
6939            if (app == null) return;
6940
6941            Message msg = Message.obtain();
6942            msg.what = WAIT_FOR_DEBUGGER_MSG;
6943            msg.obj = app;
6944            msg.arg1 = waiting ? 1 : 0;
6945            mHandler.sendMessage(msg);
6946        }
6947    }
6948
6949    @Override
6950    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
6951        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
6952        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
6953        outInfo.availMem = Process.getFreeMemory();
6954        outInfo.totalMem = Process.getTotalMemory();
6955        outInfo.threshold = homeAppMem;
6956        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
6957        outInfo.hiddenAppThreshold = cachedAppMem;
6958        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
6959                ProcessList.SERVICE_ADJ);
6960        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
6961                ProcessList.VISIBLE_APP_ADJ);
6962        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
6963                ProcessList.FOREGROUND_APP_ADJ);
6964    }
6965
6966    // =========================================================
6967    // TASK MANAGEMENT
6968    // =========================================================
6969
6970    @Override
6971    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
6972        final int callingUid = Binder.getCallingUid();
6973        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
6974
6975        synchronized(this) {
6976            if (localLOGV) Slog.v(
6977                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
6978
6979            final boolean allowed = checkCallingPermission(
6980                    android.Manifest.permission.GET_TASKS)
6981                    == PackageManager.PERMISSION_GRANTED;
6982            if (!allowed) {
6983                Slog.w(TAG, "getTasks: caller " + callingUid
6984                        + " does not hold GET_TASKS; limiting output");
6985            }
6986
6987            // TODO: Improve with MRU list from all ActivityStacks.
6988            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
6989        }
6990
6991        return list;
6992    }
6993
6994    TaskRecord getMostRecentTask() {
6995        return mRecentTasks.get(0);
6996    }
6997
6998    @Override
6999    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
7000            int flags, int userId) {
7001        final int callingUid = Binder.getCallingUid();
7002        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7003                false, true, "getRecentTasks", null);
7004
7005        synchronized (this) {
7006            final boolean allowed = checkCallingPermission(
7007                    android.Manifest.permission.GET_TASKS)
7008                    == PackageManager.PERMISSION_GRANTED;
7009            if (!allowed) {
7010                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7011                        + " does not hold GET_TASKS; limiting output");
7012            }
7013            final boolean detailed = checkCallingPermission(
7014                    android.Manifest.permission.GET_DETAILED_TASKS)
7015                    == PackageManager.PERMISSION_GRANTED;
7016
7017            IPackageManager pm = AppGlobals.getPackageManager();
7018
7019            final int N = mRecentTasks.size();
7020            ArrayList<ActivityManager.RecentTaskInfo> res
7021                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7022                            maxNum < N ? maxNum : N);
7023
7024            final Set<Integer> includedUsers;
7025            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
7026                includedUsers = getProfileIdsLocked(userId);
7027            } else {
7028                includedUsers = new HashSet<Integer>();
7029            }
7030            includedUsers.add(Integer.valueOf(userId));
7031            for (int i=0; i<N && maxNum > 0; i++) {
7032                TaskRecord tr = mRecentTasks.get(i);
7033                // Only add calling user or related users recent tasks
7034                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7035
7036                // Return the entry if desired by the caller.  We always return
7037                // the first entry, because callers always expect this to be the
7038                // foreground app.  We may filter others if the caller has
7039                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7040                // we should exclude the entry.
7041
7042                if (i == 0
7043                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
7044                        || (tr.intent == null)
7045                        || ((tr.intent.getFlags()
7046                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
7047                    if (!allowed) {
7048                        // If the caller doesn't have the GET_TASKS permission, then only
7049                        // allow them to see a small subset of tasks -- their own and home.
7050                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7051                            continue;
7052                        }
7053                    }
7054                    ActivityManager.RecentTaskInfo rti
7055                            = new ActivityManager.RecentTaskInfo();
7056                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
7057                    rti.persistentId = tr.taskId;
7058                    rti.baseIntent = new Intent(
7059                            tr.intent != null ? tr.intent : tr.affinityIntent);
7060                    if (!detailed) {
7061                        rti.baseIntent.replaceExtras((Bundle)null);
7062                    }
7063                    rti.origActivity = tr.origActivity;
7064                    rti.description = tr.lastDescription;
7065                    rti.stackId = tr.stack.mStackId;
7066                    rti.userId = tr.userId;
7067
7068                    // Traverse upwards looking for any break between main task activities and
7069                    // utility activities.
7070                    final ArrayList<ActivityRecord> activities = tr.mActivities;
7071                    int activityNdx;
7072                    final int numActivities = activities.size();
7073                    for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities;
7074                            ++activityNdx) {
7075                        final ActivityRecord r = activities.get(activityNdx);
7076                        if (r.intent != null &&
7077                                (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET)
7078                                        != 0) {
7079                            break;
7080                        }
7081                    }
7082                    if (activityNdx > 0) {
7083                        // Traverse downwards starting below break looking for set label, icon.
7084                        // Note that if there are activities in the task but none of them set the
7085                        // recent activity values, then we do not fall back to the last set
7086                        // values in the TaskRecord.
7087                        rti.activityValues = new ActivityManager.RecentsActivityValues();
7088                        for (--activityNdx; activityNdx >= 0; --activityNdx) {
7089                            final ActivityRecord r = activities.get(activityNdx);
7090                            if (r.activityValues != null) {
7091                                if (rti.activityValues.label == null) {
7092                                    rti.activityValues.label = r.activityValues.label;
7093                                    tr.lastActivityValues.label = r.activityValues.label;
7094                                }
7095                                if (rti.activityValues.icon == null) {
7096                                    rti.activityValues.icon = r.activityValues.icon;
7097                                    tr.lastActivityValues.icon = r.activityValues.icon;
7098                                }
7099                                if (rti.activityValues.colorPrimary == 0) {
7100                                    rti.activityValues.colorPrimary = r.activityValues.colorPrimary;
7101                                    tr.lastActivityValues.colorPrimary = r.activityValues.colorPrimary;
7102                                }
7103                            }
7104                        }
7105                    } else {
7106                        // If there are no activity records in this task, then we use the last
7107                        // resolved values
7108                        rti.activityValues =
7109                                new ActivityManager.RecentsActivityValues(tr.lastActivityValues);
7110                    }
7111
7112                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7113                        // Check whether this activity is currently available.
7114                        try {
7115                            if (rti.origActivity != null) {
7116                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7117                                        == null) {
7118                                    continue;
7119                                }
7120                            } else if (rti.baseIntent != null) {
7121                                if (pm.queryIntentActivities(rti.baseIntent,
7122                                        null, 0, userId) == null) {
7123                                    continue;
7124                                }
7125                            }
7126                        } catch (RemoteException e) {
7127                            // Will never happen.
7128                        }
7129                    }
7130
7131                    res.add(rti);
7132                    maxNum--;
7133                }
7134            }
7135            return res;
7136        }
7137    }
7138
7139    private TaskRecord recentTaskForIdLocked(int id) {
7140        final int N = mRecentTasks.size();
7141            for (int i=0; i<N; i++) {
7142                TaskRecord tr = mRecentTasks.get(i);
7143                if (tr.taskId == id) {
7144                    return tr;
7145                }
7146            }
7147            return null;
7148    }
7149
7150    @Override
7151    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
7152        synchronized (this) {
7153            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7154                    "getTaskThumbnails()");
7155            TaskRecord tr = recentTaskForIdLocked(id);
7156            if (tr != null) {
7157                return tr.getTaskThumbnailsLocked();
7158            }
7159        }
7160        return null;
7161    }
7162
7163    @Override
7164    public Bitmap getTaskTopThumbnail(int id) {
7165        synchronized (this) {
7166            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7167                    "getTaskTopThumbnail()");
7168            TaskRecord tr = recentTaskForIdLocked(id);
7169            if (tr != null) {
7170                return tr.getTaskTopThumbnailLocked();
7171            }
7172        }
7173        return null;
7174    }
7175
7176    @Override
7177    public void setRecentsActivityValues(IBinder token, ActivityManager.RecentsActivityValues rav) {
7178        synchronized (this) {
7179            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7180            if (r != null) {
7181                r.activityValues = rav;
7182            }
7183        }
7184    }
7185
7186    @Override
7187    public boolean removeSubTask(int taskId, int subTaskIndex) {
7188        synchronized (this) {
7189            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7190                    "removeSubTask()");
7191            long ident = Binder.clearCallingIdentity();
7192            try {
7193                TaskRecord tr = recentTaskForIdLocked(taskId);
7194                if (tr != null) {
7195                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
7196                }
7197                return false;
7198            } finally {
7199                Binder.restoreCallingIdentity(ident);
7200            }
7201        }
7202    }
7203
7204    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7205        if (!pr.killedByAm) {
7206            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7207            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7208                    pr.processName, pr.setAdj, reason);
7209            pr.killedByAm = true;
7210            Process.killProcessQuiet(pr.pid);
7211        }
7212    }
7213
7214    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7215        tr.disposeThumbnail();
7216        mRecentTasks.remove(tr);
7217        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7218        Intent baseIntent = new Intent(
7219                tr.intent != null ? tr.intent : tr.affinityIntent);
7220        ComponentName component = baseIntent.getComponent();
7221        if (component == null) {
7222            Slog.w(TAG, "Now component for base intent of task: " + tr);
7223            return;
7224        }
7225
7226        // Find any running services associated with this app.
7227        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7228
7229        if (killProcesses) {
7230            // Find any running processes associated with this app.
7231            final String pkg = component.getPackageName();
7232            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7233            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7234            for (int i=0; i<pmap.size(); i++) {
7235                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7236                for (int j=0; j<uids.size(); j++) {
7237                    ProcessRecord proc = uids.valueAt(j);
7238                    if (proc.userId != tr.userId) {
7239                        continue;
7240                    }
7241                    if (!proc.pkgList.containsKey(pkg)) {
7242                        continue;
7243                    }
7244                    procs.add(proc);
7245                }
7246            }
7247
7248            // Kill the running processes.
7249            for (int i=0; i<procs.size(); i++) {
7250                ProcessRecord pr = procs.get(i);
7251                if (pr == mHomeProcess) {
7252                    // Don't kill the home process along with tasks from the same package.
7253                    continue;
7254                }
7255                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7256                    killUnneededProcessLocked(pr, "remove task");
7257                } else {
7258                    pr.waitingToKill = "remove task";
7259                }
7260            }
7261        }
7262    }
7263
7264    /**
7265     * Removes the task with the specified task id.
7266     *
7267     * @param taskId Identifier of the task to be removed.
7268     * @param flags Additional operational flags.  May be 0 or
7269     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7270     * @return Returns true if the given task was found and removed.
7271     */
7272    private boolean removeTaskByIdLocked(int taskId, int flags) {
7273        TaskRecord tr = recentTaskForIdLocked(taskId);
7274        if (tr != null) {
7275            tr.removeTaskActivitiesLocked(-1, false);
7276            cleanUpRemovedTaskLocked(tr, flags);
7277            return true;
7278        }
7279        return false;
7280    }
7281
7282    @Override
7283    public boolean removeTask(int taskId, int flags) {
7284        synchronized (this) {
7285            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7286                    "removeTask()");
7287            long ident = Binder.clearCallingIdentity();
7288            try {
7289                return removeTaskByIdLocked(taskId, flags);
7290            } finally {
7291                Binder.restoreCallingIdentity(ident);
7292            }
7293        }
7294    }
7295
7296    /**
7297     * TODO: Add mController hook
7298     */
7299    @Override
7300    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7301        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7302                "moveTaskToFront()");
7303
7304        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7305        synchronized(this) {
7306            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7307                    Binder.getCallingUid(), "Task to front")) {
7308                ActivityOptions.abort(options);
7309                return;
7310            }
7311            final long origId = Binder.clearCallingIdentity();
7312            try {
7313                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7314                if (task == null) {
7315                    return;
7316                }
7317                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7318                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7319                    return;
7320                }
7321                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7322            } finally {
7323                Binder.restoreCallingIdentity(origId);
7324            }
7325            ActivityOptions.abort(options);
7326        }
7327    }
7328
7329    @Override
7330    public void moveTaskToBack(int taskId) {
7331        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7332                "moveTaskToBack()");
7333
7334        synchronized(this) {
7335            TaskRecord tr = recentTaskForIdLocked(taskId);
7336            if (tr != null) {
7337                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7338                ActivityStack stack = tr.stack;
7339                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7340                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7341                            Binder.getCallingUid(), "Task to back")) {
7342                        return;
7343                    }
7344                }
7345                final long origId = Binder.clearCallingIdentity();
7346                try {
7347                    stack.moveTaskToBackLocked(taskId, null);
7348                } finally {
7349                    Binder.restoreCallingIdentity(origId);
7350                }
7351            }
7352        }
7353    }
7354
7355    /**
7356     * Moves an activity, and all of the other activities within the same task, to the bottom
7357     * of the history stack.  The activity's order within the task is unchanged.
7358     *
7359     * @param token A reference to the activity we wish to move
7360     * @param nonRoot If false then this only works if the activity is the root
7361     *                of a task; if true it will work for any activity in a task.
7362     * @return Returns true if the move completed, false if not.
7363     */
7364    @Override
7365    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7366        enforceNotIsolatedCaller("moveActivityTaskToBack");
7367        synchronized(this) {
7368            final long origId = Binder.clearCallingIdentity();
7369            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7370            if (taskId >= 0) {
7371                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7372            }
7373            Binder.restoreCallingIdentity(origId);
7374        }
7375        return false;
7376    }
7377
7378    @Override
7379    public void moveTaskBackwards(int task) {
7380        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7381                "moveTaskBackwards()");
7382
7383        synchronized(this) {
7384            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7385                    Binder.getCallingUid(), "Task backwards")) {
7386                return;
7387            }
7388            final long origId = Binder.clearCallingIdentity();
7389            moveTaskBackwardsLocked(task);
7390            Binder.restoreCallingIdentity(origId);
7391        }
7392    }
7393
7394    private final void moveTaskBackwardsLocked(int task) {
7395        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7396    }
7397
7398    @Override
7399    public IBinder getHomeActivityToken() throws RemoteException {
7400        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7401                "getHomeActivityToken()");
7402        synchronized (this) {
7403            return mStackSupervisor.getHomeActivityToken();
7404        }
7405    }
7406
7407    @Override
7408    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7409            IActivityContainerCallback callback) throws RemoteException {
7410        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7411                "createActivityContainer()");
7412        synchronized (this) {
7413            if (parentActivityToken == null) {
7414                throw new IllegalArgumentException("parent token must not be null");
7415            }
7416            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7417            if (r == null) {
7418                return null;
7419            }
7420            if (callback == null) {
7421                throw new IllegalArgumentException("callback must not be null");
7422            }
7423            return mStackSupervisor.createActivityContainer(r, callback);
7424        }
7425    }
7426
7427    @Override
7428    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7429        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7430                "deleteActivityContainer()");
7431        synchronized (this) {
7432            mStackSupervisor.deleteActivityContainer(container);
7433        }
7434    }
7435
7436    @Override
7437    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7438            throws RemoteException {
7439        synchronized (this) {
7440            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7441            if (stack != null) {
7442                return stack.mActivityContainer;
7443            }
7444            return null;
7445        }
7446    }
7447
7448    @Override
7449    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7450        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7451                "moveTaskToStack()");
7452        if (stackId == HOME_STACK_ID) {
7453            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7454                    new RuntimeException("here").fillInStackTrace());
7455        }
7456        synchronized (this) {
7457            long ident = Binder.clearCallingIdentity();
7458            try {
7459                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7460                        + stackId + " toTop=" + toTop);
7461                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7462            } finally {
7463                Binder.restoreCallingIdentity(ident);
7464            }
7465        }
7466    }
7467
7468    @Override
7469    public void resizeStack(int stackBoxId, Rect bounds) {
7470        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7471                "resizeStackBox()");
7472        long ident = Binder.clearCallingIdentity();
7473        try {
7474            mWindowManager.resizeStack(stackBoxId, bounds);
7475        } finally {
7476            Binder.restoreCallingIdentity(ident);
7477        }
7478    }
7479
7480    @Override
7481    public List<StackInfo> getAllStackInfos() {
7482        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7483                "getAllStackInfos()");
7484        long ident = Binder.clearCallingIdentity();
7485        try {
7486            synchronized (this) {
7487                return mStackSupervisor.getAllStackInfosLocked();
7488            }
7489        } finally {
7490            Binder.restoreCallingIdentity(ident);
7491        }
7492    }
7493
7494    @Override
7495    public StackInfo getStackInfo(int stackId) {
7496        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7497                "getStackInfo()");
7498        long ident = Binder.clearCallingIdentity();
7499        try {
7500            synchronized (this) {
7501                return mStackSupervisor.getStackInfoLocked(stackId);
7502            }
7503        } finally {
7504            Binder.restoreCallingIdentity(ident);
7505        }
7506    }
7507
7508    @Override
7509    public boolean isInHomeStack(int taskId) {
7510        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7511                "getStackInfo()");
7512        long ident = Binder.clearCallingIdentity();
7513        try {
7514            synchronized (this) {
7515                TaskRecord tr = recentTaskForIdLocked(taskId);
7516                if (tr != null) {
7517                    return tr.stack.isHomeStack();
7518                }
7519            }
7520        } finally {
7521            Binder.restoreCallingIdentity(ident);
7522        }
7523        return false;
7524    }
7525
7526    @Override
7527    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7528        synchronized(this) {
7529            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7530        }
7531    }
7532
7533    private boolean isLockTaskAuthorized(ComponentName name) {
7534//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7535//                "startLockTaskMode()");
7536//        DevicePolicyManager dpm = (DevicePolicyManager)
7537//                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7538//        return dpm != null && dpm.isLockTaskPermitted(name);
7539        return true;
7540    }
7541
7542    private void startLockTaskMode(TaskRecord task) {
7543        if (!isLockTaskAuthorized(task.intent.getComponent())) {
7544            return;
7545        }
7546        long ident = Binder.clearCallingIdentity();
7547        try {
7548            synchronized (this) {
7549                // Since we lost lock on task, make sure it is still there.
7550                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7551                if (task != null) {
7552                    mStackSupervisor.setLockTaskModeLocked(task);
7553                }
7554            }
7555        } finally {
7556            Binder.restoreCallingIdentity(ident);
7557        }
7558    }
7559
7560    @Override
7561    public void startLockTaskMode(int taskId) {
7562        long ident = Binder.clearCallingIdentity();
7563        try {
7564            final TaskRecord task;
7565            synchronized (this) {
7566                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7567            }
7568            if (task != null) {
7569                startLockTaskMode(task);
7570            }
7571        } finally {
7572            Binder.restoreCallingIdentity(ident);
7573        }
7574    }
7575
7576    @Override
7577    public void startLockTaskMode(IBinder token) {
7578        long ident = Binder.clearCallingIdentity();
7579        try {
7580            final TaskRecord task;
7581            synchronized (this) {
7582                final ActivityRecord r = ActivityRecord.forToken(token);
7583                if (r == null) {
7584                    return;
7585                }
7586                task = r.task;
7587            }
7588            if (task != null) {
7589                startLockTaskMode(task);
7590            }
7591        } finally {
7592            Binder.restoreCallingIdentity(ident);
7593        }
7594    }
7595
7596    @Override
7597    public void stopLockTaskMode() {
7598//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7599//                "stopLockTaskMode()");
7600        synchronized (this) {
7601            mStackSupervisor.setLockTaskModeLocked(null);
7602        }
7603    }
7604
7605    @Override
7606    public boolean isInLockTaskMode() {
7607        synchronized (this) {
7608            return mStackSupervisor.isInLockTaskMode();
7609        }
7610    }
7611
7612    // =========================================================
7613    // CONTENT PROVIDERS
7614    // =========================================================
7615
7616    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7617        List<ProviderInfo> providers = null;
7618        try {
7619            providers = AppGlobals.getPackageManager().
7620                queryContentProviders(app.processName, app.uid,
7621                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7622        } catch (RemoteException ex) {
7623        }
7624        if (DEBUG_MU)
7625            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7626        int userId = app.userId;
7627        if (providers != null) {
7628            int N = providers.size();
7629            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7630            for (int i=0; i<N; i++) {
7631                ProviderInfo cpi =
7632                    (ProviderInfo)providers.get(i);
7633                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7634                        cpi.name, cpi.flags);
7635                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7636                    // This is a singleton provider, but a user besides the
7637                    // default user is asking to initialize a process it runs
7638                    // in...  well, no, it doesn't actually run in this process,
7639                    // it runs in the process of the default user.  Get rid of it.
7640                    providers.remove(i);
7641                    N--;
7642                    i--;
7643                    continue;
7644                }
7645
7646                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7647                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7648                if (cpr == null) {
7649                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7650                    mProviderMap.putProviderByClass(comp, cpr);
7651                }
7652                if (DEBUG_MU)
7653                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7654                app.pubProviders.put(cpi.name, cpr);
7655                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7656                    // Don't add this if it is a platform component that is marked
7657                    // to run in multiple processes, because this is actually
7658                    // part of the framework so doesn't make sense to track as a
7659                    // separate apk in the process.
7660                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7661                }
7662                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7663            }
7664        }
7665        return providers;
7666    }
7667
7668    /**
7669     * Check if {@link ProcessRecord} has a possible chance at accessing the
7670     * given {@link ProviderInfo}. Final permission checking is always done
7671     * in {@link ContentProvider}.
7672     */
7673    private final String checkContentProviderPermissionLocked(
7674            ProviderInfo cpi, ProcessRecord r) {
7675        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7676        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7677        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7678                cpi.applicationInfo.uid, cpi.exported)
7679                == PackageManager.PERMISSION_GRANTED) {
7680            return null;
7681        }
7682        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7683                cpi.applicationInfo.uid, cpi.exported)
7684                == PackageManager.PERMISSION_GRANTED) {
7685            return null;
7686        }
7687
7688        PathPermission[] pps = cpi.pathPermissions;
7689        if (pps != null) {
7690            int i = pps.length;
7691            while (i > 0) {
7692                i--;
7693                PathPermission pp = pps[i];
7694                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7695                        cpi.applicationInfo.uid, cpi.exported)
7696                        == PackageManager.PERMISSION_GRANTED) {
7697                    return null;
7698                }
7699                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7700                        cpi.applicationInfo.uid, cpi.exported)
7701                        == PackageManager.PERMISSION_GRANTED) {
7702                    return null;
7703                }
7704            }
7705        }
7706
7707        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7708        if (perms != null) {
7709            for (GrantUri uri : perms.keySet()) {
7710                if (uri.uri.getAuthority().equals(cpi.authority)) {
7711                    return null;
7712                }
7713            }
7714        }
7715
7716        String msg;
7717        if (!cpi.exported) {
7718            msg = "Permission Denial: opening provider " + cpi.name
7719                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7720                    + ", uid=" + callingUid + ") that is not exported from uid "
7721                    + cpi.applicationInfo.uid;
7722        } else {
7723            msg = "Permission Denial: opening provider " + cpi.name
7724                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7725                    + ", uid=" + callingUid + ") requires "
7726                    + cpi.readPermission + " or " + cpi.writePermission;
7727        }
7728        Slog.w(TAG, msg);
7729        return msg;
7730    }
7731
7732    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7733            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7734        if (r != null) {
7735            for (int i=0; i<r.conProviders.size(); i++) {
7736                ContentProviderConnection conn = r.conProviders.get(i);
7737                if (conn.provider == cpr) {
7738                    if (DEBUG_PROVIDER) Slog.v(TAG,
7739                            "Adding provider requested by "
7740                            + r.processName + " from process "
7741                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7742                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7743                    if (stable) {
7744                        conn.stableCount++;
7745                        conn.numStableIncs++;
7746                    } else {
7747                        conn.unstableCount++;
7748                        conn.numUnstableIncs++;
7749                    }
7750                    return conn;
7751                }
7752            }
7753            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7754            if (stable) {
7755                conn.stableCount = 1;
7756                conn.numStableIncs = 1;
7757            } else {
7758                conn.unstableCount = 1;
7759                conn.numUnstableIncs = 1;
7760            }
7761            cpr.connections.add(conn);
7762            r.conProviders.add(conn);
7763            return conn;
7764        }
7765        cpr.addExternalProcessHandleLocked(externalProcessToken);
7766        return null;
7767    }
7768
7769    boolean decProviderCountLocked(ContentProviderConnection conn,
7770            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7771        if (conn != null) {
7772            cpr = conn.provider;
7773            if (DEBUG_PROVIDER) Slog.v(TAG,
7774                    "Removing provider requested by "
7775                    + conn.client.processName + " from process "
7776                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7777                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7778            if (stable) {
7779                conn.stableCount--;
7780            } else {
7781                conn.unstableCount--;
7782            }
7783            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7784                cpr.connections.remove(conn);
7785                conn.client.conProviders.remove(conn);
7786                return true;
7787            }
7788            return false;
7789        }
7790        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7791        return false;
7792    }
7793
7794    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7795            String name, IBinder token, boolean stable, int userId) {
7796        ContentProviderRecord cpr;
7797        ContentProviderConnection conn = null;
7798        ProviderInfo cpi = null;
7799
7800        synchronized(this) {
7801            ProcessRecord r = null;
7802            if (caller != null) {
7803                r = getRecordForAppLocked(caller);
7804                if (r == null) {
7805                    throw new SecurityException(
7806                            "Unable to find app for caller " + caller
7807                          + " (pid=" + Binder.getCallingPid()
7808                          + ") when getting content provider " + name);
7809                }
7810            }
7811
7812            // First check if this content provider has been published...
7813            cpr = mProviderMap.getProviderByName(name, userId);
7814            boolean providerRunning = cpr != null;
7815            if (providerRunning) {
7816                cpi = cpr.info;
7817                String msg;
7818                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7819                    throw new SecurityException(msg);
7820                }
7821
7822                if (r != null && cpr.canRunHere(r)) {
7823                    // This provider has been published or is in the process
7824                    // of being published...  but it is also allowed to run
7825                    // in the caller's process, so don't make a connection
7826                    // and just let the caller instantiate its own instance.
7827                    ContentProviderHolder holder = cpr.newHolder(null);
7828                    // don't give caller the provider object, it needs
7829                    // to make its own.
7830                    holder.provider = null;
7831                    return holder;
7832                }
7833
7834                final long origId = Binder.clearCallingIdentity();
7835
7836                // In this case the provider instance already exists, so we can
7837                // return it right away.
7838                conn = incProviderCountLocked(r, cpr, token, stable);
7839                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7840                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7841                        // If this is a perceptible app accessing the provider,
7842                        // make sure to count it as being accessed and thus
7843                        // back up on the LRU list.  This is good because
7844                        // content providers are often expensive to start.
7845                        updateLruProcessLocked(cpr.proc, false, null);
7846                    }
7847                }
7848
7849                if (cpr.proc != null) {
7850                    if (false) {
7851                        if (cpr.name.flattenToShortString().equals(
7852                                "com.android.providers.calendar/.CalendarProvider2")) {
7853                            Slog.v(TAG, "****************** KILLING "
7854                                + cpr.name.flattenToShortString());
7855                            Process.killProcess(cpr.proc.pid);
7856                        }
7857                    }
7858                    boolean success = updateOomAdjLocked(cpr.proc);
7859                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7860                    // NOTE: there is still a race here where a signal could be
7861                    // pending on the process even though we managed to update its
7862                    // adj level.  Not sure what to do about this, but at least
7863                    // the race is now smaller.
7864                    if (!success) {
7865                        // Uh oh...  it looks like the provider's process
7866                        // has been killed on us.  We need to wait for a new
7867                        // process to be started, and make sure its death
7868                        // doesn't kill our process.
7869                        Slog.i(TAG,
7870                                "Existing provider " + cpr.name.flattenToShortString()
7871                                + " is crashing; detaching " + r);
7872                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7873                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7874                        if (!lastRef) {
7875                            // This wasn't the last ref our process had on
7876                            // the provider...  we have now been killed, bail.
7877                            return null;
7878                        }
7879                        providerRunning = false;
7880                        conn = null;
7881                    }
7882                }
7883
7884                Binder.restoreCallingIdentity(origId);
7885            }
7886
7887            boolean singleton;
7888            if (!providerRunning) {
7889                try {
7890                    cpi = AppGlobals.getPackageManager().
7891                        resolveContentProvider(name,
7892                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7893                } catch (RemoteException ex) {
7894                }
7895                if (cpi == null) {
7896                    return null;
7897                }
7898                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7899                        cpi.name, cpi.flags);
7900                if (singleton) {
7901                    userId = 0;
7902                }
7903                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7904
7905                String msg;
7906                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7907                    throw new SecurityException(msg);
7908                }
7909
7910                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
7911                        && !cpi.processName.equals("system")) {
7912                    // If this content provider does not run in the system
7913                    // process, and the system is not yet ready to run other
7914                    // processes, then fail fast instead of hanging.
7915                    throw new IllegalArgumentException(
7916                            "Attempt to launch content provider before system ready");
7917                }
7918
7919                // Make sure that the user who owns this provider is started.  If not,
7920                // we don't want to allow it to run.
7921                if (mStartedUsers.get(userId) == null) {
7922                    Slog.w(TAG, "Unable to launch app "
7923                            + cpi.applicationInfo.packageName + "/"
7924                            + cpi.applicationInfo.uid + " for provider "
7925                            + name + ": user " + userId + " is stopped");
7926                    return null;
7927                }
7928
7929                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7930                cpr = mProviderMap.getProviderByClass(comp, userId);
7931                final boolean firstClass = cpr == null;
7932                if (firstClass) {
7933                    try {
7934                        ApplicationInfo ai =
7935                            AppGlobals.getPackageManager().
7936                                getApplicationInfo(
7937                                        cpi.applicationInfo.packageName,
7938                                        STOCK_PM_FLAGS, userId);
7939                        if (ai == null) {
7940                            Slog.w(TAG, "No package info for content provider "
7941                                    + cpi.name);
7942                            return null;
7943                        }
7944                        ai = getAppInfoForUser(ai, userId);
7945                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
7946                    } catch (RemoteException ex) {
7947                        // pm is in same process, this will never happen.
7948                    }
7949                }
7950
7951                if (r != null && cpr.canRunHere(r)) {
7952                    // If this is a multiprocess provider, then just return its
7953                    // info and allow the caller to instantiate it.  Only do
7954                    // this if the provider is the same user as the caller's
7955                    // process, or can run as root (so can be in any process).
7956                    return cpr.newHolder(null);
7957                }
7958
7959                if (DEBUG_PROVIDER) {
7960                    RuntimeException e = new RuntimeException("here");
7961                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
7962                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
7963                }
7964
7965                // This is single process, and our app is now connecting to it.
7966                // See if we are already in the process of launching this
7967                // provider.
7968                final int N = mLaunchingProviders.size();
7969                int i;
7970                for (i=0; i<N; i++) {
7971                    if (mLaunchingProviders.get(i) == cpr) {
7972                        break;
7973                    }
7974                }
7975
7976                // If the provider is not already being launched, then get it
7977                // started.
7978                if (i >= N) {
7979                    final long origId = Binder.clearCallingIdentity();
7980
7981                    try {
7982                        // Content provider is now in use, its package can't be stopped.
7983                        try {
7984                            AppGlobals.getPackageManager().setPackageStoppedState(
7985                                    cpr.appInfo.packageName, false, userId);
7986                        } catch (RemoteException e) {
7987                        } catch (IllegalArgumentException e) {
7988                            Slog.w(TAG, "Failed trying to unstop package "
7989                                    + cpr.appInfo.packageName + ": " + e);
7990                        }
7991
7992                        // Use existing process if already started
7993                        ProcessRecord proc = getProcessRecordLocked(
7994                                cpi.processName, cpr.appInfo.uid, false);
7995                        if (proc != null && proc.thread != null) {
7996                            if (DEBUG_PROVIDER) {
7997                                Slog.d(TAG, "Installing in existing process " + proc);
7998                            }
7999                            proc.pubProviders.put(cpi.name, cpr);
8000                            try {
8001                                proc.thread.scheduleInstallProvider(cpi);
8002                            } catch (RemoteException e) {
8003                            }
8004                        } else {
8005                            proc = startProcessLocked(cpi.processName,
8006                                    cpr.appInfo, false, 0, "content provider",
8007                                    new ComponentName(cpi.applicationInfo.packageName,
8008                                            cpi.name), false, false, false);
8009                            if (proc == null) {
8010                                Slog.w(TAG, "Unable to launch app "
8011                                        + cpi.applicationInfo.packageName + "/"
8012                                        + cpi.applicationInfo.uid + " for provider "
8013                                        + name + ": process is bad");
8014                                return null;
8015                            }
8016                        }
8017                        cpr.launchingApp = proc;
8018                        mLaunchingProviders.add(cpr);
8019                    } finally {
8020                        Binder.restoreCallingIdentity(origId);
8021                    }
8022                }
8023
8024                // Make sure the provider is published (the same provider class
8025                // may be published under multiple names).
8026                if (firstClass) {
8027                    mProviderMap.putProviderByClass(comp, cpr);
8028                }
8029
8030                mProviderMap.putProviderByName(name, cpr);
8031                conn = incProviderCountLocked(r, cpr, token, stable);
8032                if (conn != null) {
8033                    conn.waiting = true;
8034                }
8035            }
8036        }
8037
8038        // Wait for the provider to be published...
8039        synchronized (cpr) {
8040            while (cpr.provider == null) {
8041                if (cpr.launchingApp == null) {
8042                    Slog.w(TAG, "Unable to launch app "
8043                            + cpi.applicationInfo.packageName + "/"
8044                            + cpi.applicationInfo.uid + " for provider "
8045                            + name + ": launching app became null");
8046                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8047                            UserHandle.getUserId(cpi.applicationInfo.uid),
8048                            cpi.applicationInfo.packageName,
8049                            cpi.applicationInfo.uid, name);
8050                    return null;
8051                }
8052                try {
8053                    if (DEBUG_MU) {
8054                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8055                                + cpr.launchingApp);
8056                    }
8057                    if (conn != null) {
8058                        conn.waiting = true;
8059                    }
8060                    cpr.wait();
8061                } catch (InterruptedException ex) {
8062                } finally {
8063                    if (conn != null) {
8064                        conn.waiting = false;
8065                    }
8066                }
8067            }
8068        }
8069        return cpr != null ? cpr.newHolder(conn) : null;
8070    }
8071
8072    public final ContentProviderHolder getContentProvider(
8073            IApplicationThread caller, String name, int userId, boolean stable) {
8074        enforceNotIsolatedCaller("getContentProvider");
8075        if (caller == null) {
8076            String msg = "null IApplicationThread when getting content provider "
8077                    + name;
8078            Slog.w(TAG, msg);
8079            throw new SecurityException(msg);
8080        }
8081
8082        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8083                false, true, "getContentProvider", null);
8084        return getContentProviderImpl(caller, name, null, stable, userId);
8085    }
8086
8087    public ContentProviderHolder getContentProviderExternal(
8088            String name, int userId, IBinder token) {
8089        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8090            "Do not have permission in call getContentProviderExternal()");
8091        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8092                false, true, "getContentProvider", null);
8093        return getContentProviderExternalUnchecked(name, token, userId);
8094    }
8095
8096    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8097            IBinder token, int userId) {
8098        return getContentProviderImpl(null, name, token, true, userId);
8099    }
8100
8101    /**
8102     * Drop a content provider from a ProcessRecord's bookkeeping
8103     */
8104    public void removeContentProvider(IBinder connection, boolean stable) {
8105        enforceNotIsolatedCaller("removeContentProvider");
8106        long ident = Binder.clearCallingIdentity();
8107        try {
8108            synchronized (this) {
8109                ContentProviderConnection conn;
8110                try {
8111                    conn = (ContentProviderConnection)connection;
8112                } catch (ClassCastException e) {
8113                    String msg ="removeContentProvider: " + connection
8114                            + " not a ContentProviderConnection";
8115                    Slog.w(TAG, msg);
8116                    throw new IllegalArgumentException(msg);
8117                }
8118                if (conn == null) {
8119                    throw new NullPointerException("connection is null");
8120                }
8121                if (decProviderCountLocked(conn, null, null, stable)) {
8122                    updateOomAdjLocked();
8123                }
8124            }
8125        } finally {
8126            Binder.restoreCallingIdentity(ident);
8127        }
8128    }
8129
8130    public void removeContentProviderExternal(String name, IBinder token) {
8131        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8132            "Do not have permission in call removeContentProviderExternal()");
8133        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8134    }
8135
8136    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8137        synchronized (this) {
8138            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8139            if(cpr == null) {
8140                //remove from mProvidersByClass
8141                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8142                return;
8143            }
8144
8145            //update content provider record entry info
8146            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8147            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8148            if (localCpr.hasExternalProcessHandles()) {
8149                if (localCpr.removeExternalProcessHandleLocked(token)) {
8150                    updateOomAdjLocked();
8151                } else {
8152                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8153                            + " with no external reference for token: "
8154                            + token + ".");
8155                }
8156            } else {
8157                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8158                        + " with no external references.");
8159            }
8160        }
8161    }
8162
8163    public final void publishContentProviders(IApplicationThread caller,
8164            List<ContentProviderHolder> providers) {
8165        if (providers == null) {
8166            return;
8167        }
8168
8169        enforceNotIsolatedCaller("publishContentProviders");
8170        synchronized (this) {
8171            final ProcessRecord r = getRecordForAppLocked(caller);
8172            if (DEBUG_MU)
8173                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8174            if (r == null) {
8175                throw new SecurityException(
8176                        "Unable to find app for caller " + caller
8177                      + " (pid=" + Binder.getCallingPid()
8178                      + ") when publishing content providers");
8179            }
8180
8181            final long origId = Binder.clearCallingIdentity();
8182
8183            final int N = providers.size();
8184            for (int i=0; i<N; i++) {
8185                ContentProviderHolder src = providers.get(i);
8186                if (src == null || src.info == null || src.provider == null) {
8187                    continue;
8188                }
8189                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8190                if (DEBUG_MU)
8191                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8192                if (dst != null) {
8193                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8194                    mProviderMap.putProviderByClass(comp, dst);
8195                    String names[] = dst.info.authority.split(";");
8196                    for (int j = 0; j < names.length; j++) {
8197                        mProviderMap.putProviderByName(names[j], dst);
8198                    }
8199
8200                    int NL = mLaunchingProviders.size();
8201                    int j;
8202                    for (j=0; j<NL; j++) {
8203                        if (mLaunchingProviders.get(j) == dst) {
8204                            mLaunchingProviders.remove(j);
8205                            j--;
8206                            NL--;
8207                        }
8208                    }
8209                    synchronized (dst) {
8210                        dst.provider = src.provider;
8211                        dst.proc = r;
8212                        dst.notifyAll();
8213                    }
8214                    updateOomAdjLocked(r);
8215                }
8216            }
8217
8218            Binder.restoreCallingIdentity(origId);
8219        }
8220    }
8221
8222    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8223        ContentProviderConnection conn;
8224        try {
8225            conn = (ContentProviderConnection)connection;
8226        } catch (ClassCastException e) {
8227            String msg ="refContentProvider: " + connection
8228                    + " not a ContentProviderConnection";
8229            Slog.w(TAG, msg);
8230            throw new IllegalArgumentException(msg);
8231        }
8232        if (conn == null) {
8233            throw new NullPointerException("connection is null");
8234        }
8235
8236        synchronized (this) {
8237            if (stable > 0) {
8238                conn.numStableIncs += stable;
8239            }
8240            stable = conn.stableCount + stable;
8241            if (stable < 0) {
8242                throw new IllegalStateException("stableCount < 0: " + stable);
8243            }
8244
8245            if (unstable > 0) {
8246                conn.numUnstableIncs += unstable;
8247            }
8248            unstable = conn.unstableCount + unstable;
8249            if (unstable < 0) {
8250                throw new IllegalStateException("unstableCount < 0: " + unstable);
8251            }
8252
8253            if ((stable+unstable) <= 0) {
8254                throw new IllegalStateException("ref counts can't go to zero here: stable="
8255                        + stable + " unstable=" + unstable);
8256            }
8257            conn.stableCount = stable;
8258            conn.unstableCount = unstable;
8259            return !conn.dead;
8260        }
8261    }
8262
8263    public void unstableProviderDied(IBinder connection) {
8264        ContentProviderConnection conn;
8265        try {
8266            conn = (ContentProviderConnection)connection;
8267        } catch (ClassCastException e) {
8268            String msg ="refContentProvider: " + connection
8269                    + " not a ContentProviderConnection";
8270            Slog.w(TAG, msg);
8271            throw new IllegalArgumentException(msg);
8272        }
8273        if (conn == null) {
8274            throw new NullPointerException("connection is null");
8275        }
8276
8277        // Safely retrieve the content provider associated with the connection.
8278        IContentProvider provider;
8279        synchronized (this) {
8280            provider = conn.provider.provider;
8281        }
8282
8283        if (provider == null) {
8284            // Um, yeah, we're way ahead of you.
8285            return;
8286        }
8287
8288        // Make sure the caller is being honest with us.
8289        if (provider.asBinder().pingBinder()) {
8290            // Er, no, still looks good to us.
8291            synchronized (this) {
8292                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8293                        + " says " + conn + " died, but we don't agree");
8294                return;
8295            }
8296        }
8297
8298        // Well look at that!  It's dead!
8299        synchronized (this) {
8300            if (conn.provider.provider != provider) {
8301                // But something changed...  good enough.
8302                return;
8303            }
8304
8305            ProcessRecord proc = conn.provider.proc;
8306            if (proc == null || proc.thread == null) {
8307                // Seems like the process is already cleaned up.
8308                return;
8309            }
8310
8311            // As far as we're concerned, this is just like receiving a
8312            // death notification...  just a bit prematurely.
8313            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8314                    + ") early provider death");
8315            final long ident = Binder.clearCallingIdentity();
8316            try {
8317                appDiedLocked(proc, proc.pid, proc.thread);
8318            } finally {
8319                Binder.restoreCallingIdentity(ident);
8320            }
8321        }
8322    }
8323
8324    @Override
8325    public void appNotRespondingViaProvider(IBinder connection) {
8326        enforceCallingPermission(
8327                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8328
8329        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8330        if (conn == null) {
8331            Slog.w(TAG, "ContentProviderConnection is null");
8332            return;
8333        }
8334
8335        final ProcessRecord host = conn.provider.proc;
8336        if (host == null) {
8337            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8338            return;
8339        }
8340
8341        final long token = Binder.clearCallingIdentity();
8342        try {
8343            appNotResponding(host, null, null, false, "ContentProvider not responding");
8344        } finally {
8345            Binder.restoreCallingIdentity(token);
8346        }
8347    }
8348
8349    public final void installSystemProviders() {
8350        List<ProviderInfo> providers;
8351        synchronized (this) {
8352            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8353            providers = generateApplicationProvidersLocked(app);
8354            if (providers != null) {
8355                for (int i=providers.size()-1; i>=0; i--) {
8356                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8357                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8358                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8359                                + ": not system .apk");
8360                        providers.remove(i);
8361                    }
8362                }
8363            }
8364        }
8365        if (providers != null) {
8366            mSystemThread.installSystemProviders(providers);
8367        }
8368
8369        mCoreSettingsObserver = new CoreSettingsObserver(this);
8370
8371        mUsageStatsService.monitorPackages();
8372    }
8373
8374    /**
8375     * Allows app to retrieve the MIME type of a URI without having permission
8376     * to access its content provider.
8377     *
8378     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8379     *
8380     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8381     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8382     */
8383    public String getProviderMimeType(Uri uri, int userId) {
8384        enforceNotIsolatedCaller("getProviderMimeType");
8385        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8386                userId, false, true, "getProviderMimeType", null);
8387        final String name = uri.getAuthority();
8388        final long ident = Binder.clearCallingIdentity();
8389        ContentProviderHolder holder = null;
8390
8391        try {
8392            holder = getContentProviderExternalUnchecked(name, null, userId);
8393            if (holder != null) {
8394                return holder.provider.getType(uri);
8395            }
8396        } catch (RemoteException e) {
8397            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8398            return null;
8399        } finally {
8400            if (holder != null) {
8401                removeContentProviderExternalUnchecked(name, null, userId);
8402            }
8403            Binder.restoreCallingIdentity(ident);
8404        }
8405
8406        return null;
8407    }
8408
8409    // =========================================================
8410    // GLOBAL MANAGEMENT
8411    // =========================================================
8412
8413    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8414            boolean isolated) {
8415        String proc = customProcess != null ? customProcess : info.processName;
8416        BatteryStatsImpl.Uid.Proc ps = null;
8417        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8418        int uid = info.uid;
8419        if (isolated) {
8420            int userId = UserHandle.getUserId(uid);
8421            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8422            while (true) {
8423                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8424                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8425                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8426                }
8427                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8428                mNextIsolatedProcessUid++;
8429                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8430                    // No process for this uid, use it.
8431                    break;
8432                }
8433                stepsLeft--;
8434                if (stepsLeft <= 0) {
8435                    return null;
8436                }
8437            }
8438        }
8439        return new ProcessRecord(stats, info, proc, uid);
8440    }
8441
8442    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8443        ProcessRecord app;
8444        if (!isolated) {
8445            app = getProcessRecordLocked(info.processName, info.uid, true);
8446        } else {
8447            app = null;
8448        }
8449
8450        if (app == null) {
8451            app = newProcessRecordLocked(info, null, isolated);
8452            mProcessNames.put(info.processName, app.uid, app);
8453            if (isolated) {
8454                mIsolatedProcesses.put(app.uid, app);
8455            }
8456            updateLruProcessLocked(app, false, null);
8457            updateOomAdjLocked();
8458        }
8459
8460        // This package really, really can not be stopped.
8461        try {
8462            AppGlobals.getPackageManager().setPackageStoppedState(
8463                    info.packageName, false, UserHandle.getUserId(app.uid));
8464        } catch (RemoteException e) {
8465        } catch (IllegalArgumentException e) {
8466            Slog.w(TAG, "Failed trying to unstop package "
8467                    + info.packageName + ": " + e);
8468        }
8469
8470        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8471                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8472            app.persistent = true;
8473            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8474        }
8475        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8476            mPersistentStartingProcesses.add(app);
8477            startProcessLocked(app, "added application", app.processName);
8478        }
8479
8480        return app;
8481    }
8482
8483    public void unhandledBack() {
8484        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8485                "unhandledBack()");
8486
8487        synchronized(this) {
8488            final long origId = Binder.clearCallingIdentity();
8489            try {
8490                getFocusedStack().unhandledBackLocked();
8491            } finally {
8492                Binder.restoreCallingIdentity(origId);
8493            }
8494        }
8495    }
8496
8497    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8498        enforceNotIsolatedCaller("openContentUri");
8499        final int userId = UserHandle.getCallingUserId();
8500        String name = uri.getAuthority();
8501        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8502        ParcelFileDescriptor pfd = null;
8503        if (cph != null) {
8504            // We record the binder invoker's uid in thread-local storage before
8505            // going to the content provider to open the file.  Later, in the code
8506            // that handles all permissions checks, we look for this uid and use
8507            // that rather than the Activity Manager's own uid.  The effect is that
8508            // we do the check against the caller's permissions even though it looks
8509            // to the content provider like the Activity Manager itself is making
8510            // the request.
8511            sCallerIdentity.set(new Identity(
8512                    Binder.getCallingPid(), Binder.getCallingUid()));
8513            try {
8514                pfd = cph.provider.openFile(null, uri, "r", null);
8515            } catch (FileNotFoundException e) {
8516                // do nothing; pfd will be returned null
8517            } finally {
8518                // Ensure that whatever happens, we clean up the identity state
8519                sCallerIdentity.remove();
8520            }
8521
8522            // We've got the fd now, so we're done with the provider.
8523            removeContentProviderExternalUnchecked(name, null, userId);
8524        } else {
8525            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8526        }
8527        return pfd;
8528    }
8529
8530    // Actually is sleeping or shutting down or whatever else in the future
8531    // is an inactive state.
8532    public boolean isSleepingOrShuttingDown() {
8533        return mSleeping || mShuttingDown;
8534    }
8535
8536    public boolean isSleeping() {
8537        return mSleeping;
8538    }
8539
8540    void goingToSleep() {
8541        synchronized(this) {
8542            mWentToSleep = true;
8543            updateEventDispatchingLocked();
8544            goToSleepIfNeededLocked();
8545        }
8546    }
8547
8548    void finishRunningVoiceLocked() {
8549        if (mRunningVoice) {
8550            mRunningVoice = false;
8551            goToSleepIfNeededLocked();
8552        }
8553    }
8554
8555    void goToSleepIfNeededLocked() {
8556        if (mWentToSleep && !mRunningVoice) {
8557            if (!mSleeping) {
8558                mSleeping = true;
8559                mStackSupervisor.goingToSleepLocked();
8560
8561                // Initialize the wake times of all processes.
8562                checkExcessivePowerUsageLocked(false);
8563                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8564                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8565                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8566            }
8567        }
8568    }
8569
8570    @Override
8571    public boolean shutdown(int timeout) {
8572        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8573                != PackageManager.PERMISSION_GRANTED) {
8574            throw new SecurityException("Requires permission "
8575                    + android.Manifest.permission.SHUTDOWN);
8576        }
8577
8578        boolean timedout = false;
8579
8580        synchronized(this) {
8581            mShuttingDown = true;
8582            updateEventDispatchingLocked();
8583            timedout = mStackSupervisor.shutdownLocked(timeout);
8584        }
8585
8586        mAppOpsService.shutdown();
8587        mUsageStatsService.shutdown();
8588        mBatteryStatsService.shutdown();
8589        synchronized (this) {
8590            mProcessStats.shutdownLocked();
8591        }
8592
8593        return timedout;
8594    }
8595
8596    public final void activitySlept(IBinder token) {
8597        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8598
8599        final long origId = Binder.clearCallingIdentity();
8600
8601        synchronized (this) {
8602            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8603            if (r != null) {
8604                mStackSupervisor.activitySleptLocked(r);
8605            }
8606        }
8607
8608        Binder.restoreCallingIdentity(origId);
8609    }
8610
8611    void logLockScreen(String msg) {
8612        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8613                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8614                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8615                mStackSupervisor.mDismissKeyguardOnNextActivity);
8616    }
8617
8618    private void comeOutOfSleepIfNeededLocked() {
8619        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
8620            if (mSleeping) {
8621                mSleeping = false;
8622                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8623            }
8624        }
8625    }
8626
8627    void wakingUp() {
8628        synchronized(this) {
8629            mWentToSleep = false;
8630            updateEventDispatchingLocked();
8631            comeOutOfSleepIfNeededLocked();
8632        }
8633    }
8634
8635    void startRunningVoiceLocked() {
8636        if (!mRunningVoice) {
8637            mRunningVoice = true;
8638            comeOutOfSleepIfNeededLocked();
8639        }
8640    }
8641
8642    private void updateEventDispatchingLocked() {
8643        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8644    }
8645
8646    public void setLockScreenShown(boolean shown) {
8647        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8648                != PackageManager.PERMISSION_GRANTED) {
8649            throw new SecurityException("Requires permission "
8650                    + android.Manifest.permission.DEVICE_POWER);
8651        }
8652
8653        synchronized(this) {
8654            long ident = Binder.clearCallingIdentity();
8655            try {
8656                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8657                mLockScreenShown = shown;
8658                comeOutOfSleepIfNeededLocked();
8659            } finally {
8660                Binder.restoreCallingIdentity(ident);
8661            }
8662        }
8663    }
8664
8665    public void stopAppSwitches() {
8666        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8667                != PackageManager.PERMISSION_GRANTED) {
8668            throw new SecurityException("Requires permission "
8669                    + android.Manifest.permission.STOP_APP_SWITCHES);
8670        }
8671
8672        synchronized(this) {
8673            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8674                    + APP_SWITCH_DELAY_TIME;
8675            mDidAppSwitch = false;
8676            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8677            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8678            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8679        }
8680    }
8681
8682    public void resumeAppSwitches() {
8683        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8684                != PackageManager.PERMISSION_GRANTED) {
8685            throw new SecurityException("Requires permission "
8686                    + android.Manifest.permission.STOP_APP_SWITCHES);
8687        }
8688
8689        synchronized(this) {
8690            // Note that we don't execute any pending app switches... we will
8691            // let those wait until either the timeout, or the next start
8692            // activity request.
8693            mAppSwitchesAllowedTime = 0;
8694        }
8695    }
8696
8697    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8698            String name) {
8699        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8700            return true;
8701        }
8702
8703        final int perm = checkComponentPermission(
8704                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8705                callingUid, -1, true);
8706        if (perm == PackageManager.PERMISSION_GRANTED) {
8707            return true;
8708        }
8709
8710        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8711        return false;
8712    }
8713
8714    public void setDebugApp(String packageName, boolean waitForDebugger,
8715            boolean persistent) {
8716        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8717                "setDebugApp()");
8718
8719        long ident = Binder.clearCallingIdentity();
8720        try {
8721            // Note that this is not really thread safe if there are multiple
8722            // callers into it at the same time, but that's not a situation we
8723            // care about.
8724            if (persistent) {
8725                final ContentResolver resolver = mContext.getContentResolver();
8726                Settings.Global.putString(
8727                    resolver, Settings.Global.DEBUG_APP,
8728                    packageName);
8729                Settings.Global.putInt(
8730                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8731                    waitForDebugger ? 1 : 0);
8732            }
8733
8734            synchronized (this) {
8735                if (!persistent) {
8736                    mOrigDebugApp = mDebugApp;
8737                    mOrigWaitForDebugger = mWaitForDebugger;
8738                }
8739                mDebugApp = packageName;
8740                mWaitForDebugger = waitForDebugger;
8741                mDebugTransient = !persistent;
8742                if (packageName != null) {
8743                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8744                            false, UserHandle.USER_ALL, "set debug app");
8745                }
8746            }
8747        } finally {
8748            Binder.restoreCallingIdentity(ident);
8749        }
8750    }
8751
8752    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8753        synchronized (this) {
8754            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8755            if (!isDebuggable) {
8756                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8757                    throw new SecurityException("Process not debuggable: " + app.packageName);
8758                }
8759            }
8760
8761            mOpenGlTraceApp = processName;
8762        }
8763    }
8764
8765    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8766            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8767        synchronized (this) {
8768            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8769            if (!isDebuggable) {
8770                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8771                    throw new SecurityException("Process not debuggable: " + app.packageName);
8772                }
8773            }
8774            mProfileApp = processName;
8775            mProfileFile = profileFile;
8776            if (mProfileFd != null) {
8777                try {
8778                    mProfileFd.close();
8779                } catch (IOException e) {
8780                }
8781                mProfileFd = null;
8782            }
8783            mProfileFd = profileFd;
8784            mProfileType = 0;
8785            mAutoStopProfiler = autoStopProfiler;
8786        }
8787    }
8788
8789    @Override
8790    public void setAlwaysFinish(boolean enabled) {
8791        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8792                "setAlwaysFinish()");
8793
8794        Settings.Global.putInt(
8795                mContext.getContentResolver(),
8796                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8797
8798        synchronized (this) {
8799            mAlwaysFinishActivities = enabled;
8800        }
8801    }
8802
8803    @Override
8804    public void setActivityController(IActivityController controller) {
8805        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8806                "setActivityController()");
8807        synchronized (this) {
8808            mController = controller;
8809            Watchdog.getInstance().setActivityController(controller);
8810        }
8811    }
8812
8813    @Override
8814    public void setUserIsMonkey(boolean userIsMonkey) {
8815        synchronized (this) {
8816            synchronized (mPidsSelfLocked) {
8817                final int callingPid = Binder.getCallingPid();
8818                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8819                if (precessRecord == null) {
8820                    throw new SecurityException("Unknown process: " + callingPid);
8821                }
8822                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8823                    throw new SecurityException("Only an instrumentation process "
8824                            + "with a UiAutomation can call setUserIsMonkey");
8825                }
8826            }
8827            mUserIsMonkey = userIsMonkey;
8828        }
8829    }
8830
8831    @Override
8832    public boolean isUserAMonkey() {
8833        synchronized (this) {
8834            // If there is a controller also implies the user is a monkey.
8835            return (mUserIsMonkey || mController != null);
8836        }
8837    }
8838
8839    public void requestBugReport() {
8840        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8841        SystemProperties.set("ctl.start", "bugreport");
8842    }
8843
8844    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8845        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8846    }
8847
8848    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8849        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8850            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8851        }
8852        return KEY_DISPATCHING_TIMEOUT;
8853    }
8854
8855    @Override
8856    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8857        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8858                != PackageManager.PERMISSION_GRANTED) {
8859            throw new SecurityException("Requires permission "
8860                    + android.Manifest.permission.FILTER_EVENTS);
8861        }
8862        ProcessRecord proc;
8863        long timeout;
8864        synchronized (this) {
8865            synchronized (mPidsSelfLocked) {
8866                proc = mPidsSelfLocked.get(pid);
8867            }
8868            timeout = getInputDispatchingTimeoutLocked(proc);
8869        }
8870
8871        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8872            return -1;
8873        }
8874
8875        return timeout;
8876    }
8877
8878    /**
8879     * Handle input dispatching timeouts.
8880     * Returns whether input dispatching should be aborted or not.
8881     */
8882    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8883            final ActivityRecord activity, final ActivityRecord parent,
8884            final boolean aboveSystem, String reason) {
8885        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8886                != PackageManager.PERMISSION_GRANTED) {
8887            throw new SecurityException("Requires permission "
8888                    + android.Manifest.permission.FILTER_EVENTS);
8889        }
8890
8891        final String annotation;
8892        if (reason == null) {
8893            annotation = "Input dispatching timed out";
8894        } else {
8895            annotation = "Input dispatching timed out (" + reason + ")";
8896        }
8897
8898        if (proc != null) {
8899            synchronized (this) {
8900                if (proc.debugging) {
8901                    return false;
8902                }
8903
8904                if (mDidDexOpt) {
8905                    // Give more time since we were dexopting.
8906                    mDidDexOpt = false;
8907                    return false;
8908                }
8909
8910                if (proc.instrumentationClass != null) {
8911                    Bundle info = new Bundle();
8912                    info.putString("shortMsg", "keyDispatchingTimedOut");
8913                    info.putString("longMsg", annotation);
8914                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8915                    return true;
8916                }
8917            }
8918            mHandler.post(new Runnable() {
8919                @Override
8920                public void run() {
8921                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
8922                }
8923            });
8924        }
8925
8926        return true;
8927    }
8928
8929    public Bundle getAssistContextExtras(int requestType) {
8930        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
8931                "getAssistContextExtras()");
8932        PendingAssistExtras pae;
8933        Bundle extras = new Bundle();
8934        synchronized (this) {
8935            ActivityRecord activity = getFocusedStack().mResumedActivity;
8936            if (activity == null) {
8937                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
8938                return null;
8939            }
8940            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
8941            if (activity.app == null || activity.app.thread == null) {
8942                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
8943                return extras;
8944            }
8945            if (activity.app.pid == Binder.getCallingPid()) {
8946                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
8947                return extras;
8948            }
8949            pae = new PendingAssistExtras(activity);
8950            try {
8951                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
8952                        requestType);
8953                mPendingAssistExtras.add(pae);
8954                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
8955            } catch (RemoteException e) {
8956                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
8957                return extras;
8958            }
8959        }
8960        synchronized (pae) {
8961            while (!pae.haveResult) {
8962                try {
8963                    pae.wait();
8964                } catch (InterruptedException e) {
8965                }
8966            }
8967            if (pae.result != null) {
8968                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
8969            }
8970        }
8971        synchronized (this) {
8972            mPendingAssistExtras.remove(pae);
8973            mHandler.removeCallbacks(pae);
8974        }
8975        return extras;
8976    }
8977
8978    public void reportAssistContextExtras(IBinder token, Bundle extras) {
8979        PendingAssistExtras pae = (PendingAssistExtras)token;
8980        synchronized (pae) {
8981            pae.result = extras;
8982            pae.haveResult = true;
8983            pae.notifyAll();
8984        }
8985    }
8986
8987    public void registerProcessObserver(IProcessObserver observer) {
8988        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8989                "registerProcessObserver()");
8990        synchronized (this) {
8991            mProcessObservers.register(observer);
8992        }
8993    }
8994
8995    @Override
8996    public void unregisterProcessObserver(IProcessObserver observer) {
8997        synchronized (this) {
8998            mProcessObservers.unregister(observer);
8999        }
9000    }
9001
9002    @Override
9003    public boolean convertFromTranslucent(IBinder token) {
9004        final long origId = Binder.clearCallingIdentity();
9005        try {
9006            synchronized (this) {
9007                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9008                if (r == null) {
9009                    return false;
9010                }
9011                if (r.changeWindowTranslucency(true)) {
9012                    mWindowManager.setAppFullscreen(token, true);
9013                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9014                    return true;
9015                }
9016                return false;
9017            }
9018        } finally {
9019            Binder.restoreCallingIdentity(origId);
9020        }
9021    }
9022
9023    @Override
9024    public boolean convertToTranslucent(IBinder token) {
9025        final long origId = Binder.clearCallingIdentity();
9026        try {
9027            synchronized (this) {
9028                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9029                if (r == null) {
9030                    return false;
9031                }
9032                if (r.changeWindowTranslucency(false)) {
9033                    r.task.stack.convertToTranslucent(r);
9034                    mWindowManager.setAppFullscreen(token, false);
9035                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9036                    return true;
9037                }
9038                return false;
9039            }
9040        } finally {
9041            Binder.restoreCallingIdentity(origId);
9042        }
9043    }
9044
9045    @Override
9046    public void setImmersive(IBinder token, boolean immersive) {
9047        synchronized(this) {
9048            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9049            if (r == null) {
9050                throw new IllegalArgumentException();
9051            }
9052            r.immersive = immersive;
9053
9054            // update associated state if we're frontmost
9055            if (r == mFocusedActivity) {
9056                if (DEBUG_IMMERSIVE) {
9057                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9058                }
9059                applyUpdateLockStateLocked(r);
9060            }
9061        }
9062    }
9063
9064    @Override
9065    public boolean isImmersive(IBinder token) {
9066        synchronized (this) {
9067            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9068            if (r == null) {
9069                throw new IllegalArgumentException();
9070            }
9071            return r.immersive;
9072        }
9073    }
9074
9075    public boolean isTopActivityImmersive() {
9076        enforceNotIsolatedCaller("startActivity");
9077        synchronized (this) {
9078            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9079            return (r != null) ? r.immersive : false;
9080        }
9081    }
9082
9083    public final void enterSafeMode() {
9084        synchronized(this) {
9085            // It only makes sense to do this before the system is ready
9086            // and started launching other packages.
9087            if (!mSystemReady) {
9088                try {
9089                    AppGlobals.getPackageManager().enterSafeMode();
9090                } catch (RemoteException e) {
9091                }
9092            }
9093
9094            mSafeMode = true;
9095        }
9096    }
9097
9098    public final void showSafeModeOverlay() {
9099        View v = LayoutInflater.from(mContext).inflate(
9100                com.android.internal.R.layout.safe_mode, null);
9101        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9102        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9103        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9104        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9105        lp.gravity = Gravity.BOTTOM | Gravity.START;
9106        lp.format = v.getBackground().getOpacity();
9107        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9108                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9109        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9110        ((WindowManager)mContext.getSystemService(
9111                Context.WINDOW_SERVICE)).addView(v, lp);
9112    }
9113
9114    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9115        if (!(sender instanceof PendingIntentRecord)) {
9116            return;
9117        }
9118        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9119        synchronized (stats) {
9120            if (mBatteryStatsService.isOnBattery()) {
9121                mBatteryStatsService.enforceCallingPermission();
9122                PendingIntentRecord rec = (PendingIntentRecord)sender;
9123                int MY_UID = Binder.getCallingUid();
9124                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9125                BatteryStatsImpl.Uid.Pkg pkg =
9126                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9127                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9128                pkg.incWakeupsLocked();
9129            }
9130        }
9131    }
9132
9133    public boolean killPids(int[] pids, String pReason, boolean secure) {
9134        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9135            throw new SecurityException("killPids only available to the system");
9136        }
9137        String reason = (pReason == null) ? "Unknown" : pReason;
9138        // XXX Note: don't acquire main activity lock here, because the window
9139        // manager calls in with its locks held.
9140
9141        boolean killed = false;
9142        synchronized (mPidsSelfLocked) {
9143            int[] types = new int[pids.length];
9144            int worstType = 0;
9145            for (int i=0; i<pids.length; i++) {
9146                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9147                if (proc != null) {
9148                    int type = proc.setAdj;
9149                    types[i] = type;
9150                    if (type > worstType) {
9151                        worstType = type;
9152                    }
9153                }
9154            }
9155
9156            // If the worst oom_adj is somewhere in the cached proc LRU range,
9157            // then constrain it so we will kill all cached procs.
9158            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9159                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9160                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9161            }
9162
9163            // If this is not a secure call, don't let it kill processes that
9164            // are important.
9165            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9166                worstType = ProcessList.SERVICE_ADJ;
9167            }
9168
9169            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9170            for (int i=0; i<pids.length; i++) {
9171                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9172                if (proc == null) {
9173                    continue;
9174                }
9175                int adj = proc.setAdj;
9176                if (adj >= worstType && !proc.killedByAm) {
9177                    killUnneededProcessLocked(proc, reason);
9178                    killed = true;
9179                }
9180            }
9181        }
9182        return killed;
9183    }
9184
9185    @Override
9186    public void killUid(int uid, String reason) {
9187        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9188            throw new SecurityException("killUid only available to the system");
9189        }
9190        synchronized (this) {
9191            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9192                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9193                    reason != null ? reason : "kill uid");
9194        }
9195    }
9196
9197    @Override
9198    public boolean killProcessesBelowForeground(String reason) {
9199        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9200            throw new SecurityException("killProcessesBelowForeground() only available to system");
9201        }
9202
9203        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9204    }
9205
9206    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9207        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9208            throw new SecurityException("killProcessesBelowAdj() only available to system");
9209        }
9210
9211        boolean killed = false;
9212        synchronized (mPidsSelfLocked) {
9213            final int size = mPidsSelfLocked.size();
9214            for (int i = 0; i < size; i++) {
9215                final int pid = mPidsSelfLocked.keyAt(i);
9216                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9217                if (proc == null) continue;
9218
9219                final int adj = proc.setAdj;
9220                if (adj > belowAdj && !proc.killedByAm) {
9221                    killUnneededProcessLocked(proc, reason);
9222                    killed = true;
9223                }
9224            }
9225        }
9226        return killed;
9227    }
9228
9229    @Override
9230    public void hang(final IBinder who, boolean allowRestart) {
9231        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9232                != PackageManager.PERMISSION_GRANTED) {
9233            throw new SecurityException("Requires permission "
9234                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9235        }
9236
9237        final IBinder.DeathRecipient death = new DeathRecipient() {
9238            @Override
9239            public void binderDied() {
9240                synchronized (this) {
9241                    notifyAll();
9242                }
9243            }
9244        };
9245
9246        try {
9247            who.linkToDeath(death, 0);
9248        } catch (RemoteException e) {
9249            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9250            return;
9251        }
9252
9253        synchronized (this) {
9254            Watchdog.getInstance().setAllowRestart(allowRestart);
9255            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9256            synchronized (death) {
9257                while (who.isBinderAlive()) {
9258                    try {
9259                        death.wait();
9260                    } catch (InterruptedException e) {
9261                    }
9262                }
9263            }
9264            Watchdog.getInstance().setAllowRestart(true);
9265        }
9266    }
9267
9268    @Override
9269    public void restart() {
9270        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9271                != PackageManager.PERMISSION_GRANTED) {
9272            throw new SecurityException("Requires permission "
9273                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9274        }
9275
9276        Log.i(TAG, "Sending shutdown broadcast...");
9277
9278        BroadcastReceiver br = new BroadcastReceiver() {
9279            @Override public void onReceive(Context context, Intent intent) {
9280                // Now the broadcast is done, finish up the low-level shutdown.
9281                Log.i(TAG, "Shutting down activity manager...");
9282                shutdown(10000);
9283                Log.i(TAG, "Shutdown complete, restarting!");
9284                Process.killProcess(Process.myPid());
9285                System.exit(10);
9286            }
9287        };
9288
9289        // First send the high-level shut down broadcast.
9290        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9291        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9292        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9293        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9294        mContext.sendOrderedBroadcastAsUser(intent,
9295                UserHandle.ALL, null, br, mHandler, 0, null, null);
9296        */
9297        br.onReceive(mContext, intent);
9298    }
9299
9300    private long getLowRamTimeSinceIdle(long now) {
9301        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9302    }
9303
9304    @Override
9305    public void performIdleMaintenance() {
9306        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9307                != PackageManager.PERMISSION_GRANTED) {
9308            throw new SecurityException("Requires permission "
9309                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9310        }
9311
9312        synchronized (this) {
9313            final long now = SystemClock.uptimeMillis();
9314            final long timeSinceLastIdle = now - mLastIdleTime;
9315            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9316            mLastIdleTime = now;
9317            mLowRamTimeSinceLastIdle = 0;
9318            if (mLowRamStartTime != 0) {
9319                mLowRamStartTime = now;
9320            }
9321
9322            StringBuilder sb = new StringBuilder(128);
9323            sb.append("Idle maintenance over ");
9324            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9325            sb.append(" low RAM for ");
9326            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9327            Slog.i(TAG, sb.toString());
9328
9329            // If at least 1/3 of our time since the last idle period has been spent
9330            // with RAM low, then we want to kill processes.
9331            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9332
9333            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9334                ProcessRecord proc = mLruProcesses.get(i);
9335                if (proc.notCachedSinceIdle) {
9336                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9337                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9338                        if (doKilling && proc.initialIdlePss != 0
9339                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9340                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9341                                    + " from " + proc.initialIdlePss + ")");
9342                        }
9343                    }
9344                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9345                    proc.notCachedSinceIdle = true;
9346                    proc.initialIdlePss = 0;
9347                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9348                            isSleeping(), now);
9349                }
9350            }
9351
9352            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9353            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9354        }
9355    }
9356
9357    private void retrieveSettings() {
9358        final ContentResolver resolver = mContext.getContentResolver();
9359        String debugApp = Settings.Global.getString(
9360            resolver, Settings.Global.DEBUG_APP);
9361        boolean waitForDebugger = Settings.Global.getInt(
9362            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9363        boolean alwaysFinishActivities = Settings.Global.getInt(
9364            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9365        boolean forceRtl = Settings.Global.getInt(
9366                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9367        // Transfer any global setting for forcing RTL layout, into a System Property
9368        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9369
9370        Configuration configuration = new Configuration();
9371        Settings.System.getConfiguration(resolver, configuration);
9372        if (forceRtl) {
9373            // This will take care of setting the correct layout direction flags
9374            configuration.setLayoutDirection(configuration.locale);
9375        }
9376
9377        synchronized (this) {
9378            mDebugApp = mOrigDebugApp = debugApp;
9379            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9380            mAlwaysFinishActivities = alwaysFinishActivities;
9381            // This happens before any activities are started, so we can
9382            // change mConfiguration in-place.
9383            updateConfigurationLocked(configuration, null, false, true);
9384            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9385        }
9386    }
9387
9388    public boolean testIsSystemReady() {
9389        // no need to synchronize(this) just to read & return the value
9390        return mSystemReady;
9391    }
9392
9393    private static File getCalledPreBootReceiversFile() {
9394        File dataDir = Environment.getDataDirectory();
9395        File systemDir = new File(dataDir, "system");
9396        File fname = new File(systemDir, "called_pre_boots.dat");
9397        return fname;
9398    }
9399
9400    static final int LAST_DONE_VERSION = 10000;
9401
9402    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9403        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9404        File file = getCalledPreBootReceiversFile();
9405        FileInputStream fis = null;
9406        try {
9407            fis = new FileInputStream(file);
9408            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9409            int fvers = dis.readInt();
9410            if (fvers == LAST_DONE_VERSION) {
9411                String vers = dis.readUTF();
9412                String codename = dis.readUTF();
9413                String build = dis.readUTF();
9414                if (android.os.Build.VERSION.RELEASE.equals(vers)
9415                        && android.os.Build.VERSION.CODENAME.equals(codename)
9416                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9417                    int num = dis.readInt();
9418                    while (num > 0) {
9419                        num--;
9420                        String pkg = dis.readUTF();
9421                        String cls = dis.readUTF();
9422                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9423                    }
9424                }
9425            }
9426        } catch (FileNotFoundException e) {
9427        } catch (IOException e) {
9428            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9429        } finally {
9430            if (fis != null) {
9431                try {
9432                    fis.close();
9433                } catch (IOException e) {
9434                }
9435            }
9436        }
9437        return lastDoneReceivers;
9438    }
9439
9440    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9441        File file = getCalledPreBootReceiversFile();
9442        FileOutputStream fos = null;
9443        DataOutputStream dos = null;
9444        try {
9445            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9446            fos = new FileOutputStream(file);
9447            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9448            dos.writeInt(LAST_DONE_VERSION);
9449            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9450            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9451            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9452            dos.writeInt(list.size());
9453            for (int i=0; i<list.size(); i++) {
9454                dos.writeUTF(list.get(i).getPackageName());
9455                dos.writeUTF(list.get(i).getClassName());
9456            }
9457        } catch (IOException e) {
9458            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9459            file.delete();
9460        } finally {
9461            FileUtils.sync(fos);
9462            if (dos != null) {
9463                try {
9464                    dos.close();
9465                } catch (IOException e) {
9466                    // TODO Auto-generated catch block
9467                    e.printStackTrace();
9468                }
9469            }
9470        }
9471    }
9472
9473    public void systemReady(final Runnable goingCallback) {
9474        synchronized(this) {
9475            if (mSystemReady) {
9476                if (goingCallback != null) goingCallback.run();
9477                return;
9478            }
9479
9480            // Check to see if there are any update receivers to run.
9481            if (!mDidUpdate) {
9482                if (mWaitingUpdate) {
9483                    return;
9484                }
9485                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9486                List<ResolveInfo> ris = null;
9487                try {
9488                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9489                            intent, null, 0, 0);
9490                } catch (RemoteException e) {
9491                }
9492                if (ris != null) {
9493                    for (int i=ris.size()-1; i>=0; i--) {
9494                        if ((ris.get(i).activityInfo.applicationInfo.flags
9495                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9496                            ris.remove(i);
9497                        }
9498                    }
9499                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9500
9501                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9502
9503                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9504                    for (int i=0; i<ris.size(); i++) {
9505                        ActivityInfo ai = ris.get(i).activityInfo;
9506                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9507                        if (lastDoneReceivers.contains(comp)) {
9508                            // We already did the pre boot receiver for this app with the current
9509                            // platform version, so don't do it again...
9510                            ris.remove(i);
9511                            i--;
9512                            // ...however, do keep it as one that has been done, so we don't
9513                            // forget about it when rewriting the file of last done receivers.
9514                            doneReceivers.add(comp);
9515                        }
9516                    }
9517
9518                    final int[] users = getUsersLocked();
9519                    for (int i=0; i<ris.size(); i++) {
9520                        ActivityInfo ai = ris.get(i).activityInfo;
9521                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9522                        doneReceivers.add(comp);
9523                        intent.setComponent(comp);
9524                        for (int j=0; j<users.length; j++) {
9525                            IIntentReceiver finisher = null;
9526                            if (i == ris.size()-1 && j == users.length-1) {
9527                                finisher = new IIntentReceiver.Stub() {
9528                                    public void performReceive(Intent intent, int resultCode,
9529                                            String data, Bundle extras, boolean ordered,
9530                                            boolean sticky, int sendingUser) {
9531                                        // The raw IIntentReceiver interface is called
9532                                        // with the AM lock held, so redispatch to
9533                                        // execute our code without the lock.
9534                                        mHandler.post(new Runnable() {
9535                                            public void run() {
9536                                                synchronized (ActivityManagerService.this) {
9537                                                    mDidUpdate = true;
9538                                                }
9539                                                writeLastDonePreBootReceivers(doneReceivers);
9540                                                showBootMessage(mContext.getText(
9541                                                        R.string.android_upgrading_complete),
9542                                                        false);
9543                                                systemReady(goingCallback);
9544                                            }
9545                                        });
9546                                    }
9547                                };
9548                            }
9549                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9550                                    + " for user " + users[j]);
9551                            broadcastIntentLocked(null, null, intent, null, finisher,
9552                                    0, null, null, null, AppOpsManager.OP_NONE,
9553                                    true, false, MY_PID, Process.SYSTEM_UID,
9554                                    users[j]);
9555                            if (finisher != null) {
9556                                mWaitingUpdate = true;
9557                            }
9558                        }
9559                    }
9560                }
9561                if (mWaitingUpdate) {
9562                    return;
9563                }
9564                mDidUpdate = true;
9565            }
9566
9567            mAppOpsService.systemReady();
9568            mSystemReady = true;
9569        }
9570
9571        ArrayList<ProcessRecord> procsToKill = null;
9572        synchronized(mPidsSelfLocked) {
9573            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9574                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9575                if (!isAllowedWhileBooting(proc.info)){
9576                    if (procsToKill == null) {
9577                        procsToKill = new ArrayList<ProcessRecord>();
9578                    }
9579                    procsToKill.add(proc);
9580                }
9581            }
9582        }
9583
9584        synchronized(this) {
9585            if (procsToKill != null) {
9586                for (int i=procsToKill.size()-1; i>=0; i--) {
9587                    ProcessRecord proc = procsToKill.get(i);
9588                    Slog.i(TAG, "Removing system update proc: " + proc);
9589                    removeProcessLocked(proc, true, false, "system update done");
9590                }
9591            }
9592
9593            // Now that we have cleaned up any update processes, we
9594            // are ready to start launching real processes and know that
9595            // we won't trample on them any more.
9596            mProcessesReady = true;
9597        }
9598
9599        Slog.i(TAG, "System now ready");
9600        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9601            SystemClock.uptimeMillis());
9602
9603        synchronized(this) {
9604            // Make sure we have no pre-ready processes sitting around.
9605
9606            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9607                ResolveInfo ri = mContext.getPackageManager()
9608                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9609                                STOCK_PM_FLAGS);
9610                CharSequence errorMsg = null;
9611                if (ri != null) {
9612                    ActivityInfo ai = ri.activityInfo;
9613                    ApplicationInfo app = ai.applicationInfo;
9614                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9615                        mTopAction = Intent.ACTION_FACTORY_TEST;
9616                        mTopData = null;
9617                        mTopComponent = new ComponentName(app.packageName,
9618                                ai.name);
9619                    } else {
9620                        errorMsg = mContext.getResources().getText(
9621                                com.android.internal.R.string.factorytest_not_system);
9622                    }
9623                } else {
9624                    errorMsg = mContext.getResources().getText(
9625                            com.android.internal.R.string.factorytest_no_action);
9626                }
9627                if (errorMsg != null) {
9628                    mTopAction = null;
9629                    mTopData = null;
9630                    mTopComponent = null;
9631                    Message msg = Message.obtain();
9632                    msg.what = SHOW_FACTORY_ERROR_MSG;
9633                    msg.getData().putCharSequence("msg", errorMsg);
9634                    mHandler.sendMessage(msg);
9635                }
9636            }
9637        }
9638
9639        retrieveSettings();
9640
9641        synchronized (this) {
9642            readGrantedUriPermissionsLocked();
9643        }
9644
9645        if (goingCallback != null) goingCallback.run();
9646
9647        mSystemServiceManager.startUser(mCurrentUserId);
9648
9649        synchronized (this) {
9650            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9651                try {
9652                    List apps = AppGlobals.getPackageManager().
9653                        getPersistentApplications(STOCK_PM_FLAGS);
9654                    if (apps != null) {
9655                        int N = apps.size();
9656                        int i;
9657                        for (i=0; i<N; i++) {
9658                            ApplicationInfo info
9659                                = (ApplicationInfo)apps.get(i);
9660                            if (info != null &&
9661                                    !info.packageName.equals("android")) {
9662                                addAppLocked(info, false);
9663                            }
9664                        }
9665                    }
9666                } catch (RemoteException ex) {
9667                    // pm is in same process, this will never happen.
9668                }
9669            }
9670
9671            // Start up initial activity.
9672            mBooting = true;
9673
9674            try {
9675                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9676                    Message msg = Message.obtain();
9677                    msg.what = SHOW_UID_ERROR_MSG;
9678                    mHandler.sendMessage(msg);
9679                }
9680            } catch (RemoteException e) {
9681            }
9682
9683            long ident = Binder.clearCallingIdentity();
9684            try {
9685                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9686                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9687                        | Intent.FLAG_RECEIVER_FOREGROUND);
9688                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9689                broadcastIntentLocked(null, null, intent,
9690                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9691                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9692                intent = new Intent(Intent.ACTION_USER_STARTING);
9693                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9694                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9695                broadcastIntentLocked(null, null, intent,
9696                        null, new IIntentReceiver.Stub() {
9697                            @Override
9698                            public void performReceive(Intent intent, int resultCode, String data,
9699                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9700                                    throws RemoteException {
9701                            }
9702                        }, 0, null, null,
9703                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9704                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9705            } catch (Throwable t) {
9706                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
9707            } finally {
9708                Binder.restoreCallingIdentity(ident);
9709            }
9710            mStackSupervisor.resumeTopActivitiesLocked();
9711            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9712        }
9713    }
9714
9715    private boolean makeAppCrashingLocked(ProcessRecord app,
9716            String shortMsg, String longMsg, String stackTrace) {
9717        app.crashing = true;
9718        app.crashingReport = generateProcessError(app,
9719                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9720        startAppProblemLocked(app);
9721        app.stopFreezingAllLocked();
9722        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9723    }
9724
9725    private void makeAppNotRespondingLocked(ProcessRecord app,
9726            String activity, String shortMsg, String longMsg) {
9727        app.notResponding = true;
9728        app.notRespondingReport = generateProcessError(app,
9729                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9730                activity, shortMsg, longMsg, null);
9731        startAppProblemLocked(app);
9732        app.stopFreezingAllLocked();
9733    }
9734
9735    /**
9736     * Generate a process error record, suitable for attachment to a ProcessRecord.
9737     *
9738     * @param app The ProcessRecord in which the error occurred.
9739     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9740     *                      ActivityManager.AppErrorStateInfo
9741     * @param activity The activity associated with the crash, if known.
9742     * @param shortMsg Short message describing the crash.
9743     * @param longMsg Long message describing the crash.
9744     * @param stackTrace Full crash stack trace, may be null.
9745     *
9746     * @return Returns a fully-formed AppErrorStateInfo record.
9747     */
9748    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9749            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9750        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9751
9752        report.condition = condition;
9753        report.processName = app.processName;
9754        report.pid = app.pid;
9755        report.uid = app.info.uid;
9756        report.tag = activity;
9757        report.shortMsg = shortMsg;
9758        report.longMsg = longMsg;
9759        report.stackTrace = stackTrace;
9760
9761        return report;
9762    }
9763
9764    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9765        synchronized (this) {
9766            app.crashing = false;
9767            app.crashingReport = null;
9768            app.notResponding = false;
9769            app.notRespondingReport = null;
9770            if (app.anrDialog == fromDialog) {
9771                app.anrDialog = null;
9772            }
9773            if (app.waitDialog == fromDialog) {
9774                app.waitDialog = null;
9775            }
9776            if (app.pid > 0 && app.pid != MY_PID) {
9777                handleAppCrashLocked(app, null, null, null);
9778                killUnneededProcessLocked(app, "user request after error");
9779            }
9780        }
9781    }
9782
9783    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9784            String stackTrace) {
9785        long now = SystemClock.uptimeMillis();
9786
9787        Long crashTime;
9788        if (!app.isolated) {
9789            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9790        } else {
9791            crashTime = null;
9792        }
9793        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9794            // This process loses!
9795            Slog.w(TAG, "Process " + app.info.processName
9796                    + " has crashed too many times: killing!");
9797            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9798                    app.userId, app.info.processName, app.uid);
9799            mStackSupervisor.handleAppCrashLocked(app);
9800            if (!app.persistent) {
9801                // We don't want to start this process again until the user
9802                // explicitly does so...  but for persistent process, we really
9803                // need to keep it running.  If a persistent process is actually
9804                // repeatedly crashing, then badness for everyone.
9805                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9806                        app.info.processName);
9807                if (!app.isolated) {
9808                    // XXX We don't have a way to mark isolated processes
9809                    // as bad, since they don't have a peristent identity.
9810                    mBadProcesses.put(app.info.processName, app.uid,
9811                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9812                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9813                }
9814                app.bad = true;
9815                app.removed = true;
9816                // Don't let services in this process be restarted and potentially
9817                // annoy the user repeatedly.  Unless it is persistent, since those
9818                // processes run critical code.
9819                removeProcessLocked(app, false, false, "crash");
9820                mStackSupervisor.resumeTopActivitiesLocked();
9821                return false;
9822            }
9823            mStackSupervisor.resumeTopActivitiesLocked();
9824        } else {
9825            mStackSupervisor.finishTopRunningActivityLocked(app);
9826        }
9827
9828        // Bump up the crash count of any services currently running in the proc.
9829        for (int i=app.services.size()-1; i>=0; i--) {
9830            // Any services running in the application need to be placed
9831            // back in the pending list.
9832            ServiceRecord sr = app.services.valueAt(i);
9833            sr.crashCount++;
9834        }
9835
9836        // If the crashing process is what we consider to be the "home process" and it has been
9837        // replaced by a third-party app, clear the package preferred activities from packages
9838        // with a home activity running in the process to prevent a repeatedly crashing app
9839        // from blocking the user to manually clear the list.
9840        final ArrayList<ActivityRecord> activities = app.activities;
9841        if (app == mHomeProcess && activities.size() > 0
9842                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9843            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9844                final ActivityRecord r = activities.get(activityNdx);
9845                if (r.isHomeActivity()) {
9846                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9847                    try {
9848                        ActivityThread.getPackageManager()
9849                                .clearPackagePreferredActivities(r.packageName);
9850                    } catch (RemoteException c) {
9851                        // pm is in same process, this will never happen.
9852                    }
9853                }
9854            }
9855        }
9856
9857        if (!app.isolated) {
9858            // XXX Can't keep track of crash times for isolated processes,
9859            // because they don't have a perisistent identity.
9860            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9861        }
9862
9863        return true;
9864    }
9865
9866    void startAppProblemLocked(ProcessRecord app) {
9867        if (app.userId == mCurrentUserId) {
9868            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9869                    mContext, app.info.packageName, app.info.flags);
9870        } else {
9871            // If this app is not running under the current user, then we
9872            // can't give it a report button because that would require
9873            // launching the report UI under a different user.
9874            app.errorReportReceiver = null;
9875        }
9876        skipCurrentReceiverLocked(app);
9877    }
9878
9879    void skipCurrentReceiverLocked(ProcessRecord app) {
9880        for (BroadcastQueue queue : mBroadcastQueues) {
9881            queue.skipCurrentReceiverLocked(app);
9882        }
9883    }
9884
9885    /**
9886     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9887     * The application process will exit immediately after this call returns.
9888     * @param app object of the crashing app, null for the system server
9889     * @param crashInfo describing the exception
9890     */
9891    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9892        ProcessRecord r = findAppProcess(app, "Crash");
9893        final String processName = app == null ? "system_server"
9894                : (r == null ? "unknown" : r.processName);
9895
9896        handleApplicationCrashInner("crash", r, processName, crashInfo);
9897    }
9898
9899    /* Native crash reporting uses this inner version because it needs to be somewhat
9900     * decoupled from the AM-managed cleanup lifecycle
9901     */
9902    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
9903            ApplicationErrorReport.CrashInfo crashInfo) {
9904        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
9905                UserHandle.getUserId(Binder.getCallingUid()), processName,
9906                r == null ? -1 : r.info.flags,
9907                crashInfo.exceptionClassName,
9908                crashInfo.exceptionMessage,
9909                crashInfo.throwFileName,
9910                crashInfo.throwLineNumber);
9911
9912        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
9913
9914        crashApplication(r, crashInfo);
9915    }
9916
9917    public void handleApplicationStrictModeViolation(
9918            IBinder app,
9919            int violationMask,
9920            StrictMode.ViolationInfo info) {
9921        ProcessRecord r = findAppProcess(app, "StrictMode");
9922        if (r == null) {
9923            return;
9924        }
9925
9926        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
9927            Integer stackFingerprint = info.hashCode();
9928            boolean logIt = true;
9929            synchronized (mAlreadyLoggedViolatedStacks) {
9930                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
9931                    logIt = false;
9932                    // TODO: sub-sample into EventLog for these, with
9933                    // the info.durationMillis?  Then we'd get
9934                    // the relative pain numbers, without logging all
9935                    // the stack traces repeatedly.  We'd want to do
9936                    // likewise in the client code, which also does
9937                    // dup suppression, before the Binder call.
9938                } else {
9939                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
9940                        mAlreadyLoggedViolatedStacks.clear();
9941                    }
9942                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
9943                }
9944            }
9945            if (logIt) {
9946                logStrictModeViolationToDropBox(r, info);
9947            }
9948        }
9949
9950        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
9951            AppErrorResult result = new AppErrorResult();
9952            synchronized (this) {
9953                final long origId = Binder.clearCallingIdentity();
9954
9955                Message msg = Message.obtain();
9956                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
9957                HashMap<String, Object> data = new HashMap<String, Object>();
9958                data.put("result", result);
9959                data.put("app", r);
9960                data.put("violationMask", violationMask);
9961                data.put("info", info);
9962                msg.obj = data;
9963                mHandler.sendMessage(msg);
9964
9965                Binder.restoreCallingIdentity(origId);
9966            }
9967            int res = result.get();
9968            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
9969        }
9970    }
9971
9972    // Depending on the policy in effect, there could be a bunch of
9973    // these in quick succession so we try to batch these together to
9974    // minimize disk writes, number of dropbox entries, and maximize
9975    // compression, by having more fewer, larger records.
9976    private void logStrictModeViolationToDropBox(
9977            ProcessRecord process,
9978            StrictMode.ViolationInfo info) {
9979        if (info == null) {
9980            return;
9981        }
9982        final boolean isSystemApp = process == null ||
9983                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
9984                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
9985        final String processName = process == null ? "unknown" : process.processName;
9986        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
9987        final DropBoxManager dbox = (DropBoxManager)
9988                mContext.getSystemService(Context.DROPBOX_SERVICE);
9989
9990        // Exit early if the dropbox isn't configured to accept this report type.
9991        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9992
9993        boolean bufferWasEmpty;
9994        boolean needsFlush;
9995        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
9996        synchronized (sb) {
9997            bufferWasEmpty = sb.length() == 0;
9998            appendDropBoxProcessHeaders(process, processName, sb);
9999            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10000            sb.append("System-App: ").append(isSystemApp).append("\n");
10001            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10002            if (info.violationNumThisLoop != 0) {
10003                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10004            }
10005            if (info.numAnimationsRunning != 0) {
10006                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10007            }
10008            if (info.broadcastIntentAction != null) {
10009                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10010            }
10011            if (info.durationMillis != -1) {
10012                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10013            }
10014            if (info.numInstances != -1) {
10015                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10016            }
10017            if (info.tags != null) {
10018                for (String tag : info.tags) {
10019                    sb.append("Span-Tag: ").append(tag).append("\n");
10020                }
10021            }
10022            sb.append("\n");
10023            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10024                sb.append(info.crashInfo.stackTrace);
10025            }
10026            sb.append("\n");
10027
10028            // Only buffer up to ~64k.  Various logging bits truncate
10029            // things at 128k.
10030            needsFlush = (sb.length() > 64 * 1024);
10031        }
10032
10033        // Flush immediately if the buffer's grown too large, or this
10034        // is a non-system app.  Non-system apps are isolated with a
10035        // different tag & policy and not batched.
10036        //
10037        // Batching is useful during internal testing with
10038        // StrictMode settings turned up high.  Without batching,
10039        // thousands of separate files could be created on boot.
10040        if (!isSystemApp || needsFlush) {
10041            new Thread("Error dump: " + dropboxTag) {
10042                @Override
10043                public void run() {
10044                    String report;
10045                    synchronized (sb) {
10046                        report = sb.toString();
10047                        sb.delete(0, sb.length());
10048                        sb.trimToSize();
10049                    }
10050                    if (report.length() != 0) {
10051                        dbox.addText(dropboxTag, report);
10052                    }
10053                }
10054            }.start();
10055            return;
10056        }
10057
10058        // System app batching:
10059        if (!bufferWasEmpty) {
10060            // An existing dropbox-writing thread is outstanding, so
10061            // we don't need to start it up.  The existing thread will
10062            // catch the buffer appends we just did.
10063            return;
10064        }
10065
10066        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10067        // (After this point, we shouldn't access AMS internal data structures.)
10068        new Thread("Error dump: " + dropboxTag) {
10069            @Override
10070            public void run() {
10071                // 5 second sleep to let stacks arrive and be batched together
10072                try {
10073                    Thread.sleep(5000);  // 5 seconds
10074                } catch (InterruptedException e) {}
10075
10076                String errorReport;
10077                synchronized (mStrictModeBuffer) {
10078                    errorReport = mStrictModeBuffer.toString();
10079                    if (errorReport.length() == 0) {
10080                        return;
10081                    }
10082                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10083                    mStrictModeBuffer.trimToSize();
10084                }
10085                dbox.addText(dropboxTag, errorReport);
10086            }
10087        }.start();
10088    }
10089
10090    /**
10091     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10092     * @param app object of the crashing app, null for the system server
10093     * @param tag reported by the caller
10094     * @param crashInfo describing the context of the error
10095     * @return true if the process should exit immediately (WTF is fatal)
10096     */
10097    public boolean handleApplicationWtf(IBinder app, String tag,
10098            ApplicationErrorReport.CrashInfo crashInfo) {
10099        ProcessRecord r = findAppProcess(app, "WTF");
10100        final String processName = app == null ? "system_server"
10101                : (r == null ? "unknown" : r.processName);
10102
10103        EventLog.writeEvent(EventLogTags.AM_WTF,
10104                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10105                processName,
10106                r == null ? -1 : r.info.flags,
10107                tag, crashInfo.exceptionMessage);
10108
10109        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10110
10111        if (r != null && r.pid != Process.myPid() &&
10112                Settings.Global.getInt(mContext.getContentResolver(),
10113                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10114            crashApplication(r, crashInfo);
10115            return true;
10116        } else {
10117            return false;
10118        }
10119    }
10120
10121    /**
10122     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10123     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10124     */
10125    private ProcessRecord findAppProcess(IBinder app, String reason) {
10126        if (app == null) {
10127            return null;
10128        }
10129
10130        synchronized (this) {
10131            final int NP = mProcessNames.getMap().size();
10132            for (int ip=0; ip<NP; ip++) {
10133                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10134                final int NA = apps.size();
10135                for (int ia=0; ia<NA; ia++) {
10136                    ProcessRecord p = apps.valueAt(ia);
10137                    if (p.thread != null && p.thread.asBinder() == app) {
10138                        return p;
10139                    }
10140                }
10141            }
10142
10143            Slog.w(TAG, "Can't find mystery application for " + reason
10144                    + " from pid=" + Binder.getCallingPid()
10145                    + " uid=" + Binder.getCallingUid() + ": " + app);
10146            return null;
10147        }
10148    }
10149
10150    /**
10151     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10152     * to append various headers to the dropbox log text.
10153     */
10154    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10155            StringBuilder sb) {
10156        // Watchdog thread ends up invoking this function (with
10157        // a null ProcessRecord) to add the stack file to dropbox.
10158        // Do not acquire a lock on this (am) in such cases, as it
10159        // could cause a potential deadlock, if and when watchdog
10160        // is invoked due to unavailability of lock on am and it
10161        // would prevent watchdog from killing system_server.
10162        if (process == null) {
10163            sb.append("Process: ").append(processName).append("\n");
10164            return;
10165        }
10166        // Note: ProcessRecord 'process' is guarded by the service
10167        // instance.  (notably process.pkgList, which could otherwise change
10168        // concurrently during execution of this method)
10169        synchronized (this) {
10170            sb.append("Process: ").append(processName).append("\n");
10171            int flags = process.info.flags;
10172            IPackageManager pm = AppGlobals.getPackageManager();
10173            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10174            for (int ip=0; ip<process.pkgList.size(); ip++) {
10175                String pkg = process.pkgList.keyAt(ip);
10176                sb.append("Package: ").append(pkg);
10177                try {
10178                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10179                    if (pi != null) {
10180                        sb.append(" v").append(pi.versionCode);
10181                        if (pi.versionName != null) {
10182                            sb.append(" (").append(pi.versionName).append(")");
10183                        }
10184                    }
10185                } catch (RemoteException e) {
10186                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10187                }
10188                sb.append("\n");
10189            }
10190        }
10191    }
10192
10193    private static String processClass(ProcessRecord process) {
10194        if (process == null || process.pid == MY_PID) {
10195            return "system_server";
10196        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10197            return "system_app";
10198        } else {
10199            return "data_app";
10200        }
10201    }
10202
10203    /**
10204     * Write a description of an error (crash, WTF, ANR) to the drop box.
10205     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10206     * @param process which caused the error, null means the system server
10207     * @param activity which triggered the error, null if unknown
10208     * @param parent activity related to the error, null if unknown
10209     * @param subject line related to the error, null if absent
10210     * @param report in long form describing the error, null if absent
10211     * @param logFile to include in the report, null if none
10212     * @param crashInfo giving an application stack trace, null if absent
10213     */
10214    public void addErrorToDropBox(String eventType,
10215            ProcessRecord process, String processName, ActivityRecord activity,
10216            ActivityRecord parent, String subject,
10217            final String report, final File logFile,
10218            final ApplicationErrorReport.CrashInfo crashInfo) {
10219        // NOTE -- this must never acquire the ActivityManagerService lock,
10220        // otherwise the watchdog may be prevented from resetting the system.
10221
10222        final String dropboxTag = processClass(process) + "_" + eventType;
10223        final DropBoxManager dbox = (DropBoxManager)
10224                mContext.getSystemService(Context.DROPBOX_SERVICE);
10225
10226        // Exit early if the dropbox isn't configured to accept this report type.
10227        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10228
10229        final StringBuilder sb = new StringBuilder(1024);
10230        appendDropBoxProcessHeaders(process, processName, sb);
10231        if (activity != null) {
10232            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10233        }
10234        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10235            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10236        }
10237        if (parent != null && parent != activity) {
10238            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10239        }
10240        if (subject != null) {
10241            sb.append("Subject: ").append(subject).append("\n");
10242        }
10243        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10244        if (Debug.isDebuggerConnected()) {
10245            sb.append("Debugger: Connected\n");
10246        }
10247        sb.append("\n");
10248
10249        // Do the rest in a worker thread to avoid blocking the caller on I/O
10250        // (After this point, we shouldn't access AMS internal data structures.)
10251        Thread worker = new Thread("Error dump: " + dropboxTag) {
10252            @Override
10253            public void run() {
10254                if (report != null) {
10255                    sb.append(report);
10256                }
10257                if (logFile != null) {
10258                    try {
10259                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10260                                    "\n\n[[TRUNCATED]]"));
10261                    } catch (IOException e) {
10262                        Slog.e(TAG, "Error reading " + logFile, e);
10263                    }
10264                }
10265                if (crashInfo != null && crashInfo.stackTrace != null) {
10266                    sb.append(crashInfo.stackTrace);
10267                }
10268
10269                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10270                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10271                if (lines > 0) {
10272                    sb.append("\n");
10273
10274                    // Merge several logcat streams, and take the last N lines
10275                    InputStreamReader input = null;
10276                    try {
10277                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10278                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10279                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10280
10281                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10282                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10283                        input = new InputStreamReader(logcat.getInputStream());
10284
10285                        int num;
10286                        char[] buf = new char[8192];
10287                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10288                    } catch (IOException e) {
10289                        Slog.e(TAG, "Error running logcat", e);
10290                    } finally {
10291                        if (input != null) try { input.close(); } catch (IOException e) {}
10292                    }
10293                }
10294
10295                dbox.addText(dropboxTag, sb.toString());
10296            }
10297        };
10298
10299        if (process == null) {
10300            // If process is null, we are being called from some internal code
10301            // and may be about to die -- run this synchronously.
10302            worker.run();
10303        } else {
10304            worker.start();
10305        }
10306    }
10307
10308    /**
10309     * Bring up the "unexpected error" dialog box for a crashing app.
10310     * Deal with edge cases (intercepts from instrumented applications,
10311     * ActivityController, error intent receivers, that sort of thing).
10312     * @param r the application crashing
10313     * @param crashInfo describing the failure
10314     */
10315    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10316        long timeMillis = System.currentTimeMillis();
10317        String shortMsg = crashInfo.exceptionClassName;
10318        String longMsg = crashInfo.exceptionMessage;
10319        String stackTrace = crashInfo.stackTrace;
10320        if (shortMsg != null && longMsg != null) {
10321            longMsg = shortMsg + ": " + longMsg;
10322        } else if (shortMsg != null) {
10323            longMsg = shortMsg;
10324        }
10325
10326        AppErrorResult result = new AppErrorResult();
10327        synchronized (this) {
10328            if (mController != null) {
10329                try {
10330                    String name = r != null ? r.processName : null;
10331                    int pid = r != null ? r.pid : Binder.getCallingPid();
10332                    if (!mController.appCrashed(name, pid,
10333                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10334                        Slog.w(TAG, "Force-killing crashed app " + name
10335                                + " at watcher's request");
10336                        Process.killProcess(pid);
10337                        return;
10338                    }
10339                } catch (RemoteException e) {
10340                    mController = null;
10341                    Watchdog.getInstance().setActivityController(null);
10342                }
10343            }
10344
10345            final long origId = Binder.clearCallingIdentity();
10346
10347            // If this process is running instrumentation, finish it.
10348            if (r != null && r.instrumentationClass != null) {
10349                Slog.w(TAG, "Error in app " + r.processName
10350                      + " running instrumentation " + r.instrumentationClass + ":");
10351                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10352                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10353                Bundle info = new Bundle();
10354                info.putString("shortMsg", shortMsg);
10355                info.putString("longMsg", longMsg);
10356                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10357                Binder.restoreCallingIdentity(origId);
10358                return;
10359            }
10360
10361            // If we can't identify the process or it's already exceeded its crash quota,
10362            // quit right away without showing a crash dialog.
10363            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10364                Binder.restoreCallingIdentity(origId);
10365                return;
10366            }
10367
10368            Message msg = Message.obtain();
10369            msg.what = SHOW_ERROR_MSG;
10370            HashMap data = new HashMap();
10371            data.put("result", result);
10372            data.put("app", r);
10373            msg.obj = data;
10374            mHandler.sendMessage(msg);
10375
10376            Binder.restoreCallingIdentity(origId);
10377        }
10378
10379        int res = result.get();
10380
10381        Intent appErrorIntent = null;
10382        synchronized (this) {
10383            if (r != null && !r.isolated) {
10384                // XXX Can't keep track of crash time for isolated processes,
10385                // since they don't have a persistent identity.
10386                mProcessCrashTimes.put(r.info.processName, r.uid,
10387                        SystemClock.uptimeMillis());
10388            }
10389            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10390                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10391            }
10392        }
10393
10394        if (appErrorIntent != null) {
10395            try {
10396                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10397            } catch (ActivityNotFoundException e) {
10398                Slog.w(TAG, "bug report receiver dissappeared", e);
10399            }
10400        }
10401    }
10402
10403    Intent createAppErrorIntentLocked(ProcessRecord r,
10404            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10405        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10406        if (report == null) {
10407            return null;
10408        }
10409        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10410        result.setComponent(r.errorReportReceiver);
10411        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10412        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10413        return result;
10414    }
10415
10416    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10417            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10418        if (r.errorReportReceiver == null) {
10419            return null;
10420        }
10421
10422        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10423            return null;
10424        }
10425
10426        ApplicationErrorReport report = new ApplicationErrorReport();
10427        report.packageName = r.info.packageName;
10428        report.installerPackageName = r.errorReportReceiver.getPackageName();
10429        report.processName = r.processName;
10430        report.time = timeMillis;
10431        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10432
10433        if (r.crashing || r.forceCrashReport) {
10434            report.type = ApplicationErrorReport.TYPE_CRASH;
10435            report.crashInfo = crashInfo;
10436        } else if (r.notResponding) {
10437            report.type = ApplicationErrorReport.TYPE_ANR;
10438            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10439
10440            report.anrInfo.activity = r.notRespondingReport.tag;
10441            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10442            report.anrInfo.info = r.notRespondingReport.longMsg;
10443        }
10444
10445        return report;
10446    }
10447
10448    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10449        enforceNotIsolatedCaller("getProcessesInErrorState");
10450        // assume our apps are happy - lazy create the list
10451        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10452
10453        final boolean allUsers = ActivityManager.checkUidPermission(
10454                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10455                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10456        int userId = UserHandle.getUserId(Binder.getCallingUid());
10457
10458        synchronized (this) {
10459
10460            // iterate across all processes
10461            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10462                ProcessRecord app = mLruProcesses.get(i);
10463                if (!allUsers && app.userId != userId) {
10464                    continue;
10465                }
10466                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10467                    // This one's in trouble, so we'll generate a report for it
10468                    // crashes are higher priority (in case there's a crash *and* an anr)
10469                    ActivityManager.ProcessErrorStateInfo report = null;
10470                    if (app.crashing) {
10471                        report = app.crashingReport;
10472                    } else if (app.notResponding) {
10473                        report = app.notRespondingReport;
10474                    }
10475
10476                    if (report != null) {
10477                        if (errList == null) {
10478                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10479                        }
10480                        errList.add(report);
10481                    } else {
10482                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10483                                " crashing = " + app.crashing +
10484                                " notResponding = " + app.notResponding);
10485                    }
10486                }
10487            }
10488        }
10489
10490        return errList;
10491    }
10492
10493    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10494        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10495            if (currApp != null) {
10496                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10497            }
10498            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10499        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10500            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10501        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10502            if (currApp != null) {
10503                currApp.lru = 0;
10504            }
10505            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10506        } else if (adj >= ProcessList.SERVICE_ADJ) {
10507            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10508        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10509            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10510        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10511            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10512        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10513            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10514        } else {
10515            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10516        }
10517    }
10518
10519    private void fillInProcMemInfo(ProcessRecord app,
10520            ActivityManager.RunningAppProcessInfo outInfo) {
10521        outInfo.pid = app.pid;
10522        outInfo.uid = app.info.uid;
10523        if (mHeavyWeightProcess == app) {
10524            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10525        }
10526        if (app.persistent) {
10527            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10528        }
10529        if (app.activities.size() > 0) {
10530            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10531        }
10532        outInfo.lastTrimLevel = app.trimMemoryLevel;
10533        int adj = app.curAdj;
10534        outInfo.importance = oomAdjToImportance(adj, outInfo);
10535        outInfo.importanceReasonCode = app.adjTypeCode;
10536        outInfo.processState = app.curProcState;
10537    }
10538
10539    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10540        enforceNotIsolatedCaller("getRunningAppProcesses");
10541        // Lazy instantiation of list
10542        List<ActivityManager.RunningAppProcessInfo> runList = null;
10543        final boolean allUsers = ActivityManager.checkUidPermission(
10544                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10545                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10546        int userId = UserHandle.getUserId(Binder.getCallingUid());
10547        synchronized (this) {
10548            // Iterate across all processes
10549            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10550                ProcessRecord app = mLruProcesses.get(i);
10551                if (!allUsers && app.userId != userId) {
10552                    continue;
10553                }
10554                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10555                    // Generate process state info for running application
10556                    ActivityManager.RunningAppProcessInfo currApp =
10557                        new ActivityManager.RunningAppProcessInfo(app.processName,
10558                                app.pid, app.getPackageList());
10559                    fillInProcMemInfo(app, currApp);
10560                    if (app.adjSource instanceof ProcessRecord) {
10561                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10562                        currApp.importanceReasonImportance = oomAdjToImportance(
10563                                app.adjSourceOom, null);
10564                    } else if (app.adjSource instanceof ActivityRecord) {
10565                        ActivityRecord r = (ActivityRecord)app.adjSource;
10566                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10567                    }
10568                    if (app.adjTarget instanceof ComponentName) {
10569                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10570                    }
10571                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10572                    //        + " lru=" + currApp.lru);
10573                    if (runList == null) {
10574                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10575                    }
10576                    runList.add(currApp);
10577                }
10578            }
10579        }
10580        return runList;
10581    }
10582
10583    public List<ApplicationInfo> getRunningExternalApplications() {
10584        enforceNotIsolatedCaller("getRunningExternalApplications");
10585        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10586        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10587        if (runningApps != null && runningApps.size() > 0) {
10588            Set<String> extList = new HashSet<String>();
10589            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10590                if (app.pkgList != null) {
10591                    for (String pkg : app.pkgList) {
10592                        extList.add(pkg);
10593                    }
10594                }
10595            }
10596            IPackageManager pm = AppGlobals.getPackageManager();
10597            for (String pkg : extList) {
10598                try {
10599                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10600                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10601                        retList.add(info);
10602                    }
10603                } catch (RemoteException e) {
10604                }
10605            }
10606        }
10607        return retList;
10608    }
10609
10610    @Override
10611    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10612        enforceNotIsolatedCaller("getMyMemoryState");
10613        synchronized (this) {
10614            ProcessRecord proc;
10615            synchronized (mPidsSelfLocked) {
10616                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10617            }
10618            fillInProcMemInfo(proc, outInfo);
10619        }
10620    }
10621
10622    @Override
10623    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10624        if (checkCallingPermission(android.Manifest.permission.DUMP)
10625                != PackageManager.PERMISSION_GRANTED) {
10626            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10627                    + Binder.getCallingPid()
10628                    + ", uid=" + Binder.getCallingUid()
10629                    + " without permission "
10630                    + android.Manifest.permission.DUMP);
10631            return;
10632        }
10633
10634        boolean dumpAll = false;
10635        boolean dumpClient = false;
10636        String dumpPackage = null;
10637
10638        int opti = 0;
10639        while (opti < args.length) {
10640            String opt = args[opti];
10641            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10642                break;
10643            }
10644            opti++;
10645            if ("-a".equals(opt)) {
10646                dumpAll = true;
10647            } else if ("-c".equals(opt)) {
10648                dumpClient = true;
10649            } else if ("-h".equals(opt)) {
10650                pw.println("Activity manager dump options:");
10651                pw.println("  [-a] [-c] [-h] [cmd] ...");
10652                pw.println("  cmd may be one of:");
10653                pw.println("    a[ctivities]: activity stack state");
10654                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10655                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10656                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10657                pw.println("    o[om]: out of memory management");
10658                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10659                pw.println("    provider [COMP_SPEC]: provider client-side state");
10660                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10661                pw.println("    service [COMP_SPEC]: service client-side state");
10662                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10663                pw.println("    all: dump all activities");
10664                pw.println("    top: dump the top activity");
10665                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10666                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10667                pw.println("    a partial substring in a component name, a");
10668                pw.println("    hex object identifier.");
10669                pw.println("  -a: include all available server state.");
10670                pw.println("  -c: include client state.");
10671                return;
10672            } else {
10673                pw.println("Unknown argument: " + opt + "; use -h for help");
10674            }
10675        }
10676
10677        long origId = Binder.clearCallingIdentity();
10678        boolean more = false;
10679        // Is the caller requesting to dump a particular piece of data?
10680        if (opti < args.length) {
10681            String cmd = args[opti];
10682            opti++;
10683            if ("activities".equals(cmd) || "a".equals(cmd)) {
10684                synchronized (this) {
10685                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10686                }
10687            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10688                String[] newArgs;
10689                String name;
10690                if (opti >= args.length) {
10691                    name = null;
10692                    newArgs = EMPTY_STRING_ARRAY;
10693                } else {
10694                    name = args[opti];
10695                    opti++;
10696                    newArgs = new String[args.length - opti];
10697                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10698                            args.length - opti);
10699                }
10700                synchronized (this) {
10701                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10702                }
10703            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10704                String[] newArgs;
10705                String name;
10706                if (opti >= args.length) {
10707                    name = null;
10708                    newArgs = EMPTY_STRING_ARRAY;
10709                } else {
10710                    name = args[opti];
10711                    opti++;
10712                    newArgs = new String[args.length - opti];
10713                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10714                            args.length - opti);
10715                }
10716                synchronized (this) {
10717                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10718                }
10719            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10720                String[] newArgs;
10721                String name;
10722                if (opti >= args.length) {
10723                    name = null;
10724                    newArgs = EMPTY_STRING_ARRAY;
10725                } else {
10726                    name = args[opti];
10727                    opti++;
10728                    newArgs = new String[args.length - opti];
10729                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10730                            args.length - opti);
10731                }
10732                synchronized (this) {
10733                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10734                }
10735            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10736                synchronized (this) {
10737                    dumpOomLocked(fd, pw, args, opti, true);
10738                }
10739            } else if ("provider".equals(cmd)) {
10740                String[] newArgs;
10741                String name;
10742                if (opti >= args.length) {
10743                    name = null;
10744                    newArgs = EMPTY_STRING_ARRAY;
10745                } else {
10746                    name = args[opti];
10747                    opti++;
10748                    newArgs = new String[args.length - opti];
10749                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10750                }
10751                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10752                    pw.println("No providers match: " + name);
10753                    pw.println("Use -h for help.");
10754                }
10755            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10756                synchronized (this) {
10757                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10758                }
10759            } else if ("service".equals(cmd)) {
10760                String[] newArgs;
10761                String name;
10762                if (opti >= args.length) {
10763                    name = null;
10764                    newArgs = EMPTY_STRING_ARRAY;
10765                } else {
10766                    name = args[opti];
10767                    opti++;
10768                    newArgs = new String[args.length - opti];
10769                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10770                            args.length - opti);
10771                }
10772                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10773                    pw.println("No services match: " + name);
10774                    pw.println("Use -h for help.");
10775                }
10776            } else if ("package".equals(cmd)) {
10777                String[] newArgs;
10778                if (opti >= args.length) {
10779                    pw.println("package: no package name specified");
10780                    pw.println("Use -h for help.");
10781                } else {
10782                    dumpPackage = args[opti];
10783                    opti++;
10784                    newArgs = new String[args.length - opti];
10785                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10786                            args.length - opti);
10787                    args = newArgs;
10788                    opti = 0;
10789                    more = true;
10790                }
10791            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10792                synchronized (this) {
10793                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10794                }
10795            } else {
10796                // Dumping a single activity?
10797                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10798                    pw.println("Bad activity command, or no activities match: " + cmd);
10799                    pw.println("Use -h for help.");
10800                }
10801            }
10802            if (!more) {
10803                Binder.restoreCallingIdentity(origId);
10804                return;
10805            }
10806        }
10807
10808        // No piece of data specified, dump everything.
10809        synchronized (this) {
10810            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10811            pw.println();
10812            if (dumpAll) {
10813                pw.println("-------------------------------------------------------------------------------");
10814            }
10815            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10816            pw.println();
10817            if (dumpAll) {
10818                pw.println("-------------------------------------------------------------------------------");
10819            }
10820            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10821            pw.println();
10822            if (dumpAll) {
10823                pw.println("-------------------------------------------------------------------------------");
10824            }
10825            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10826            pw.println();
10827            if (dumpAll) {
10828                pw.println("-------------------------------------------------------------------------------");
10829            }
10830            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10831            pw.println();
10832            if (dumpAll) {
10833                pw.println("-------------------------------------------------------------------------------");
10834            }
10835            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10836        }
10837        Binder.restoreCallingIdentity(origId);
10838    }
10839
10840    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10841            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10842        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10843
10844        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10845                dumpPackage);
10846        boolean needSep = printedAnything;
10847
10848        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10849                dumpPackage, needSep, "  mFocusedActivity: ");
10850        if (printed) {
10851            printedAnything = true;
10852            needSep = false;
10853        }
10854
10855        if (dumpPackage == null) {
10856            if (needSep) {
10857                pw.println();
10858            }
10859            needSep = true;
10860            printedAnything = true;
10861            mStackSupervisor.dump(pw, "  ");
10862        }
10863
10864        if (mRecentTasks.size() > 0) {
10865            boolean printedHeader = false;
10866
10867            final int N = mRecentTasks.size();
10868            for (int i=0; i<N; i++) {
10869                TaskRecord tr = mRecentTasks.get(i);
10870                if (dumpPackage != null) {
10871                    if (tr.realActivity == null ||
10872                            !dumpPackage.equals(tr.realActivity)) {
10873                        continue;
10874                    }
10875                }
10876                if (!printedHeader) {
10877                    if (needSep) {
10878                        pw.println();
10879                    }
10880                    pw.println("  Recent tasks:");
10881                    printedHeader = true;
10882                    printedAnything = true;
10883                }
10884                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10885                        pw.println(tr);
10886                if (dumpAll) {
10887                    mRecentTasks.get(i).dump(pw, "    ");
10888                }
10889            }
10890        }
10891
10892        if (!printedAnything) {
10893            pw.println("  (nothing)");
10894        }
10895    }
10896
10897    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10898            int opti, boolean dumpAll, String dumpPackage) {
10899        boolean needSep = false;
10900        boolean printedAnything = false;
10901        int numPers = 0;
10902
10903        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
10904
10905        if (dumpAll) {
10906            final int NP = mProcessNames.getMap().size();
10907            for (int ip=0; ip<NP; ip++) {
10908                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
10909                final int NA = procs.size();
10910                for (int ia=0; ia<NA; ia++) {
10911                    ProcessRecord r = procs.valueAt(ia);
10912                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10913                        continue;
10914                    }
10915                    if (!needSep) {
10916                        pw.println("  All known processes:");
10917                        needSep = true;
10918                        printedAnything = true;
10919                    }
10920                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
10921                        pw.print(" UID "); pw.print(procs.keyAt(ia));
10922                        pw.print(" "); pw.println(r);
10923                    r.dump(pw, "    ");
10924                    if (r.persistent) {
10925                        numPers++;
10926                    }
10927                }
10928            }
10929        }
10930
10931        if (mIsolatedProcesses.size() > 0) {
10932            boolean printed = false;
10933            for (int i=0; i<mIsolatedProcesses.size(); i++) {
10934                ProcessRecord r = mIsolatedProcesses.valueAt(i);
10935                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10936                    continue;
10937                }
10938                if (!printed) {
10939                    if (needSep) {
10940                        pw.println();
10941                    }
10942                    pw.println("  Isolated process list (sorted by uid):");
10943                    printedAnything = true;
10944                    printed = true;
10945                    needSep = true;
10946                }
10947                pw.println(String.format("%sIsolated #%2d: %s",
10948                        "    ", i, r.toString()));
10949            }
10950        }
10951
10952        if (mLruProcesses.size() > 0) {
10953            if (needSep) {
10954                pw.println();
10955            }
10956            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
10957                    pw.print(" total, non-act at ");
10958                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10959                    pw.print(", non-svc at ");
10960                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10961                    pw.println("):");
10962            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
10963            needSep = true;
10964            printedAnything = true;
10965        }
10966
10967        if (dumpAll || dumpPackage != null) {
10968            synchronized (mPidsSelfLocked) {
10969                boolean printed = false;
10970                for (int i=0; i<mPidsSelfLocked.size(); i++) {
10971                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
10972                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10973                        continue;
10974                    }
10975                    if (!printed) {
10976                        if (needSep) pw.println();
10977                        needSep = true;
10978                        pw.println("  PID mappings:");
10979                        printed = true;
10980                        printedAnything = true;
10981                    }
10982                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
10983                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
10984                }
10985            }
10986        }
10987
10988        if (mForegroundProcesses.size() > 0) {
10989            synchronized (mPidsSelfLocked) {
10990                boolean printed = false;
10991                for (int i=0; i<mForegroundProcesses.size(); i++) {
10992                    ProcessRecord r = mPidsSelfLocked.get(
10993                            mForegroundProcesses.valueAt(i).pid);
10994                    if (dumpPackage != null && (r == null
10995                            || !r.pkgList.containsKey(dumpPackage))) {
10996                        continue;
10997                    }
10998                    if (!printed) {
10999                        if (needSep) pw.println();
11000                        needSep = true;
11001                        pw.println("  Foreground Processes:");
11002                        printed = true;
11003                        printedAnything = true;
11004                    }
11005                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11006                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11007                }
11008            }
11009        }
11010
11011        if (mPersistentStartingProcesses.size() > 0) {
11012            if (needSep) pw.println();
11013            needSep = true;
11014            printedAnything = true;
11015            pw.println("  Persisent processes that are starting:");
11016            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11017                    "Starting Norm", "Restarting PERS", dumpPackage);
11018        }
11019
11020        if (mRemovedProcesses.size() > 0) {
11021            if (needSep) pw.println();
11022            needSep = true;
11023            printedAnything = true;
11024            pw.println("  Processes that are being removed:");
11025            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11026                    "Removed Norm", "Removed PERS", dumpPackage);
11027        }
11028
11029        if (mProcessesOnHold.size() > 0) {
11030            if (needSep) pw.println();
11031            needSep = true;
11032            printedAnything = true;
11033            pw.println("  Processes that are on old until the system is ready:");
11034            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11035                    "OnHold Norm", "OnHold PERS", dumpPackage);
11036        }
11037
11038        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11039
11040        if (mProcessCrashTimes.getMap().size() > 0) {
11041            boolean printed = false;
11042            long now = SystemClock.uptimeMillis();
11043            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11044            final int NP = pmap.size();
11045            for (int ip=0; ip<NP; ip++) {
11046                String pname = pmap.keyAt(ip);
11047                SparseArray<Long> uids = pmap.valueAt(ip);
11048                final int N = uids.size();
11049                for (int i=0; i<N; i++) {
11050                    int puid = uids.keyAt(i);
11051                    ProcessRecord r = mProcessNames.get(pname, puid);
11052                    if (dumpPackage != null && (r == null
11053                            || !r.pkgList.containsKey(dumpPackage))) {
11054                        continue;
11055                    }
11056                    if (!printed) {
11057                        if (needSep) pw.println();
11058                        needSep = true;
11059                        pw.println("  Time since processes crashed:");
11060                        printed = true;
11061                        printedAnything = true;
11062                    }
11063                    pw.print("    Process "); pw.print(pname);
11064                            pw.print(" uid "); pw.print(puid);
11065                            pw.print(": last crashed ");
11066                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11067                            pw.println(" ago");
11068                }
11069            }
11070        }
11071
11072        if (mBadProcesses.getMap().size() > 0) {
11073            boolean printed = false;
11074            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11075            final int NP = pmap.size();
11076            for (int ip=0; ip<NP; ip++) {
11077                String pname = pmap.keyAt(ip);
11078                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11079                final int N = uids.size();
11080                for (int i=0; i<N; i++) {
11081                    int puid = uids.keyAt(i);
11082                    ProcessRecord r = mProcessNames.get(pname, puid);
11083                    if (dumpPackage != null && (r == null
11084                            || !r.pkgList.containsKey(dumpPackage))) {
11085                        continue;
11086                    }
11087                    if (!printed) {
11088                        if (needSep) pw.println();
11089                        needSep = true;
11090                        pw.println("  Bad processes:");
11091                        printedAnything = true;
11092                    }
11093                    BadProcessInfo info = uids.valueAt(i);
11094                    pw.print("    Bad process "); pw.print(pname);
11095                            pw.print(" uid "); pw.print(puid);
11096                            pw.print(": crashed at time "); pw.println(info.time);
11097                    if (info.shortMsg != null) {
11098                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11099                    }
11100                    if (info.longMsg != null) {
11101                        pw.print("      Long msg: "); pw.println(info.longMsg);
11102                    }
11103                    if (info.stack != null) {
11104                        pw.println("      Stack:");
11105                        int lastPos = 0;
11106                        for (int pos=0; pos<info.stack.length(); pos++) {
11107                            if (info.stack.charAt(pos) == '\n') {
11108                                pw.print("        ");
11109                                pw.write(info.stack, lastPos, pos-lastPos);
11110                                pw.println();
11111                                lastPos = pos+1;
11112                            }
11113                        }
11114                        if (lastPos < info.stack.length()) {
11115                            pw.print("        ");
11116                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11117                            pw.println();
11118                        }
11119                    }
11120                }
11121            }
11122        }
11123
11124        if (dumpPackage == null) {
11125            pw.println();
11126            needSep = false;
11127            pw.println("  mStartedUsers:");
11128            for (int i=0; i<mStartedUsers.size(); i++) {
11129                UserStartedState uss = mStartedUsers.valueAt(i);
11130                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11131                        pw.print(": "); uss.dump("", pw);
11132            }
11133            pw.print("  mStartedUserArray: [");
11134            for (int i=0; i<mStartedUserArray.length; i++) {
11135                if (i > 0) pw.print(", ");
11136                pw.print(mStartedUserArray[i]);
11137            }
11138            pw.println("]");
11139            pw.print("  mUserLru: [");
11140            for (int i=0; i<mUserLru.size(); i++) {
11141                if (i > 0) pw.print(", ");
11142                pw.print(mUserLru.get(i));
11143            }
11144            pw.println("]");
11145            if (dumpAll) {
11146                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11147            }
11148        }
11149        if (mHomeProcess != null && (dumpPackage == null
11150                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11151            if (needSep) {
11152                pw.println();
11153                needSep = false;
11154            }
11155            pw.println("  mHomeProcess: " + mHomeProcess);
11156        }
11157        if (mPreviousProcess != null && (dumpPackage == null
11158                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11159            if (needSep) {
11160                pw.println();
11161                needSep = false;
11162            }
11163            pw.println("  mPreviousProcess: " + mPreviousProcess);
11164        }
11165        if (dumpAll) {
11166            StringBuilder sb = new StringBuilder(128);
11167            sb.append("  mPreviousProcessVisibleTime: ");
11168            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11169            pw.println(sb);
11170        }
11171        if (mHeavyWeightProcess != null && (dumpPackage == null
11172                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11173            if (needSep) {
11174                pw.println();
11175                needSep = false;
11176            }
11177            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11178        }
11179        if (dumpPackage == null) {
11180            pw.println("  mConfiguration: " + mConfiguration);
11181        }
11182        if (dumpAll) {
11183            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11184            if (mCompatModePackages.getPackages().size() > 0) {
11185                boolean printed = false;
11186                for (Map.Entry<String, Integer> entry
11187                        : mCompatModePackages.getPackages().entrySet()) {
11188                    String pkg = entry.getKey();
11189                    int mode = entry.getValue();
11190                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11191                        continue;
11192                    }
11193                    if (!printed) {
11194                        pw.println("  mScreenCompatPackages:");
11195                        printed = true;
11196                    }
11197                    pw.print("    "); pw.print(pkg); pw.print(": ");
11198                            pw.print(mode); pw.println();
11199                }
11200            }
11201        }
11202        if (dumpPackage == null) {
11203            if (mSleeping || mWentToSleep || mLockScreenShown) {
11204                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11205                        + " mLockScreenShown " + mLockScreenShown);
11206            }
11207            if (mShuttingDown || mRunningVoice) {
11208                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11209            }
11210        }
11211        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11212                || mOrigWaitForDebugger) {
11213            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11214                    || dumpPackage.equals(mOrigDebugApp)) {
11215                if (needSep) {
11216                    pw.println();
11217                    needSep = false;
11218                }
11219                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11220                        + " mDebugTransient=" + mDebugTransient
11221                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11222            }
11223        }
11224        if (mOpenGlTraceApp != null) {
11225            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11226                if (needSep) {
11227                    pw.println();
11228                    needSep = false;
11229                }
11230                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11231            }
11232        }
11233        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11234                || mProfileFd != null) {
11235            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11236                if (needSep) {
11237                    pw.println();
11238                    needSep = false;
11239                }
11240                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11241                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11242                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11243                        + mAutoStopProfiler);
11244            }
11245        }
11246        if (dumpPackage == null) {
11247            if (mAlwaysFinishActivities || mController != null) {
11248                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11249                        + " mController=" + mController);
11250            }
11251            if (dumpAll) {
11252                pw.println("  Total persistent processes: " + numPers);
11253                pw.println("  mProcessesReady=" + mProcessesReady
11254                        + " mSystemReady=" + mSystemReady);
11255                pw.println("  mBooting=" + mBooting
11256                        + " mBooted=" + mBooted
11257                        + " mFactoryTest=" + mFactoryTest);
11258                pw.print("  mLastPowerCheckRealtime=");
11259                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11260                        pw.println("");
11261                pw.print("  mLastPowerCheckUptime=");
11262                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11263                        pw.println("");
11264                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11265                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11266                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11267                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11268                        + " (" + mLruProcesses.size() + " total)"
11269                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11270                        + " mNumServiceProcs=" + mNumServiceProcs
11271                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11272                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11273                        + " mLastMemoryLevel" + mLastMemoryLevel
11274                        + " mLastNumProcesses" + mLastNumProcesses);
11275                long now = SystemClock.uptimeMillis();
11276                pw.print("  mLastIdleTime=");
11277                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11278                        pw.print(" mLowRamSinceLastIdle=");
11279                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11280                        pw.println();
11281            }
11282        }
11283
11284        if (!printedAnything) {
11285            pw.println("  (nothing)");
11286        }
11287    }
11288
11289    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11290            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11291        if (mProcessesToGc.size() > 0) {
11292            boolean printed = false;
11293            long now = SystemClock.uptimeMillis();
11294            for (int i=0; i<mProcessesToGc.size(); i++) {
11295                ProcessRecord proc = mProcessesToGc.get(i);
11296                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11297                    continue;
11298                }
11299                if (!printed) {
11300                    if (needSep) pw.println();
11301                    needSep = true;
11302                    pw.println("  Processes that are waiting to GC:");
11303                    printed = true;
11304                }
11305                pw.print("    Process "); pw.println(proc);
11306                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11307                        pw.print(", last gced=");
11308                        pw.print(now-proc.lastRequestedGc);
11309                        pw.print(" ms ago, last lowMem=");
11310                        pw.print(now-proc.lastLowMemory);
11311                        pw.println(" ms ago");
11312
11313            }
11314        }
11315        return needSep;
11316    }
11317
11318    void printOomLevel(PrintWriter pw, String name, int adj) {
11319        pw.print("    ");
11320        if (adj >= 0) {
11321            pw.print(' ');
11322            if (adj < 10) pw.print(' ');
11323        } else {
11324            if (adj > -10) pw.print(' ');
11325        }
11326        pw.print(adj);
11327        pw.print(": ");
11328        pw.print(name);
11329        pw.print(" (");
11330        pw.print(mProcessList.getMemLevel(adj)/1024);
11331        pw.println(" kB)");
11332    }
11333
11334    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11335            int opti, boolean dumpAll) {
11336        boolean needSep = false;
11337
11338        if (mLruProcesses.size() > 0) {
11339            if (needSep) pw.println();
11340            needSep = true;
11341            pw.println("  OOM levels:");
11342            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11343            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11344            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11345            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11346            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11347            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11348            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11349            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11350            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11351            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11352            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11353            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11354            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11355
11356            if (needSep) pw.println();
11357            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11358                    pw.print(" total, non-act at ");
11359                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11360                    pw.print(", non-svc at ");
11361                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11362                    pw.println("):");
11363            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11364            needSep = true;
11365        }
11366
11367        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11368
11369        pw.println();
11370        pw.println("  mHomeProcess: " + mHomeProcess);
11371        pw.println("  mPreviousProcess: " + mPreviousProcess);
11372        if (mHeavyWeightProcess != null) {
11373            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11374        }
11375
11376        return true;
11377    }
11378
11379    /**
11380     * There are three ways to call this:
11381     *  - no provider specified: dump all the providers
11382     *  - a flattened component name that matched an existing provider was specified as the
11383     *    first arg: dump that one provider
11384     *  - the first arg isn't the flattened component name of an existing provider:
11385     *    dump all providers whose component contains the first arg as a substring
11386     */
11387    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11388            int opti, boolean dumpAll) {
11389        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11390    }
11391
11392    static class ItemMatcher {
11393        ArrayList<ComponentName> components;
11394        ArrayList<String> strings;
11395        ArrayList<Integer> objects;
11396        boolean all;
11397
11398        ItemMatcher() {
11399            all = true;
11400        }
11401
11402        void build(String name) {
11403            ComponentName componentName = ComponentName.unflattenFromString(name);
11404            if (componentName != null) {
11405                if (components == null) {
11406                    components = new ArrayList<ComponentName>();
11407                }
11408                components.add(componentName);
11409                all = false;
11410            } else {
11411                int objectId = 0;
11412                // Not a '/' separated full component name; maybe an object ID?
11413                try {
11414                    objectId = Integer.parseInt(name, 16);
11415                    if (objects == null) {
11416                        objects = new ArrayList<Integer>();
11417                    }
11418                    objects.add(objectId);
11419                    all = false;
11420                } catch (RuntimeException e) {
11421                    // Not an integer; just do string match.
11422                    if (strings == null) {
11423                        strings = new ArrayList<String>();
11424                    }
11425                    strings.add(name);
11426                    all = false;
11427                }
11428            }
11429        }
11430
11431        int build(String[] args, int opti) {
11432            for (; opti<args.length; opti++) {
11433                String name = args[opti];
11434                if ("--".equals(name)) {
11435                    return opti+1;
11436                }
11437                build(name);
11438            }
11439            return opti;
11440        }
11441
11442        boolean match(Object object, ComponentName comp) {
11443            if (all) {
11444                return true;
11445            }
11446            if (components != null) {
11447                for (int i=0; i<components.size(); i++) {
11448                    if (components.get(i).equals(comp)) {
11449                        return true;
11450                    }
11451                }
11452            }
11453            if (objects != null) {
11454                for (int i=0; i<objects.size(); i++) {
11455                    if (System.identityHashCode(object) == objects.get(i)) {
11456                        return true;
11457                    }
11458                }
11459            }
11460            if (strings != null) {
11461                String flat = comp.flattenToString();
11462                for (int i=0; i<strings.size(); i++) {
11463                    if (flat.contains(strings.get(i))) {
11464                        return true;
11465                    }
11466                }
11467            }
11468            return false;
11469        }
11470    }
11471
11472    /**
11473     * There are three things that cmd can be:
11474     *  - a flattened component name that matches an existing activity
11475     *  - the cmd arg isn't the flattened component name of an existing activity:
11476     *    dump all activity whose component contains the cmd as a substring
11477     *  - A hex number of the ActivityRecord object instance.
11478     */
11479    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11480            int opti, boolean dumpAll) {
11481        ArrayList<ActivityRecord> activities;
11482
11483        synchronized (this) {
11484            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11485        }
11486
11487        if (activities.size() <= 0) {
11488            return false;
11489        }
11490
11491        String[] newArgs = new String[args.length - opti];
11492        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11493
11494        TaskRecord lastTask = null;
11495        boolean needSep = false;
11496        for (int i=activities.size()-1; i>=0; i--) {
11497            ActivityRecord r = activities.get(i);
11498            if (needSep) {
11499                pw.println();
11500            }
11501            needSep = true;
11502            synchronized (this) {
11503                if (lastTask != r.task) {
11504                    lastTask = r.task;
11505                    pw.print("TASK "); pw.print(lastTask.affinity);
11506                            pw.print(" id="); pw.println(lastTask.taskId);
11507                    if (dumpAll) {
11508                        lastTask.dump(pw, "  ");
11509                    }
11510                }
11511            }
11512            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11513        }
11514        return true;
11515    }
11516
11517    /**
11518     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11519     * there is a thread associated with the activity.
11520     */
11521    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11522            final ActivityRecord r, String[] args, boolean dumpAll) {
11523        String innerPrefix = prefix + "  ";
11524        synchronized (this) {
11525            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11526                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11527                    pw.print(" pid=");
11528                    if (r.app != null) pw.println(r.app.pid);
11529                    else pw.println("(not running)");
11530            if (dumpAll) {
11531                r.dump(pw, innerPrefix);
11532            }
11533        }
11534        if (r.app != null && r.app.thread != null) {
11535            // flush anything that is already in the PrintWriter since the thread is going
11536            // to write to the file descriptor directly
11537            pw.flush();
11538            try {
11539                TransferPipe tp = new TransferPipe();
11540                try {
11541                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11542                            r.appToken, innerPrefix, args);
11543                    tp.go(fd);
11544                } finally {
11545                    tp.kill();
11546                }
11547            } catch (IOException e) {
11548                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11549            } catch (RemoteException e) {
11550                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11551            }
11552        }
11553    }
11554
11555    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11556            int opti, boolean dumpAll, String dumpPackage) {
11557        boolean needSep = false;
11558        boolean onlyHistory = false;
11559        boolean printedAnything = false;
11560
11561        if ("history".equals(dumpPackage)) {
11562            if (opti < args.length && "-s".equals(args[opti])) {
11563                dumpAll = false;
11564            }
11565            onlyHistory = true;
11566            dumpPackage = null;
11567        }
11568
11569        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11570        if (!onlyHistory && dumpAll) {
11571            if (mRegisteredReceivers.size() > 0) {
11572                boolean printed = false;
11573                Iterator it = mRegisteredReceivers.values().iterator();
11574                while (it.hasNext()) {
11575                    ReceiverList r = (ReceiverList)it.next();
11576                    if (dumpPackage != null && (r.app == null ||
11577                            !dumpPackage.equals(r.app.info.packageName))) {
11578                        continue;
11579                    }
11580                    if (!printed) {
11581                        pw.println("  Registered Receivers:");
11582                        needSep = true;
11583                        printed = true;
11584                        printedAnything = true;
11585                    }
11586                    pw.print("  * "); pw.println(r);
11587                    r.dump(pw, "    ");
11588                }
11589            }
11590
11591            if (mReceiverResolver.dump(pw, needSep ?
11592                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11593                    "    ", dumpPackage, false)) {
11594                needSep = true;
11595                printedAnything = true;
11596            }
11597        }
11598
11599        for (BroadcastQueue q : mBroadcastQueues) {
11600            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11601            printedAnything |= needSep;
11602        }
11603
11604        needSep = true;
11605
11606        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11607            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11608                if (needSep) {
11609                    pw.println();
11610                }
11611                needSep = true;
11612                printedAnything = true;
11613                pw.print("  Sticky broadcasts for user ");
11614                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11615                StringBuilder sb = new StringBuilder(128);
11616                for (Map.Entry<String, ArrayList<Intent>> ent
11617                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11618                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11619                    if (dumpAll) {
11620                        pw.println(":");
11621                        ArrayList<Intent> intents = ent.getValue();
11622                        final int N = intents.size();
11623                        for (int i=0; i<N; i++) {
11624                            sb.setLength(0);
11625                            sb.append("    Intent: ");
11626                            intents.get(i).toShortString(sb, false, true, false, false);
11627                            pw.println(sb.toString());
11628                            Bundle bundle = intents.get(i).getExtras();
11629                            if (bundle != null) {
11630                                pw.print("      ");
11631                                pw.println(bundle.toString());
11632                            }
11633                        }
11634                    } else {
11635                        pw.println("");
11636                    }
11637                }
11638            }
11639        }
11640
11641        if (!onlyHistory && dumpAll) {
11642            pw.println();
11643            for (BroadcastQueue queue : mBroadcastQueues) {
11644                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11645                        + queue.mBroadcastsScheduled);
11646            }
11647            pw.println("  mHandler:");
11648            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11649            needSep = true;
11650            printedAnything = true;
11651        }
11652
11653        if (!printedAnything) {
11654            pw.println("  (nothing)");
11655        }
11656    }
11657
11658    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11659            int opti, boolean dumpAll, String dumpPackage) {
11660        boolean needSep;
11661        boolean printedAnything = false;
11662
11663        ItemMatcher matcher = new ItemMatcher();
11664        matcher.build(args, opti);
11665
11666        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11667
11668        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11669        printedAnything |= needSep;
11670
11671        if (mLaunchingProviders.size() > 0) {
11672            boolean printed = false;
11673            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11674                ContentProviderRecord r = mLaunchingProviders.get(i);
11675                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11676                    continue;
11677                }
11678                if (!printed) {
11679                    if (needSep) pw.println();
11680                    needSep = true;
11681                    pw.println("  Launching content providers:");
11682                    printed = true;
11683                    printedAnything = true;
11684                }
11685                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11686                        pw.println(r);
11687            }
11688        }
11689
11690        if (mGrantedUriPermissions.size() > 0) {
11691            boolean printed = false;
11692            int dumpUid = -2;
11693            if (dumpPackage != null) {
11694                try {
11695                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11696                } catch (NameNotFoundException e) {
11697                    dumpUid = -1;
11698                }
11699            }
11700            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11701                int uid = mGrantedUriPermissions.keyAt(i);
11702                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11703                    continue;
11704                }
11705                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
11706                if (!printed) {
11707                    if (needSep) pw.println();
11708                    needSep = true;
11709                    pw.println("  Granted Uri Permissions:");
11710                    printed = true;
11711                    printedAnything = true;
11712                }
11713                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
11714                for (UriPermission perm : perms.values()) {
11715                    pw.print("    "); pw.println(perm);
11716                    if (dumpAll) {
11717                        perm.dump(pw, "      ");
11718                    }
11719                }
11720            }
11721        }
11722
11723        if (!printedAnything) {
11724            pw.println("  (nothing)");
11725        }
11726    }
11727
11728    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11729            int opti, boolean dumpAll, String dumpPackage) {
11730        boolean printed = false;
11731
11732        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11733
11734        if (mIntentSenderRecords.size() > 0) {
11735            Iterator<WeakReference<PendingIntentRecord>> it
11736                    = mIntentSenderRecords.values().iterator();
11737            while (it.hasNext()) {
11738                WeakReference<PendingIntentRecord> ref = it.next();
11739                PendingIntentRecord rec = ref != null ? ref.get(): null;
11740                if (dumpPackage != null && (rec == null
11741                        || !dumpPackage.equals(rec.key.packageName))) {
11742                    continue;
11743                }
11744                printed = true;
11745                if (rec != null) {
11746                    pw.print("  * "); pw.println(rec);
11747                    if (dumpAll) {
11748                        rec.dump(pw, "    ");
11749                    }
11750                } else {
11751                    pw.print("  * "); pw.println(ref);
11752                }
11753            }
11754        }
11755
11756        if (!printed) {
11757            pw.println("  (nothing)");
11758        }
11759    }
11760
11761    private static final int dumpProcessList(PrintWriter pw,
11762            ActivityManagerService service, List list,
11763            String prefix, String normalLabel, String persistentLabel,
11764            String dumpPackage) {
11765        int numPers = 0;
11766        final int N = list.size()-1;
11767        for (int i=N; i>=0; i--) {
11768            ProcessRecord r = (ProcessRecord)list.get(i);
11769            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11770                continue;
11771            }
11772            pw.println(String.format("%s%s #%2d: %s",
11773                    prefix, (r.persistent ? persistentLabel : normalLabel),
11774                    i, r.toString()));
11775            if (r.persistent) {
11776                numPers++;
11777            }
11778        }
11779        return numPers;
11780    }
11781
11782    private static final boolean dumpProcessOomList(PrintWriter pw,
11783            ActivityManagerService service, List<ProcessRecord> origList,
11784            String prefix, String normalLabel, String persistentLabel,
11785            boolean inclDetails, String dumpPackage) {
11786
11787        ArrayList<Pair<ProcessRecord, Integer>> list
11788                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11789        for (int i=0; i<origList.size(); i++) {
11790            ProcessRecord r = origList.get(i);
11791            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11792                continue;
11793            }
11794            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11795        }
11796
11797        if (list.size() <= 0) {
11798            return false;
11799        }
11800
11801        Comparator<Pair<ProcessRecord, Integer>> comparator
11802                = new Comparator<Pair<ProcessRecord, Integer>>() {
11803            @Override
11804            public int compare(Pair<ProcessRecord, Integer> object1,
11805                    Pair<ProcessRecord, Integer> object2) {
11806                if (object1.first.setAdj != object2.first.setAdj) {
11807                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11808                }
11809                if (object1.second.intValue() != object2.second.intValue()) {
11810                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11811                }
11812                return 0;
11813            }
11814        };
11815
11816        Collections.sort(list, comparator);
11817
11818        final long curRealtime = SystemClock.elapsedRealtime();
11819        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11820        final long curUptime = SystemClock.uptimeMillis();
11821        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11822
11823        for (int i=list.size()-1; i>=0; i--) {
11824            ProcessRecord r = list.get(i).first;
11825            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11826            char schedGroup;
11827            switch (r.setSchedGroup) {
11828                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11829                    schedGroup = 'B';
11830                    break;
11831                case Process.THREAD_GROUP_DEFAULT:
11832                    schedGroup = 'F';
11833                    break;
11834                default:
11835                    schedGroup = '?';
11836                    break;
11837            }
11838            char foreground;
11839            if (r.foregroundActivities) {
11840                foreground = 'A';
11841            } else if (r.foregroundServices) {
11842                foreground = 'S';
11843            } else {
11844                foreground = ' ';
11845            }
11846            String procState = ProcessList.makeProcStateString(r.curProcState);
11847            pw.print(prefix);
11848            pw.print(r.persistent ? persistentLabel : normalLabel);
11849            pw.print(" #");
11850            int num = (origList.size()-1)-list.get(i).second;
11851            if (num < 10) pw.print(' ');
11852            pw.print(num);
11853            pw.print(": ");
11854            pw.print(oomAdj);
11855            pw.print(' ');
11856            pw.print(schedGroup);
11857            pw.print('/');
11858            pw.print(foreground);
11859            pw.print('/');
11860            pw.print(procState);
11861            pw.print(" trm:");
11862            if (r.trimMemoryLevel < 10) pw.print(' ');
11863            pw.print(r.trimMemoryLevel);
11864            pw.print(' ');
11865            pw.print(r.toShortString());
11866            pw.print(" (");
11867            pw.print(r.adjType);
11868            pw.println(')');
11869            if (r.adjSource != null || r.adjTarget != null) {
11870                pw.print(prefix);
11871                pw.print("    ");
11872                if (r.adjTarget instanceof ComponentName) {
11873                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11874                } else if (r.adjTarget != null) {
11875                    pw.print(r.adjTarget.toString());
11876                } else {
11877                    pw.print("{null}");
11878                }
11879                pw.print("<=");
11880                if (r.adjSource instanceof ProcessRecord) {
11881                    pw.print("Proc{");
11882                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11883                    pw.println("}");
11884                } else if (r.adjSource != null) {
11885                    pw.println(r.adjSource.toString());
11886                } else {
11887                    pw.println("{null}");
11888                }
11889            }
11890            if (inclDetails) {
11891                pw.print(prefix);
11892                pw.print("    ");
11893                pw.print("oom: max="); pw.print(r.maxAdj);
11894                pw.print(" curRaw="); pw.print(r.curRawAdj);
11895                pw.print(" setRaw="); pw.print(r.setRawAdj);
11896                pw.print(" cur="); pw.print(r.curAdj);
11897                pw.print(" set="); pw.println(r.setAdj);
11898                pw.print(prefix);
11899                pw.print("    ");
11900                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
11901                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
11902                pw.print(" lastPss="); pw.print(r.lastPss);
11903                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
11904                pw.print(prefix);
11905                pw.print("    ");
11906                pw.print("keeping="); pw.print(r.keeping);
11907                pw.print(" cached="); pw.print(r.cached);
11908                pw.print(" empty="); pw.print(r.empty);
11909                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
11910
11911                if (!r.keeping) {
11912                    if (r.lastWakeTime != 0) {
11913                        long wtime;
11914                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
11915                        synchronized (stats) {
11916                            wtime = stats.getProcessWakeTime(r.info.uid,
11917                                    r.pid, curRealtime);
11918                        }
11919                        long timeUsed = wtime - r.lastWakeTime;
11920                        pw.print(prefix);
11921                        pw.print("    ");
11922                        pw.print("keep awake over ");
11923                        TimeUtils.formatDuration(realtimeSince, pw);
11924                        pw.print(" used ");
11925                        TimeUtils.formatDuration(timeUsed, pw);
11926                        pw.print(" (");
11927                        pw.print((timeUsed*100)/realtimeSince);
11928                        pw.println("%)");
11929                    }
11930                    if (r.lastCpuTime != 0) {
11931                        long timeUsed = r.curCpuTime - r.lastCpuTime;
11932                        pw.print(prefix);
11933                        pw.print("    ");
11934                        pw.print("run cpu over ");
11935                        TimeUtils.formatDuration(uptimeSince, pw);
11936                        pw.print(" used ");
11937                        TimeUtils.formatDuration(timeUsed, pw);
11938                        pw.print(" (");
11939                        pw.print((timeUsed*100)/uptimeSince);
11940                        pw.println("%)");
11941                    }
11942                }
11943            }
11944        }
11945        return true;
11946    }
11947
11948    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
11949        ArrayList<ProcessRecord> procs;
11950        synchronized (this) {
11951            if (args != null && args.length > start
11952                    && args[start].charAt(0) != '-') {
11953                procs = new ArrayList<ProcessRecord>();
11954                int pid = -1;
11955                try {
11956                    pid = Integer.parseInt(args[start]);
11957                } catch (NumberFormatException e) {
11958                }
11959                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11960                    ProcessRecord proc = mLruProcesses.get(i);
11961                    if (proc.pid == pid) {
11962                        procs.add(proc);
11963                    } else if (proc.processName.equals(args[start])) {
11964                        procs.add(proc);
11965                    }
11966                }
11967                if (procs.size() <= 0) {
11968                    return null;
11969                }
11970            } else {
11971                procs = new ArrayList<ProcessRecord>(mLruProcesses);
11972            }
11973        }
11974        return procs;
11975    }
11976
11977    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
11978            PrintWriter pw, String[] args) {
11979        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11980        if (procs == null) {
11981            pw.println("No process found for: " + args[0]);
11982            return;
11983        }
11984
11985        long uptime = SystemClock.uptimeMillis();
11986        long realtime = SystemClock.elapsedRealtime();
11987        pw.println("Applications Graphics Acceleration Info:");
11988        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11989
11990        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11991            ProcessRecord r = procs.get(i);
11992            if (r.thread != null) {
11993                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
11994                pw.flush();
11995                try {
11996                    TransferPipe tp = new TransferPipe();
11997                    try {
11998                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
11999                        tp.go(fd);
12000                    } finally {
12001                        tp.kill();
12002                    }
12003                } catch (IOException e) {
12004                    pw.println("Failure while dumping the app: " + r);
12005                    pw.flush();
12006                } catch (RemoteException e) {
12007                    pw.println("Got a RemoteException while dumping the app " + r);
12008                    pw.flush();
12009                }
12010            }
12011        }
12012    }
12013
12014    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12015        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12016        if (procs == null) {
12017            pw.println("No process found for: " + args[0]);
12018            return;
12019        }
12020
12021        pw.println("Applications Database Info:");
12022
12023        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12024            ProcessRecord r = procs.get(i);
12025            if (r.thread != null) {
12026                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12027                pw.flush();
12028                try {
12029                    TransferPipe tp = new TransferPipe();
12030                    try {
12031                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12032                        tp.go(fd);
12033                    } finally {
12034                        tp.kill();
12035                    }
12036                } catch (IOException e) {
12037                    pw.println("Failure while dumping the app: " + r);
12038                    pw.flush();
12039                } catch (RemoteException e) {
12040                    pw.println("Got a RemoteException while dumping the app " + r);
12041                    pw.flush();
12042                }
12043            }
12044        }
12045    }
12046
12047    final static class MemItem {
12048        final boolean isProc;
12049        final String label;
12050        final String shortLabel;
12051        final long pss;
12052        final int id;
12053        final boolean hasActivities;
12054        ArrayList<MemItem> subitems;
12055
12056        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12057                boolean _hasActivities) {
12058            isProc = true;
12059            label = _label;
12060            shortLabel = _shortLabel;
12061            pss = _pss;
12062            id = _id;
12063            hasActivities = _hasActivities;
12064        }
12065
12066        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12067            isProc = false;
12068            label = _label;
12069            shortLabel = _shortLabel;
12070            pss = _pss;
12071            id = _id;
12072            hasActivities = false;
12073        }
12074    }
12075
12076    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12077            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12078        if (sort && !isCompact) {
12079            Collections.sort(items, new Comparator<MemItem>() {
12080                @Override
12081                public int compare(MemItem lhs, MemItem rhs) {
12082                    if (lhs.pss < rhs.pss) {
12083                        return 1;
12084                    } else if (lhs.pss > rhs.pss) {
12085                        return -1;
12086                    }
12087                    return 0;
12088                }
12089            });
12090        }
12091
12092        for (int i=0; i<items.size(); i++) {
12093            MemItem mi = items.get(i);
12094            if (!isCompact) {
12095                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12096            } else if (mi.isProc) {
12097                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12098                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12099                pw.println(mi.hasActivities ? ",a" : ",e");
12100            } else {
12101                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12102                pw.println(mi.pss);
12103            }
12104            if (mi.subitems != null) {
12105                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12106                        true, isCompact);
12107            }
12108        }
12109    }
12110
12111    // These are in KB.
12112    static final long[] DUMP_MEM_BUCKETS = new long[] {
12113        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12114        120*1024, 160*1024, 200*1024,
12115        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12116        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12117    };
12118
12119    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12120            boolean stackLike) {
12121        int start = label.lastIndexOf('.');
12122        if (start >= 0) start++;
12123        else start = 0;
12124        int end = label.length();
12125        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12126            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12127                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12128                out.append(bucket);
12129                out.append(stackLike ? "MB." : "MB ");
12130                out.append(label, start, end);
12131                return;
12132            }
12133        }
12134        out.append(memKB/1024);
12135        out.append(stackLike ? "MB." : "MB ");
12136        out.append(label, start, end);
12137    }
12138
12139    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12140            ProcessList.NATIVE_ADJ,
12141            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12142            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12143            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12144            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12145            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12146    };
12147    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12148            "Native",
12149            "System", "Persistent", "Foreground",
12150            "Visible", "Perceptible",
12151            "Heavy Weight", "Backup",
12152            "A Services", "Home",
12153            "Previous", "B Services", "Cached"
12154    };
12155    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12156            "native",
12157            "sys", "pers", "fore",
12158            "vis", "percept",
12159            "heavy", "backup",
12160            "servicea", "home",
12161            "prev", "serviceb", "cached"
12162    };
12163
12164    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12165            long realtime, boolean isCheckinRequest, boolean isCompact) {
12166        if (isCheckinRequest || isCompact) {
12167            // short checkin version
12168            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12169        } else {
12170            pw.println("Applications Memory Usage (kB):");
12171            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12172        }
12173    }
12174
12175    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12176            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12177        boolean dumpDetails = false;
12178        boolean dumpFullDetails = false;
12179        boolean dumpDalvik = false;
12180        boolean oomOnly = false;
12181        boolean isCompact = false;
12182        boolean localOnly = false;
12183
12184        int opti = 0;
12185        while (opti < args.length) {
12186            String opt = args[opti];
12187            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12188                break;
12189            }
12190            opti++;
12191            if ("-a".equals(opt)) {
12192                dumpDetails = true;
12193                dumpFullDetails = true;
12194                dumpDalvik = true;
12195            } else if ("-d".equals(opt)) {
12196                dumpDalvik = true;
12197            } else if ("-c".equals(opt)) {
12198                isCompact = true;
12199            } else if ("--oom".equals(opt)) {
12200                oomOnly = true;
12201            } else if ("--local".equals(opt)) {
12202                localOnly = true;
12203            } else if ("-h".equals(opt)) {
12204                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12205                pw.println("  -a: include all available information for each process.");
12206                pw.println("  -d: include dalvik details when dumping process details.");
12207                pw.println("  -c: dump in a compact machine-parseable representation.");
12208                pw.println("  --oom: only show processes organized by oom adj.");
12209                pw.println("  --local: only collect details locally, don't call process.");
12210                pw.println("If [process] is specified it can be the name or ");
12211                pw.println("pid of a specific process to dump.");
12212                return;
12213            } else {
12214                pw.println("Unknown argument: " + opt + "; use -h for help");
12215            }
12216        }
12217
12218        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12219        long uptime = SystemClock.uptimeMillis();
12220        long realtime = SystemClock.elapsedRealtime();
12221        final long[] tmpLong = new long[1];
12222
12223        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12224        if (procs == null) {
12225            // No Java processes.  Maybe they want to print a native process.
12226            if (args != null && args.length > opti
12227                    && args[opti].charAt(0) != '-') {
12228                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12229                        = new ArrayList<ProcessCpuTracker.Stats>();
12230                updateCpuStatsNow();
12231                int findPid = -1;
12232                try {
12233                    findPid = Integer.parseInt(args[opti]);
12234                } catch (NumberFormatException e) {
12235                }
12236                synchronized (mProcessCpuThread) {
12237                    final int N = mProcessCpuTracker.countStats();
12238                    for (int i=0; i<N; i++) {
12239                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12240                        if (st.pid == findPid || (st.baseName != null
12241                                && st.baseName.equals(args[opti]))) {
12242                            nativeProcs.add(st);
12243                        }
12244                    }
12245                }
12246                if (nativeProcs.size() > 0) {
12247                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12248                            isCompact);
12249                    Debug.MemoryInfo mi = null;
12250                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12251                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12252                        final int pid = r.pid;
12253                        if (!isCheckinRequest && dumpDetails) {
12254                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12255                        }
12256                        if (mi == null) {
12257                            mi = new Debug.MemoryInfo();
12258                        }
12259                        if (dumpDetails || (!brief && !oomOnly)) {
12260                            Debug.getMemoryInfo(pid, mi);
12261                        } else {
12262                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12263                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12264                        }
12265                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12266                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12267                        if (isCheckinRequest) {
12268                            pw.println();
12269                        }
12270                    }
12271                    return;
12272                }
12273            }
12274            pw.println("No process found for: " + args[opti]);
12275            return;
12276        }
12277
12278        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12279            dumpDetails = true;
12280        }
12281
12282        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12283
12284        String[] innerArgs = new String[args.length-opti];
12285        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12286
12287        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12288        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12289        long nativePss=0, dalvikPss=0, otherPss=0;
12290        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12291
12292        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12293        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12294                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12295
12296        long totalPss = 0;
12297        long cachedPss = 0;
12298
12299        Debug.MemoryInfo mi = null;
12300        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12301            final ProcessRecord r = procs.get(i);
12302            final IApplicationThread thread;
12303            final int pid;
12304            final int oomAdj;
12305            final boolean hasActivities;
12306            synchronized (this) {
12307                thread = r.thread;
12308                pid = r.pid;
12309                oomAdj = r.getSetAdjWithServices();
12310                hasActivities = r.activities.size() > 0;
12311            }
12312            if (thread != null) {
12313                if (!isCheckinRequest && dumpDetails) {
12314                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12315                }
12316                if (mi == null) {
12317                    mi = new Debug.MemoryInfo();
12318                }
12319                if (dumpDetails || (!brief && !oomOnly)) {
12320                    Debug.getMemoryInfo(pid, mi);
12321                } else {
12322                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12323                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12324                }
12325                if (dumpDetails) {
12326                    if (localOnly) {
12327                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12328                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12329                        if (isCheckinRequest) {
12330                            pw.println();
12331                        }
12332                    } else {
12333                        try {
12334                            pw.flush();
12335                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12336                                    dumpDalvik, innerArgs);
12337                        } catch (RemoteException e) {
12338                            if (!isCheckinRequest) {
12339                                pw.println("Got RemoteException!");
12340                                pw.flush();
12341                            }
12342                        }
12343                    }
12344                }
12345
12346                final long myTotalPss = mi.getTotalPss();
12347                final long myTotalUss = mi.getTotalUss();
12348
12349                synchronized (this) {
12350                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12351                        // Record this for posterity if the process has been stable.
12352                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12353                    }
12354                }
12355
12356                if (!isCheckinRequest && mi != null) {
12357                    totalPss += myTotalPss;
12358                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12359                            (hasActivities ? " / activities)" : ")"),
12360                            r.processName, myTotalPss, pid, hasActivities);
12361                    procMems.add(pssItem);
12362                    procMemsMap.put(pid, pssItem);
12363
12364                    nativePss += mi.nativePss;
12365                    dalvikPss += mi.dalvikPss;
12366                    otherPss += mi.otherPss;
12367                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12368                        long mem = mi.getOtherPss(j);
12369                        miscPss[j] += mem;
12370                        otherPss -= mem;
12371                    }
12372
12373                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12374                        cachedPss += myTotalPss;
12375                    }
12376
12377                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12378                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12379                                || oomIndex == (oomPss.length-1)) {
12380                            oomPss[oomIndex] += myTotalPss;
12381                            if (oomProcs[oomIndex] == null) {
12382                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12383                            }
12384                            oomProcs[oomIndex].add(pssItem);
12385                            break;
12386                        }
12387                    }
12388                }
12389            }
12390        }
12391
12392        if (!isCheckinRequest && procs.size() > 1) {
12393            // If we are showing aggregations, also look for native processes to
12394            // include so that our aggregations are more accurate.
12395            updateCpuStatsNow();
12396            synchronized (mProcessCpuThread) {
12397                final int N = mProcessCpuTracker.countStats();
12398                for (int i=0; i<N; i++) {
12399                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12400                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12401                        if (mi == null) {
12402                            mi = new Debug.MemoryInfo();
12403                        }
12404                        if (!brief && !oomOnly) {
12405                            Debug.getMemoryInfo(st.pid, mi);
12406                        } else {
12407                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12408                            mi.nativePrivateDirty = (int)tmpLong[0];
12409                        }
12410
12411                        final long myTotalPss = mi.getTotalPss();
12412                        totalPss += myTotalPss;
12413
12414                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12415                                st.name, myTotalPss, st.pid, false);
12416                        procMems.add(pssItem);
12417
12418                        nativePss += mi.nativePss;
12419                        dalvikPss += mi.dalvikPss;
12420                        otherPss += mi.otherPss;
12421                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12422                            long mem = mi.getOtherPss(j);
12423                            miscPss[j] += mem;
12424                            otherPss -= mem;
12425                        }
12426                        oomPss[0] += myTotalPss;
12427                        if (oomProcs[0] == null) {
12428                            oomProcs[0] = new ArrayList<MemItem>();
12429                        }
12430                        oomProcs[0].add(pssItem);
12431                    }
12432                }
12433            }
12434
12435            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12436
12437            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12438            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12439            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12440            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12441                String label = Debug.MemoryInfo.getOtherLabel(j);
12442                catMems.add(new MemItem(label, label, miscPss[j], j));
12443            }
12444
12445            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12446            for (int j=0; j<oomPss.length; j++) {
12447                if (oomPss[j] != 0) {
12448                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12449                            : DUMP_MEM_OOM_LABEL[j];
12450                    MemItem item = new MemItem(label, label, oomPss[j],
12451                            DUMP_MEM_OOM_ADJ[j]);
12452                    item.subitems = oomProcs[j];
12453                    oomMems.add(item);
12454                }
12455            }
12456
12457            if (!brief && !oomOnly && !isCompact) {
12458                pw.println();
12459                pw.println("Total PSS by process:");
12460                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12461                pw.println();
12462            }
12463            if (!isCompact) {
12464                pw.println("Total PSS by OOM adjustment:");
12465            }
12466            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12467            if (!brief && !oomOnly) {
12468                PrintWriter out = categoryPw != null ? categoryPw : pw;
12469                if (!isCompact) {
12470                    out.println();
12471                    out.println("Total PSS by category:");
12472                }
12473                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12474            }
12475            if (!isCompact) {
12476                pw.println();
12477            }
12478            MemInfoReader memInfo = new MemInfoReader();
12479            memInfo.readMemInfo();
12480            if (!brief) {
12481                if (!isCompact) {
12482                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12483                    pw.print(" kB (status ");
12484                    switch (mLastMemoryLevel) {
12485                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12486                            pw.println("normal)");
12487                            break;
12488                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12489                            pw.println("moderate)");
12490                            break;
12491                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12492                            pw.println("low)");
12493                            break;
12494                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12495                            pw.println("critical)");
12496                            break;
12497                        default:
12498                            pw.print(mLastMemoryLevel);
12499                            pw.println(")");
12500                            break;
12501                    }
12502                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12503                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12504                            pw.print(cachedPss); pw.print(" cached pss + ");
12505                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12506                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12507                } else {
12508                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12509                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12510                            + memInfo.getFreeSizeKb()); pw.print(",");
12511                    pw.println(totalPss - cachedPss);
12512                }
12513            }
12514            if (!isCompact) {
12515                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12516                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12517                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12518                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12519                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12520                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12521                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12522                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12523                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12524                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12525                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12526            }
12527            if (!brief) {
12528                if (memInfo.getZramTotalSizeKb() != 0) {
12529                    if (!isCompact) {
12530                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12531                                pw.print(" kB physical used for ");
12532                                pw.print(memInfo.getSwapTotalSizeKb()
12533                                        - memInfo.getSwapFreeSizeKb());
12534                                pw.print(" kB in swap (");
12535                                pw.print(memInfo.getSwapTotalSizeKb());
12536                                pw.println(" kB total swap)");
12537                    } else {
12538                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12539                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12540                                pw.println(memInfo.getSwapFreeSizeKb());
12541                    }
12542                }
12543                final int[] SINGLE_LONG_FORMAT = new int[] {
12544                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12545                };
12546                long[] longOut = new long[1];
12547                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12548                        SINGLE_LONG_FORMAT, null, longOut, null);
12549                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12550                longOut[0] = 0;
12551                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12552                        SINGLE_LONG_FORMAT, null, longOut, null);
12553                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12554                longOut[0] = 0;
12555                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12556                        SINGLE_LONG_FORMAT, null, longOut, null);
12557                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12558                longOut[0] = 0;
12559                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12560                        SINGLE_LONG_FORMAT, null, longOut, null);
12561                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12562                if (!isCompact) {
12563                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12564                        pw.print("      KSM: "); pw.print(sharing);
12565                                pw.print(" kB saved from shared ");
12566                                pw.print(shared); pw.println(" kB");
12567                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12568                                pw.print(voltile); pw.println(" kB volatile");
12569                    }
12570                    pw.print("   Tuning: ");
12571                    pw.print(ActivityManager.staticGetMemoryClass());
12572                    pw.print(" (large ");
12573                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12574                    pw.print("), oom ");
12575                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12576                    pw.print(" kB");
12577                    pw.print(", restore limit ");
12578                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12579                    pw.print(" kB");
12580                    if (ActivityManager.isLowRamDeviceStatic()) {
12581                        pw.print(" (low-ram)");
12582                    }
12583                    if (ActivityManager.isHighEndGfx()) {
12584                        pw.print(" (high-end-gfx)");
12585                    }
12586                    pw.println();
12587                } else {
12588                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12589                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12590                    pw.println(voltile);
12591                    pw.print("tuning,");
12592                    pw.print(ActivityManager.staticGetMemoryClass());
12593                    pw.print(',');
12594                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12595                    pw.print(',');
12596                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12597                    if (ActivityManager.isLowRamDeviceStatic()) {
12598                        pw.print(",low-ram");
12599                    }
12600                    if (ActivityManager.isHighEndGfx()) {
12601                        pw.print(",high-end-gfx");
12602                    }
12603                    pw.println();
12604                }
12605            }
12606        }
12607    }
12608
12609    /**
12610     * Searches array of arguments for the specified string
12611     * @param args array of argument strings
12612     * @param value value to search for
12613     * @return true if the value is contained in the array
12614     */
12615    private static boolean scanArgs(String[] args, String value) {
12616        if (args != null) {
12617            for (String arg : args) {
12618                if (value.equals(arg)) {
12619                    return true;
12620                }
12621            }
12622        }
12623        return false;
12624    }
12625
12626    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12627            ContentProviderRecord cpr, boolean always) {
12628        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12629
12630        if (!inLaunching || always) {
12631            synchronized (cpr) {
12632                cpr.launchingApp = null;
12633                cpr.notifyAll();
12634            }
12635            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12636            String names[] = cpr.info.authority.split(";");
12637            for (int j = 0; j < names.length; j++) {
12638                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12639            }
12640        }
12641
12642        for (int i=0; i<cpr.connections.size(); i++) {
12643            ContentProviderConnection conn = cpr.connections.get(i);
12644            if (conn.waiting) {
12645                // If this connection is waiting for the provider, then we don't
12646                // need to mess with its process unless we are always removing
12647                // or for some reason the provider is not currently launching.
12648                if (inLaunching && !always) {
12649                    continue;
12650                }
12651            }
12652            ProcessRecord capp = conn.client;
12653            conn.dead = true;
12654            if (conn.stableCount > 0) {
12655                if (!capp.persistent && capp.thread != null
12656                        && capp.pid != 0
12657                        && capp.pid != MY_PID) {
12658                    killUnneededProcessLocked(capp, "depends on provider "
12659                            + cpr.name.flattenToShortString()
12660                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12661                }
12662            } else if (capp.thread != null && conn.provider.provider != null) {
12663                try {
12664                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12665                } catch (RemoteException e) {
12666                }
12667                // In the protocol here, we don't expect the client to correctly
12668                // clean up this connection, we'll just remove it.
12669                cpr.connections.remove(i);
12670                conn.client.conProviders.remove(conn);
12671            }
12672        }
12673
12674        if (inLaunching && always) {
12675            mLaunchingProviders.remove(cpr);
12676        }
12677        return inLaunching;
12678    }
12679
12680    /**
12681     * Main code for cleaning up a process when it has gone away.  This is
12682     * called both as a result of the process dying, or directly when stopping
12683     * a process when running in single process mode.
12684     */
12685    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12686            boolean restarting, boolean allowRestart, int index) {
12687        if (index >= 0) {
12688            removeLruProcessLocked(app);
12689            ProcessList.remove(app.pid);
12690        }
12691
12692        mProcessesToGc.remove(app);
12693        mPendingPssProcesses.remove(app);
12694
12695        // Dismiss any open dialogs.
12696        if (app.crashDialog != null && !app.forceCrashReport) {
12697            app.crashDialog.dismiss();
12698            app.crashDialog = null;
12699        }
12700        if (app.anrDialog != null) {
12701            app.anrDialog.dismiss();
12702            app.anrDialog = null;
12703        }
12704        if (app.waitDialog != null) {
12705            app.waitDialog.dismiss();
12706            app.waitDialog = null;
12707        }
12708
12709        app.crashing = false;
12710        app.notResponding = false;
12711
12712        app.resetPackageList(mProcessStats);
12713        app.unlinkDeathRecipient();
12714        app.makeInactive(mProcessStats);
12715        app.forcingToForeground = null;
12716        updateProcessForegroundLocked(app, false, false);
12717        app.foregroundActivities = false;
12718        app.hasShownUi = false;
12719        app.treatLikeActivity = false;
12720        app.hasAboveClient = false;
12721        app.hasClientActivities = false;
12722
12723        mServices.killServicesLocked(app, allowRestart);
12724
12725        boolean restart = false;
12726
12727        // Remove published content providers.
12728        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12729            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12730            final boolean always = app.bad || !allowRestart;
12731            if (removeDyingProviderLocked(app, cpr, always) || always) {
12732                // We left the provider in the launching list, need to
12733                // restart it.
12734                restart = true;
12735            }
12736
12737            cpr.provider = null;
12738            cpr.proc = null;
12739        }
12740        app.pubProviders.clear();
12741
12742        // Take care of any launching providers waiting for this process.
12743        if (checkAppInLaunchingProvidersLocked(app, false)) {
12744            restart = true;
12745        }
12746
12747        // Unregister from connected content providers.
12748        if (!app.conProviders.isEmpty()) {
12749            for (int i=0; i<app.conProviders.size(); i++) {
12750                ContentProviderConnection conn = app.conProviders.get(i);
12751                conn.provider.connections.remove(conn);
12752            }
12753            app.conProviders.clear();
12754        }
12755
12756        // At this point there may be remaining entries in mLaunchingProviders
12757        // where we were the only one waiting, so they are no longer of use.
12758        // Look for these and clean up if found.
12759        // XXX Commented out for now.  Trying to figure out a way to reproduce
12760        // the actual situation to identify what is actually going on.
12761        if (false) {
12762            for (int i=0; i<mLaunchingProviders.size(); i++) {
12763                ContentProviderRecord cpr = (ContentProviderRecord)
12764                        mLaunchingProviders.get(i);
12765                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12766                    synchronized (cpr) {
12767                        cpr.launchingApp = null;
12768                        cpr.notifyAll();
12769                    }
12770                }
12771            }
12772        }
12773
12774        skipCurrentReceiverLocked(app);
12775
12776        // Unregister any receivers.
12777        for (int i=app.receivers.size()-1; i>=0; i--) {
12778            removeReceiverLocked(app.receivers.valueAt(i));
12779        }
12780        app.receivers.clear();
12781
12782        // If the app is undergoing backup, tell the backup manager about it
12783        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12784            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12785                    + mBackupTarget.appInfo + " died during backup");
12786            try {
12787                IBackupManager bm = IBackupManager.Stub.asInterface(
12788                        ServiceManager.getService(Context.BACKUP_SERVICE));
12789                bm.agentDisconnected(app.info.packageName);
12790            } catch (RemoteException e) {
12791                // can't happen; backup manager is local
12792            }
12793        }
12794
12795        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12796            ProcessChangeItem item = mPendingProcessChanges.get(i);
12797            if (item.pid == app.pid) {
12798                mPendingProcessChanges.remove(i);
12799                mAvailProcessChanges.add(item);
12800            }
12801        }
12802        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12803
12804        // If the caller is restarting this app, then leave it in its
12805        // current lists and let the caller take care of it.
12806        if (restarting) {
12807            return;
12808        }
12809
12810        if (!app.persistent || app.isolated) {
12811            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12812                    "Removing non-persistent process during cleanup: " + app);
12813            mProcessNames.remove(app.processName, app.uid);
12814            mIsolatedProcesses.remove(app.uid);
12815            if (mHeavyWeightProcess == app) {
12816                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12817                        mHeavyWeightProcess.userId, 0));
12818                mHeavyWeightProcess = null;
12819            }
12820        } else if (!app.removed) {
12821            // This app is persistent, so we need to keep its record around.
12822            // If it is not already on the pending app list, add it there
12823            // and start a new process for it.
12824            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12825                mPersistentStartingProcesses.add(app);
12826                restart = true;
12827            }
12828        }
12829        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12830                "Clean-up removing on hold: " + app);
12831        mProcessesOnHold.remove(app);
12832
12833        if (app == mHomeProcess) {
12834            mHomeProcess = null;
12835        }
12836        if (app == mPreviousProcess) {
12837            mPreviousProcess = null;
12838        }
12839
12840        if (restart && !app.isolated) {
12841            // We have components that still need to be running in the
12842            // process, so re-launch it.
12843            mProcessNames.put(app.processName, app.uid, app);
12844            startProcessLocked(app, "restart", app.processName);
12845        } else if (app.pid > 0 && app.pid != MY_PID) {
12846            // Goodbye!
12847            boolean removed;
12848            synchronized (mPidsSelfLocked) {
12849                mPidsSelfLocked.remove(app.pid);
12850                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12851            }
12852            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
12853                    app.processName, app.info.uid);
12854            if (app.isolated) {
12855                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
12856            }
12857            app.setPid(0);
12858        }
12859    }
12860
12861    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12862        // Look through the content providers we are waiting to have launched,
12863        // and if any run in this process then either schedule a restart of
12864        // the process or kill the client waiting for it if this process has
12865        // gone bad.
12866        int NL = mLaunchingProviders.size();
12867        boolean restart = false;
12868        for (int i=0; i<NL; i++) {
12869            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12870            if (cpr.launchingApp == app) {
12871                if (!alwaysBad && !app.bad) {
12872                    restart = true;
12873                } else {
12874                    removeDyingProviderLocked(app, cpr, true);
12875                    // cpr should have been removed from mLaunchingProviders
12876                    NL = mLaunchingProviders.size();
12877                    i--;
12878                }
12879            }
12880        }
12881        return restart;
12882    }
12883
12884    // =========================================================
12885    // SERVICES
12886    // =========================================================
12887
12888    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12889            int flags) {
12890        enforceNotIsolatedCaller("getServices");
12891        synchronized (this) {
12892            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12893        }
12894    }
12895
12896    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12897        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12898        synchronized (this) {
12899            return mServices.getRunningServiceControlPanelLocked(name);
12900        }
12901    }
12902
12903    public ComponentName startService(IApplicationThread caller, Intent service,
12904            String resolvedType, int userId) {
12905        enforceNotIsolatedCaller("startService");
12906        // Refuse possible leaked file descriptors
12907        if (service != null && service.hasFileDescriptors() == true) {
12908            throw new IllegalArgumentException("File descriptors passed in Intent");
12909        }
12910
12911        if (DEBUG_SERVICE)
12912            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
12913        synchronized(this) {
12914            final int callingPid = Binder.getCallingPid();
12915            final int callingUid = Binder.getCallingUid();
12916            final long origId = Binder.clearCallingIdentity();
12917            ComponentName res = mServices.startServiceLocked(caller, service,
12918                    resolvedType, callingPid, callingUid, userId);
12919            Binder.restoreCallingIdentity(origId);
12920            return res;
12921        }
12922    }
12923
12924    ComponentName startServiceInPackage(int uid,
12925            Intent service, String resolvedType, int userId) {
12926        synchronized(this) {
12927            if (DEBUG_SERVICE)
12928                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
12929            final long origId = Binder.clearCallingIdentity();
12930            ComponentName res = mServices.startServiceLocked(null, service,
12931                    resolvedType, -1, uid, userId);
12932            Binder.restoreCallingIdentity(origId);
12933            return res;
12934        }
12935    }
12936
12937    public int stopService(IApplicationThread caller, Intent service,
12938            String resolvedType, int userId) {
12939        enforceNotIsolatedCaller("stopService");
12940        // Refuse possible leaked file descriptors
12941        if (service != null && service.hasFileDescriptors() == true) {
12942            throw new IllegalArgumentException("File descriptors passed in Intent");
12943        }
12944
12945        synchronized(this) {
12946            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
12947        }
12948    }
12949
12950    public IBinder peekService(Intent service, String resolvedType) {
12951        enforceNotIsolatedCaller("peekService");
12952        // Refuse possible leaked file descriptors
12953        if (service != null && service.hasFileDescriptors() == true) {
12954            throw new IllegalArgumentException("File descriptors passed in Intent");
12955        }
12956        synchronized(this) {
12957            return mServices.peekServiceLocked(service, resolvedType);
12958        }
12959    }
12960
12961    public boolean stopServiceToken(ComponentName className, IBinder token,
12962            int startId) {
12963        synchronized(this) {
12964            return mServices.stopServiceTokenLocked(className, token, startId);
12965        }
12966    }
12967
12968    public void setServiceForeground(ComponentName className, IBinder token,
12969            int id, Notification notification, boolean removeNotification) {
12970        synchronized(this) {
12971            mServices.setServiceForegroundLocked(className, token, id, notification,
12972                    removeNotification);
12973        }
12974    }
12975
12976    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
12977            boolean requireFull, String name, String callerPackage) {
12978        final int callingUserId = UserHandle.getUserId(callingUid);
12979        if (callingUserId != userId) {
12980            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
12981                if ((requireFull || checkComponentPermission(
12982                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12983                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
12984                        && checkComponentPermission(
12985                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
12986                                callingPid, callingUid, -1, true)
12987                                != PackageManager.PERMISSION_GRANTED) {
12988                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
12989                        // In this case, they would like to just execute as their
12990                        // owner user instead of failing.
12991                        userId = callingUserId;
12992                    } else {
12993                        StringBuilder builder = new StringBuilder(128);
12994                        builder.append("Permission Denial: ");
12995                        builder.append(name);
12996                        if (callerPackage != null) {
12997                            builder.append(" from ");
12998                            builder.append(callerPackage);
12999                        }
13000                        builder.append(" asks to run as user ");
13001                        builder.append(userId);
13002                        builder.append(" but is calling from user ");
13003                        builder.append(UserHandle.getUserId(callingUid));
13004                        builder.append("; this requires ");
13005                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
13006                        if (!requireFull) {
13007                            builder.append(" or ");
13008                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
13009                        }
13010                        String msg = builder.toString();
13011                        Slog.w(TAG, msg);
13012                        throw new SecurityException(msg);
13013                    }
13014                }
13015            }
13016            if (userId == UserHandle.USER_CURRENT
13017                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
13018                // Note that we may be accessing this outside of a lock...
13019                // shouldn't be a big deal, if this is being called outside
13020                // of a locked context there is intrinsically a race with
13021                // the value the caller will receive and someone else changing it.
13022                userId = mCurrentUserId;
13023            }
13024            if (!allowAll && userId < 0) {
13025                throw new IllegalArgumentException(
13026                        "Call does not support special user #" + userId);
13027            }
13028        }
13029        return userId;
13030    }
13031
13032    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13033            String className, int flags) {
13034        boolean result = false;
13035        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13036            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
13037                if (ActivityManager.checkUidPermission(
13038                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13039                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13040                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13041                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13042                            + " requests FLAG_SINGLE_USER, but app does not hold "
13043                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
13044                    Slog.w(TAG, msg);
13045                    throw new SecurityException(msg);
13046                }
13047                result = true;
13048            }
13049        } else if (componentProcessName == aInfo.packageName) {
13050            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13051        } else if ("system".equals(componentProcessName)) {
13052            result = true;
13053        }
13054        if (DEBUG_MU) {
13055            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13056                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13057        }
13058        return result;
13059    }
13060
13061    public int bindService(IApplicationThread caller, IBinder token,
13062            Intent service, String resolvedType,
13063            IServiceConnection connection, int flags, int userId) {
13064        enforceNotIsolatedCaller("bindService");
13065        // Refuse possible leaked file descriptors
13066        if (service != null && service.hasFileDescriptors() == true) {
13067            throw new IllegalArgumentException("File descriptors passed in Intent");
13068        }
13069
13070        synchronized(this) {
13071            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13072                    connection, flags, userId);
13073        }
13074    }
13075
13076    public boolean unbindService(IServiceConnection connection) {
13077        synchronized (this) {
13078            return mServices.unbindServiceLocked(connection);
13079        }
13080    }
13081
13082    public void publishService(IBinder token, Intent intent, IBinder service) {
13083        // Refuse possible leaked file descriptors
13084        if (intent != null && intent.hasFileDescriptors() == true) {
13085            throw new IllegalArgumentException("File descriptors passed in Intent");
13086        }
13087
13088        synchronized(this) {
13089            if (!(token instanceof ServiceRecord)) {
13090                throw new IllegalArgumentException("Invalid service token");
13091            }
13092            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13093        }
13094    }
13095
13096    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13097        // Refuse possible leaked file descriptors
13098        if (intent != null && intent.hasFileDescriptors() == true) {
13099            throw new IllegalArgumentException("File descriptors passed in Intent");
13100        }
13101
13102        synchronized(this) {
13103            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13104        }
13105    }
13106
13107    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13108        synchronized(this) {
13109            if (!(token instanceof ServiceRecord)) {
13110                throw new IllegalArgumentException("Invalid service token");
13111            }
13112            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13113        }
13114    }
13115
13116    // =========================================================
13117    // BACKUP AND RESTORE
13118    // =========================================================
13119
13120    // Cause the target app to be launched if necessary and its backup agent
13121    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13122    // activity manager to announce its creation.
13123    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13124        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13125        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
13126
13127        synchronized(this) {
13128            // !!! TODO: currently no check here that we're already bound
13129            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13130            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13131            synchronized (stats) {
13132                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13133            }
13134
13135            // Backup agent is now in use, its package can't be stopped.
13136            try {
13137                AppGlobals.getPackageManager().setPackageStoppedState(
13138                        app.packageName, false, UserHandle.getUserId(app.uid));
13139            } catch (RemoteException e) {
13140            } catch (IllegalArgumentException e) {
13141                Slog.w(TAG, "Failed trying to unstop package "
13142                        + app.packageName + ": " + e);
13143            }
13144
13145            BackupRecord r = new BackupRecord(ss, app, backupMode);
13146            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13147                    ? new ComponentName(app.packageName, app.backupAgentName)
13148                    : new ComponentName("android", "FullBackupAgent");
13149            // startProcessLocked() returns existing proc's record if it's already running
13150            ProcessRecord proc = startProcessLocked(app.processName, app,
13151                    false, 0, "backup", hostingName, false, false, false);
13152            if (proc == null) {
13153                Slog.e(TAG, "Unable to start backup agent process " + r);
13154                return false;
13155            }
13156
13157            r.app = proc;
13158            mBackupTarget = r;
13159            mBackupAppName = app.packageName;
13160
13161            // Try not to kill the process during backup
13162            updateOomAdjLocked(proc);
13163
13164            // If the process is already attached, schedule the creation of the backup agent now.
13165            // If it is not yet live, this will be done when it attaches to the framework.
13166            if (proc.thread != null) {
13167                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13168                try {
13169                    proc.thread.scheduleCreateBackupAgent(app,
13170                            compatibilityInfoForPackageLocked(app), backupMode);
13171                } catch (RemoteException e) {
13172                    // Will time out on the backup manager side
13173                }
13174            } else {
13175                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13176            }
13177            // Invariants: at this point, the target app process exists and the application
13178            // is either already running or in the process of coming up.  mBackupTarget and
13179            // mBackupAppName describe the app, so that when it binds back to the AM we
13180            // know that it's scheduled for a backup-agent operation.
13181        }
13182
13183        return true;
13184    }
13185
13186    @Override
13187    public void clearPendingBackup() {
13188        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13189        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13190
13191        synchronized (this) {
13192            mBackupTarget = null;
13193            mBackupAppName = null;
13194        }
13195    }
13196
13197    // A backup agent has just come up
13198    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13199        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13200                + " = " + agent);
13201
13202        synchronized(this) {
13203            if (!agentPackageName.equals(mBackupAppName)) {
13204                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13205                return;
13206            }
13207        }
13208
13209        long oldIdent = Binder.clearCallingIdentity();
13210        try {
13211            IBackupManager bm = IBackupManager.Stub.asInterface(
13212                    ServiceManager.getService(Context.BACKUP_SERVICE));
13213            bm.agentConnected(agentPackageName, agent);
13214        } catch (RemoteException e) {
13215            // can't happen; the backup manager service is local
13216        } catch (Exception e) {
13217            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13218            e.printStackTrace();
13219        } finally {
13220            Binder.restoreCallingIdentity(oldIdent);
13221        }
13222    }
13223
13224    // done with this agent
13225    public void unbindBackupAgent(ApplicationInfo appInfo) {
13226        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13227        if (appInfo == null) {
13228            Slog.w(TAG, "unbind backup agent for null app");
13229            return;
13230        }
13231
13232        synchronized(this) {
13233            try {
13234                if (mBackupAppName == null) {
13235                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13236                    return;
13237                }
13238
13239                if (!mBackupAppName.equals(appInfo.packageName)) {
13240                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13241                    return;
13242                }
13243
13244                // Not backing this app up any more; reset its OOM adjustment
13245                final ProcessRecord proc = mBackupTarget.app;
13246                updateOomAdjLocked(proc);
13247
13248                // If the app crashed during backup, 'thread' will be null here
13249                if (proc.thread != null) {
13250                    try {
13251                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13252                                compatibilityInfoForPackageLocked(appInfo));
13253                    } catch (Exception e) {
13254                        Slog.e(TAG, "Exception when unbinding backup agent:");
13255                        e.printStackTrace();
13256                    }
13257                }
13258            } finally {
13259                mBackupTarget = null;
13260                mBackupAppName = null;
13261            }
13262        }
13263    }
13264    // =========================================================
13265    // BROADCASTS
13266    // =========================================================
13267
13268    private final List getStickiesLocked(String action, IntentFilter filter,
13269            List cur, int userId) {
13270        final ContentResolver resolver = mContext.getContentResolver();
13271        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13272        if (stickies == null) {
13273            return cur;
13274        }
13275        final ArrayList<Intent> list = stickies.get(action);
13276        if (list == null) {
13277            return cur;
13278        }
13279        int N = list.size();
13280        for (int i=0; i<N; i++) {
13281            Intent intent = list.get(i);
13282            if (filter.match(resolver, intent, true, TAG) >= 0) {
13283                if (cur == null) {
13284                    cur = new ArrayList<Intent>();
13285                }
13286                cur.add(intent);
13287            }
13288        }
13289        return cur;
13290    }
13291
13292    boolean isPendingBroadcastProcessLocked(int pid) {
13293        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13294                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13295    }
13296
13297    void skipPendingBroadcastLocked(int pid) {
13298            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13299            for (BroadcastQueue queue : mBroadcastQueues) {
13300                queue.skipPendingBroadcastLocked(pid);
13301            }
13302    }
13303
13304    // The app just attached; send any pending broadcasts that it should receive
13305    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13306        boolean didSomething = false;
13307        for (BroadcastQueue queue : mBroadcastQueues) {
13308            didSomething |= queue.sendPendingBroadcastsLocked(app);
13309        }
13310        return didSomething;
13311    }
13312
13313    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13314            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13315        enforceNotIsolatedCaller("registerReceiver");
13316        int callingUid;
13317        int callingPid;
13318        synchronized(this) {
13319            ProcessRecord callerApp = null;
13320            if (caller != null) {
13321                callerApp = getRecordForAppLocked(caller);
13322                if (callerApp == null) {
13323                    throw new SecurityException(
13324                            "Unable to find app for caller " + caller
13325                            + " (pid=" + Binder.getCallingPid()
13326                            + ") when registering receiver " + receiver);
13327                }
13328                if (callerApp.info.uid != Process.SYSTEM_UID &&
13329                        !callerApp.pkgList.containsKey(callerPackage) &&
13330                        !"android".equals(callerPackage)) {
13331                    throw new SecurityException("Given caller package " + callerPackage
13332                            + " is not running in process " + callerApp);
13333                }
13334                callingUid = callerApp.info.uid;
13335                callingPid = callerApp.pid;
13336            } else {
13337                callerPackage = null;
13338                callingUid = Binder.getCallingUid();
13339                callingPid = Binder.getCallingPid();
13340            }
13341
13342            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13343                    true, true, "registerReceiver", callerPackage);
13344
13345            List allSticky = null;
13346
13347            // Look for any matching sticky broadcasts...
13348            Iterator actions = filter.actionsIterator();
13349            if (actions != null) {
13350                while (actions.hasNext()) {
13351                    String action = (String)actions.next();
13352                    allSticky = getStickiesLocked(action, filter, allSticky,
13353                            UserHandle.USER_ALL);
13354                    allSticky = getStickiesLocked(action, filter, allSticky,
13355                            UserHandle.getUserId(callingUid));
13356                }
13357            } else {
13358                allSticky = getStickiesLocked(null, filter, allSticky,
13359                        UserHandle.USER_ALL);
13360                allSticky = getStickiesLocked(null, filter, allSticky,
13361                        UserHandle.getUserId(callingUid));
13362            }
13363
13364            // The first sticky in the list is returned directly back to
13365            // the client.
13366            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13367
13368            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13369                    + ": " + sticky);
13370
13371            if (receiver == null) {
13372                return sticky;
13373            }
13374
13375            ReceiverList rl
13376                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13377            if (rl == null) {
13378                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13379                        userId, receiver);
13380                if (rl.app != null) {
13381                    rl.app.receivers.add(rl);
13382                } else {
13383                    try {
13384                        receiver.asBinder().linkToDeath(rl, 0);
13385                    } catch (RemoteException e) {
13386                        return sticky;
13387                    }
13388                    rl.linkedToDeath = true;
13389                }
13390                mRegisteredReceivers.put(receiver.asBinder(), rl);
13391            } else if (rl.uid != callingUid) {
13392                throw new IllegalArgumentException(
13393                        "Receiver requested to register for uid " + callingUid
13394                        + " was previously registered for uid " + rl.uid);
13395            } else if (rl.pid != callingPid) {
13396                throw new IllegalArgumentException(
13397                        "Receiver requested to register for pid " + callingPid
13398                        + " was previously registered for pid " + rl.pid);
13399            } else if (rl.userId != userId) {
13400                throw new IllegalArgumentException(
13401                        "Receiver requested to register for user " + userId
13402                        + " was previously registered for user " + rl.userId);
13403            }
13404            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13405                    permission, callingUid, userId);
13406            rl.add(bf);
13407            if (!bf.debugCheck()) {
13408                Slog.w(TAG, "==> For Dynamic broadast");
13409            }
13410            mReceiverResolver.addFilter(bf);
13411
13412            // Enqueue broadcasts for all existing stickies that match
13413            // this filter.
13414            if (allSticky != null) {
13415                ArrayList receivers = new ArrayList();
13416                receivers.add(bf);
13417
13418                int N = allSticky.size();
13419                for (int i=0; i<N; i++) {
13420                    Intent intent = (Intent)allSticky.get(i);
13421                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13422                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13423                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13424                            null, null, false, true, true, -1);
13425                    queue.enqueueParallelBroadcastLocked(r);
13426                    queue.scheduleBroadcastsLocked();
13427                }
13428            }
13429
13430            return sticky;
13431        }
13432    }
13433
13434    public void unregisterReceiver(IIntentReceiver receiver) {
13435        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13436
13437        final long origId = Binder.clearCallingIdentity();
13438        try {
13439            boolean doTrim = false;
13440
13441            synchronized(this) {
13442                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13443                if (rl != null) {
13444                    if (rl.curBroadcast != null) {
13445                        BroadcastRecord r = rl.curBroadcast;
13446                        final boolean doNext = finishReceiverLocked(
13447                                receiver.asBinder(), r.resultCode, r.resultData,
13448                                r.resultExtras, r.resultAbort);
13449                        if (doNext) {
13450                            doTrim = true;
13451                            r.queue.processNextBroadcast(false);
13452                        }
13453                    }
13454
13455                    if (rl.app != null) {
13456                        rl.app.receivers.remove(rl);
13457                    }
13458                    removeReceiverLocked(rl);
13459                    if (rl.linkedToDeath) {
13460                        rl.linkedToDeath = false;
13461                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13462                    }
13463                }
13464            }
13465
13466            // If we actually concluded any broadcasts, we might now be able
13467            // to trim the recipients' apps from our working set
13468            if (doTrim) {
13469                trimApplications();
13470                return;
13471            }
13472
13473        } finally {
13474            Binder.restoreCallingIdentity(origId);
13475        }
13476    }
13477
13478    void removeReceiverLocked(ReceiverList rl) {
13479        mRegisteredReceivers.remove(rl.receiver.asBinder());
13480        int N = rl.size();
13481        for (int i=0; i<N; i++) {
13482            mReceiverResolver.removeFilter(rl.get(i));
13483        }
13484    }
13485
13486    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13487        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13488            ProcessRecord r = mLruProcesses.get(i);
13489            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13490                try {
13491                    r.thread.dispatchPackageBroadcast(cmd, packages);
13492                } catch (RemoteException ex) {
13493                }
13494            }
13495        }
13496    }
13497
13498    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13499            int[] users) {
13500        List<ResolveInfo> receivers = null;
13501        try {
13502            HashSet<ComponentName> singleUserReceivers = null;
13503            boolean scannedFirstReceivers = false;
13504            for (int user : users) {
13505                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13506                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13507                if (user != 0 && newReceivers != null) {
13508                    // If this is not the primary user, we need to check for
13509                    // any receivers that should be filtered out.
13510                    for (int i=0; i<newReceivers.size(); i++) {
13511                        ResolveInfo ri = newReceivers.get(i);
13512                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13513                            newReceivers.remove(i);
13514                            i--;
13515                        }
13516                    }
13517                }
13518                if (newReceivers != null && newReceivers.size() == 0) {
13519                    newReceivers = null;
13520                }
13521                if (receivers == null) {
13522                    receivers = newReceivers;
13523                } else if (newReceivers != null) {
13524                    // We need to concatenate the additional receivers
13525                    // found with what we have do far.  This would be easy,
13526                    // but we also need to de-dup any receivers that are
13527                    // singleUser.
13528                    if (!scannedFirstReceivers) {
13529                        // Collect any single user receivers we had already retrieved.
13530                        scannedFirstReceivers = true;
13531                        for (int i=0; i<receivers.size(); i++) {
13532                            ResolveInfo ri = receivers.get(i);
13533                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13534                                ComponentName cn = new ComponentName(
13535                                        ri.activityInfo.packageName, ri.activityInfo.name);
13536                                if (singleUserReceivers == null) {
13537                                    singleUserReceivers = new HashSet<ComponentName>();
13538                                }
13539                                singleUserReceivers.add(cn);
13540                            }
13541                        }
13542                    }
13543                    // Add the new results to the existing results, tracking
13544                    // and de-dupping single user receivers.
13545                    for (int i=0; i<newReceivers.size(); i++) {
13546                        ResolveInfo ri = newReceivers.get(i);
13547                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13548                            ComponentName cn = new ComponentName(
13549                                    ri.activityInfo.packageName, ri.activityInfo.name);
13550                            if (singleUserReceivers == null) {
13551                                singleUserReceivers = new HashSet<ComponentName>();
13552                            }
13553                            if (!singleUserReceivers.contains(cn)) {
13554                                singleUserReceivers.add(cn);
13555                                receivers.add(ri);
13556                            }
13557                        } else {
13558                            receivers.add(ri);
13559                        }
13560                    }
13561                }
13562            }
13563        } catch (RemoteException ex) {
13564            // pm is in same process, this will never happen.
13565        }
13566        return receivers;
13567    }
13568
13569    private final int broadcastIntentLocked(ProcessRecord callerApp,
13570            String callerPackage, Intent intent, String resolvedType,
13571            IIntentReceiver resultTo, int resultCode, String resultData,
13572            Bundle map, String requiredPermission, int appOp,
13573            boolean ordered, boolean sticky, int callingPid, int callingUid,
13574            int userId) {
13575        intent = new Intent(intent);
13576
13577        // By default broadcasts do not go to stopped apps.
13578        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13579
13580        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13581            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13582            + " ordered=" + ordered + " userid=" + userId);
13583        if ((resultTo != null) && !ordered) {
13584            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13585        }
13586
13587        userId = handleIncomingUser(callingPid, callingUid, userId,
13588                true, false, "broadcast", callerPackage);
13589
13590        // Make sure that the user who is receiving this broadcast is started.
13591        // If not, we will just skip it.
13592        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13593            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13594                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13595                Slog.w(TAG, "Skipping broadcast of " + intent
13596                        + ": user " + userId + " is stopped");
13597                return ActivityManager.BROADCAST_SUCCESS;
13598            }
13599        }
13600
13601        /*
13602         * Prevent non-system code (defined here to be non-persistent
13603         * processes) from sending protected broadcasts.
13604         */
13605        int callingAppId = UserHandle.getAppId(callingUid);
13606        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13607            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13608            callingUid == 0) {
13609            // Always okay.
13610        } else if (callerApp == null || !callerApp.persistent) {
13611            try {
13612                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13613                        intent.getAction())) {
13614                    String msg = "Permission Denial: not allowed to send broadcast "
13615                            + intent.getAction() + " from pid="
13616                            + callingPid + ", uid=" + callingUid;
13617                    Slog.w(TAG, msg);
13618                    throw new SecurityException(msg);
13619                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13620                    // Special case for compatibility: we don't want apps to send this,
13621                    // but historically it has not been protected and apps may be using it
13622                    // to poke their own app widget.  So, instead of making it protected,
13623                    // just limit it to the caller.
13624                    if (callerApp == null) {
13625                        String msg = "Permission Denial: not allowed to send broadcast "
13626                                + intent.getAction() + " from unknown caller.";
13627                        Slog.w(TAG, msg);
13628                        throw new SecurityException(msg);
13629                    } else if (intent.getComponent() != null) {
13630                        // They are good enough to send to an explicit component...  verify
13631                        // it is being sent to the calling app.
13632                        if (!intent.getComponent().getPackageName().equals(
13633                                callerApp.info.packageName)) {
13634                            String msg = "Permission Denial: not allowed to send broadcast "
13635                                    + intent.getAction() + " to "
13636                                    + intent.getComponent().getPackageName() + " from "
13637                                    + callerApp.info.packageName;
13638                            Slog.w(TAG, msg);
13639                            throw new SecurityException(msg);
13640                        }
13641                    } else {
13642                        // Limit broadcast to their own package.
13643                        intent.setPackage(callerApp.info.packageName);
13644                    }
13645                }
13646            } catch (RemoteException e) {
13647                Slog.w(TAG, "Remote exception", e);
13648                return ActivityManager.BROADCAST_SUCCESS;
13649            }
13650        }
13651
13652        // Handle special intents: if this broadcast is from the package
13653        // manager about a package being removed, we need to remove all of
13654        // its activities from the history stack.
13655        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13656                intent.getAction());
13657        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13658                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13659                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13660                || uidRemoved) {
13661            if (checkComponentPermission(
13662                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13663                    callingPid, callingUid, -1, true)
13664                    == PackageManager.PERMISSION_GRANTED) {
13665                if (uidRemoved) {
13666                    final Bundle intentExtras = intent.getExtras();
13667                    final int uid = intentExtras != null
13668                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13669                    if (uid >= 0) {
13670                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13671                        synchronized (bs) {
13672                            bs.removeUidStatsLocked(uid);
13673                        }
13674                        mAppOpsService.uidRemoved(uid);
13675                    }
13676                } else {
13677                    // If resources are unavailable just force stop all
13678                    // those packages and flush the attribute cache as well.
13679                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13680                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13681                        if (list != null && (list.length > 0)) {
13682                            for (String pkg : list) {
13683                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13684                                        "storage unmount");
13685                            }
13686                            sendPackageBroadcastLocked(
13687                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13688                        }
13689                    } else {
13690                        Uri data = intent.getData();
13691                        String ssp;
13692                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13693                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13694                                    intent.getAction());
13695                            boolean fullUninstall = removed &&
13696                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13697                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13698                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13699                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13700                                        false, fullUninstall, userId,
13701                                        removed ? "pkg removed" : "pkg changed");
13702                            }
13703                            if (removed) {
13704                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13705                                        new String[] {ssp}, userId);
13706                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13707                                    mAppOpsService.packageRemoved(
13708                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13709
13710                                    // Remove all permissions granted from/to this package
13711                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13712                                }
13713                            }
13714                        }
13715                    }
13716                }
13717            } else {
13718                String msg = "Permission Denial: " + intent.getAction()
13719                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13720                        + ", uid=" + callingUid + ")"
13721                        + " requires "
13722                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13723                Slog.w(TAG, msg);
13724                throw new SecurityException(msg);
13725            }
13726
13727        // Special case for adding a package: by default turn on compatibility
13728        // mode.
13729        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13730            Uri data = intent.getData();
13731            String ssp;
13732            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13733                mCompatModePackages.handlePackageAddedLocked(ssp,
13734                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13735            }
13736        }
13737
13738        /*
13739         * If this is the time zone changed action, queue up a message that will reset the timezone
13740         * of all currently running processes. This message will get queued up before the broadcast
13741         * happens.
13742         */
13743        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13744            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13745        }
13746
13747        /*
13748         * If the user set the time, let all running processes know.
13749         */
13750        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
13751            final int is24Hour = intent.getBooleanExtra(
13752                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
13753            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
13754        }
13755
13756        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13757            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13758        }
13759
13760        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13761            ProxyProperties proxy = intent.getParcelableExtra("proxy");
13762            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13763        }
13764
13765        // Add to the sticky list if requested.
13766        if (sticky) {
13767            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13768                    callingPid, callingUid)
13769                    != PackageManager.PERMISSION_GRANTED) {
13770                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13771                        + callingPid + ", uid=" + callingUid
13772                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13773                Slog.w(TAG, msg);
13774                throw new SecurityException(msg);
13775            }
13776            if (requiredPermission != null) {
13777                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13778                        + " and enforce permission " + requiredPermission);
13779                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13780            }
13781            if (intent.getComponent() != null) {
13782                throw new SecurityException(
13783                        "Sticky broadcasts can't target a specific component");
13784            }
13785            // We use userId directly here, since the "all" target is maintained
13786            // as a separate set of sticky broadcasts.
13787            if (userId != UserHandle.USER_ALL) {
13788                // But first, if this is not a broadcast to all users, then
13789                // make sure it doesn't conflict with an existing broadcast to
13790                // all users.
13791                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13792                        UserHandle.USER_ALL);
13793                if (stickies != null) {
13794                    ArrayList<Intent> list = stickies.get(intent.getAction());
13795                    if (list != null) {
13796                        int N = list.size();
13797                        int i;
13798                        for (i=0; i<N; i++) {
13799                            if (intent.filterEquals(list.get(i))) {
13800                                throw new IllegalArgumentException(
13801                                        "Sticky broadcast " + intent + " for user "
13802                                        + userId + " conflicts with existing global broadcast");
13803                            }
13804                        }
13805                    }
13806                }
13807            }
13808            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13809            if (stickies == null) {
13810                stickies = new ArrayMap<String, ArrayList<Intent>>();
13811                mStickyBroadcasts.put(userId, stickies);
13812            }
13813            ArrayList<Intent> list = stickies.get(intent.getAction());
13814            if (list == null) {
13815                list = new ArrayList<Intent>();
13816                stickies.put(intent.getAction(), list);
13817            }
13818            int N = list.size();
13819            int i;
13820            for (i=0; i<N; i++) {
13821                if (intent.filterEquals(list.get(i))) {
13822                    // This sticky already exists, replace it.
13823                    list.set(i, new Intent(intent));
13824                    break;
13825                }
13826            }
13827            if (i >= N) {
13828                list.add(new Intent(intent));
13829            }
13830        }
13831
13832        int[] users;
13833        if (userId == UserHandle.USER_ALL) {
13834            // Caller wants broadcast to go to all started users.
13835            users = mStartedUserArray;
13836        } else {
13837            // Caller wants broadcast to go to one specific user.
13838            users = new int[] {userId};
13839        }
13840
13841        // Figure out who all will receive this broadcast.
13842        List receivers = null;
13843        List<BroadcastFilter> registeredReceivers = null;
13844        // Need to resolve the intent to interested receivers...
13845        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13846                 == 0) {
13847            receivers = collectReceiverComponents(intent, resolvedType, users);
13848        }
13849        if (intent.getComponent() == null) {
13850            registeredReceivers = mReceiverResolver.queryIntent(intent,
13851                    resolvedType, false, userId);
13852        }
13853
13854        final boolean replacePending =
13855                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13856
13857        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13858                + " replacePending=" + replacePending);
13859
13860        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13861        if (!ordered && NR > 0) {
13862            // If we are not serializing this broadcast, then send the
13863            // registered receivers separately so they don't wait for the
13864            // components to be launched.
13865            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13866            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13867                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13868                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13869                    ordered, sticky, false, userId);
13870            if (DEBUG_BROADCAST) Slog.v(
13871                    TAG, "Enqueueing parallel broadcast " + r);
13872            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13873            if (!replaced) {
13874                queue.enqueueParallelBroadcastLocked(r);
13875                queue.scheduleBroadcastsLocked();
13876            }
13877            registeredReceivers = null;
13878            NR = 0;
13879        }
13880
13881        // Merge into one list.
13882        int ir = 0;
13883        if (receivers != null) {
13884            // A special case for PACKAGE_ADDED: do not allow the package
13885            // being added to see this broadcast.  This prevents them from
13886            // using this as a back door to get run as soon as they are
13887            // installed.  Maybe in the future we want to have a special install
13888            // broadcast or such for apps, but we'd like to deliberately make
13889            // this decision.
13890            String skipPackages[] = null;
13891            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13892                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13893                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13894                Uri data = intent.getData();
13895                if (data != null) {
13896                    String pkgName = data.getSchemeSpecificPart();
13897                    if (pkgName != null) {
13898                        skipPackages = new String[] { pkgName };
13899                    }
13900                }
13901            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13902                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13903            }
13904            if (skipPackages != null && (skipPackages.length > 0)) {
13905                for (String skipPackage : skipPackages) {
13906                    if (skipPackage != null) {
13907                        int NT = receivers.size();
13908                        for (int it=0; it<NT; it++) {
13909                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
13910                            if (curt.activityInfo.packageName.equals(skipPackage)) {
13911                                receivers.remove(it);
13912                                it--;
13913                                NT--;
13914                            }
13915                        }
13916                    }
13917                }
13918            }
13919
13920            int NT = receivers != null ? receivers.size() : 0;
13921            int it = 0;
13922            ResolveInfo curt = null;
13923            BroadcastFilter curr = null;
13924            while (it < NT && ir < NR) {
13925                if (curt == null) {
13926                    curt = (ResolveInfo)receivers.get(it);
13927                }
13928                if (curr == null) {
13929                    curr = registeredReceivers.get(ir);
13930                }
13931                if (curr.getPriority() >= curt.priority) {
13932                    // Insert this broadcast record into the final list.
13933                    receivers.add(it, curr);
13934                    ir++;
13935                    curr = null;
13936                    it++;
13937                    NT++;
13938                } else {
13939                    // Skip to the next ResolveInfo in the final list.
13940                    it++;
13941                    curt = null;
13942                }
13943            }
13944        }
13945        while (ir < NR) {
13946            if (receivers == null) {
13947                receivers = new ArrayList();
13948            }
13949            receivers.add(registeredReceivers.get(ir));
13950            ir++;
13951        }
13952
13953        if ((receivers != null && receivers.size() > 0)
13954                || resultTo != null) {
13955            BroadcastQueue queue = broadcastQueueForIntent(intent);
13956            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13957                    callerPackage, callingPid, callingUid, resolvedType,
13958                    requiredPermission, appOp, receivers, resultTo, resultCode,
13959                    resultData, map, ordered, sticky, false, userId);
13960            if (DEBUG_BROADCAST) Slog.v(
13961                    TAG, "Enqueueing ordered broadcast " + r
13962                    + ": prev had " + queue.mOrderedBroadcasts.size());
13963            if (DEBUG_BROADCAST) {
13964                int seq = r.intent.getIntExtra("seq", -1);
13965                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
13966            }
13967            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
13968            if (!replaced) {
13969                queue.enqueueOrderedBroadcastLocked(r);
13970                queue.scheduleBroadcastsLocked();
13971            }
13972        }
13973
13974        return ActivityManager.BROADCAST_SUCCESS;
13975    }
13976
13977    final Intent verifyBroadcastLocked(Intent intent) {
13978        // Refuse possible leaked file descriptors
13979        if (intent != null && intent.hasFileDescriptors() == true) {
13980            throw new IllegalArgumentException("File descriptors passed in Intent");
13981        }
13982
13983        int flags = intent.getFlags();
13984
13985        if (!mProcessesReady) {
13986            // if the caller really truly claims to know what they're doing, go
13987            // ahead and allow the broadcast without launching any receivers
13988            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
13989                intent = new Intent(intent);
13990                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13991            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
13992                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
13993                        + " before boot completion");
13994                throw new IllegalStateException("Cannot broadcast before boot completed");
13995            }
13996        }
13997
13998        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
13999            throw new IllegalArgumentException(
14000                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14001        }
14002
14003        return intent;
14004    }
14005
14006    public final int broadcastIntent(IApplicationThread caller,
14007            Intent intent, String resolvedType, IIntentReceiver resultTo,
14008            int resultCode, String resultData, Bundle map,
14009            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14010        enforceNotIsolatedCaller("broadcastIntent");
14011        synchronized(this) {
14012            intent = verifyBroadcastLocked(intent);
14013
14014            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14015            final int callingPid = Binder.getCallingPid();
14016            final int callingUid = Binder.getCallingUid();
14017            final long origId = Binder.clearCallingIdentity();
14018            int res = broadcastIntentLocked(callerApp,
14019                    callerApp != null ? callerApp.info.packageName : null,
14020                    intent, resolvedType, resultTo,
14021                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14022                    callingPid, callingUid, userId);
14023            Binder.restoreCallingIdentity(origId);
14024            return res;
14025        }
14026    }
14027
14028    int broadcastIntentInPackage(String packageName, int uid,
14029            Intent intent, String resolvedType, IIntentReceiver resultTo,
14030            int resultCode, String resultData, Bundle map,
14031            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14032        synchronized(this) {
14033            intent = verifyBroadcastLocked(intent);
14034
14035            final long origId = Binder.clearCallingIdentity();
14036            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14037                    resultTo, resultCode, resultData, map, requiredPermission,
14038                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14039            Binder.restoreCallingIdentity(origId);
14040            return res;
14041        }
14042    }
14043
14044    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14045        // Refuse possible leaked file descriptors
14046        if (intent != null && intent.hasFileDescriptors() == true) {
14047            throw new IllegalArgumentException("File descriptors passed in Intent");
14048        }
14049
14050        userId = handleIncomingUser(Binder.getCallingPid(),
14051                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
14052
14053        synchronized(this) {
14054            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14055                    != PackageManager.PERMISSION_GRANTED) {
14056                String msg = "Permission Denial: unbroadcastIntent() from pid="
14057                        + Binder.getCallingPid()
14058                        + ", uid=" + Binder.getCallingUid()
14059                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14060                Slog.w(TAG, msg);
14061                throw new SecurityException(msg);
14062            }
14063            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14064            if (stickies != null) {
14065                ArrayList<Intent> list = stickies.get(intent.getAction());
14066                if (list != null) {
14067                    int N = list.size();
14068                    int i;
14069                    for (i=0; i<N; i++) {
14070                        if (intent.filterEquals(list.get(i))) {
14071                            list.remove(i);
14072                            break;
14073                        }
14074                    }
14075                    if (list.size() <= 0) {
14076                        stickies.remove(intent.getAction());
14077                    }
14078                }
14079                if (stickies.size() <= 0) {
14080                    mStickyBroadcasts.remove(userId);
14081                }
14082            }
14083        }
14084    }
14085
14086    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14087            String resultData, Bundle resultExtras, boolean resultAbort) {
14088        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14089        if (r == null) {
14090            Slog.w(TAG, "finishReceiver called but not found on queue");
14091            return false;
14092        }
14093
14094        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14095    }
14096
14097    void backgroundServicesFinishedLocked(int userId) {
14098        for (BroadcastQueue queue : mBroadcastQueues) {
14099            queue.backgroundServicesFinishedLocked(userId);
14100        }
14101    }
14102
14103    public void finishReceiver(IBinder who, int resultCode, String resultData,
14104            Bundle resultExtras, boolean resultAbort) {
14105        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14106
14107        // Refuse possible leaked file descriptors
14108        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14109            throw new IllegalArgumentException("File descriptors passed in Bundle");
14110        }
14111
14112        final long origId = Binder.clearCallingIdentity();
14113        try {
14114            boolean doNext = false;
14115            BroadcastRecord r;
14116
14117            synchronized(this) {
14118                r = broadcastRecordForReceiverLocked(who);
14119                if (r != null) {
14120                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14121                        resultData, resultExtras, resultAbort, true);
14122                }
14123            }
14124
14125            if (doNext) {
14126                r.queue.processNextBroadcast(false);
14127            }
14128            trimApplications();
14129        } finally {
14130            Binder.restoreCallingIdentity(origId);
14131        }
14132    }
14133
14134    // =========================================================
14135    // INSTRUMENTATION
14136    // =========================================================
14137
14138    public boolean startInstrumentation(ComponentName className,
14139            String profileFile, int flags, Bundle arguments,
14140            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14141            int userId) {
14142        enforceNotIsolatedCaller("startInstrumentation");
14143        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14144                userId, false, true, "startInstrumentation", null);
14145        // Refuse possible leaked file descriptors
14146        if (arguments != null && arguments.hasFileDescriptors()) {
14147            throw new IllegalArgumentException("File descriptors passed in Bundle");
14148        }
14149
14150        synchronized(this) {
14151            InstrumentationInfo ii = null;
14152            ApplicationInfo ai = null;
14153            try {
14154                ii = mContext.getPackageManager().getInstrumentationInfo(
14155                    className, STOCK_PM_FLAGS);
14156                ai = AppGlobals.getPackageManager().getApplicationInfo(
14157                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14158            } catch (PackageManager.NameNotFoundException e) {
14159            } catch (RemoteException e) {
14160            }
14161            if (ii == null) {
14162                reportStartInstrumentationFailure(watcher, className,
14163                        "Unable to find instrumentation info for: " + className);
14164                return false;
14165            }
14166            if (ai == null) {
14167                reportStartInstrumentationFailure(watcher, className,
14168                        "Unable to find instrumentation target package: " + ii.targetPackage);
14169                return false;
14170            }
14171
14172            int match = mContext.getPackageManager().checkSignatures(
14173                    ii.targetPackage, ii.packageName);
14174            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14175                String msg = "Permission Denial: starting instrumentation "
14176                        + className + " from pid="
14177                        + Binder.getCallingPid()
14178                        + ", uid=" + Binder.getCallingPid()
14179                        + " not allowed because package " + ii.packageName
14180                        + " does not have a signature matching the target "
14181                        + ii.targetPackage;
14182                reportStartInstrumentationFailure(watcher, className, msg);
14183                throw new SecurityException(msg);
14184            }
14185
14186            final long origId = Binder.clearCallingIdentity();
14187            // Instrumentation can kill and relaunch even persistent processes
14188            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14189                    "start instr");
14190            ProcessRecord app = addAppLocked(ai, false);
14191            app.instrumentationClass = className;
14192            app.instrumentationInfo = ai;
14193            app.instrumentationProfileFile = profileFile;
14194            app.instrumentationArguments = arguments;
14195            app.instrumentationWatcher = watcher;
14196            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14197            app.instrumentationResultClass = className;
14198            Binder.restoreCallingIdentity(origId);
14199        }
14200
14201        return true;
14202    }
14203
14204    /**
14205     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14206     * error to the logs, but if somebody is watching, send the report there too.  This enables
14207     * the "am" command to report errors with more information.
14208     *
14209     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14210     * @param cn The component name of the instrumentation.
14211     * @param report The error report.
14212     */
14213    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14214            ComponentName cn, String report) {
14215        Slog.w(TAG, report);
14216        try {
14217            if (watcher != null) {
14218                Bundle results = new Bundle();
14219                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14220                results.putString("Error", report);
14221                watcher.instrumentationStatus(cn, -1, results);
14222            }
14223        } catch (RemoteException e) {
14224            Slog.w(TAG, e);
14225        }
14226    }
14227
14228    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14229        if (app.instrumentationWatcher != null) {
14230            try {
14231                // NOTE:  IInstrumentationWatcher *must* be oneway here
14232                app.instrumentationWatcher.instrumentationFinished(
14233                    app.instrumentationClass,
14234                    resultCode,
14235                    results);
14236            } catch (RemoteException e) {
14237            }
14238        }
14239        if (app.instrumentationUiAutomationConnection != null) {
14240            try {
14241                app.instrumentationUiAutomationConnection.shutdown();
14242            } catch (RemoteException re) {
14243                /* ignore */
14244            }
14245            // Only a UiAutomation can set this flag and now that
14246            // it is finished we make sure it is reset to its default.
14247            mUserIsMonkey = false;
14248        }
14249        app.instrumentationWatcher = null;
14250        app.instrumentationUiAutomationConnection = null;
14251        app.instrumentationClass = null;
14252        app.instrumentationInfo = null;
14253        app.instrumentationProfileFile = null;
14254        app.instrumentationArguments = null;
14255
14256        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14257                "finished inst");
14258    }
14259
14260    public void finishInstrumentation(IApplicationThread target,
14261            int resultCode, Bundle results) {
14262        int userId = UserHandle.getCallingUserId();
14263        // Refuse possible leaked file descriptors
14264        if (results != null && results.hasFileDescriptors()) {
14265            throw new IllegalArgumentException("File descriptors passed in Intent");
14266        }
14267
14268        synchronized(this) {
14269            ProcessRecord app = getRecordForAppLocked(target);
14270            if (app == null) {
14271                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14272                return;
14273            }
14274            final long origId = Binder.clearCallingIdentity();
14275            finishInstrumentationLocked(app, resultCode, results);
14276            Binder.restoreCallingIdentity(origId);
14277        }
14278    }
14279
14280    // =========================================================
14281    // CONFIGURATION
14282    // =========================================================
14283
14284    public ConfigurationInfo getDeviceConfigurationInfo() {
14285        ConfigurationInfo config = new ConfigurationInfo();
14286        synchronized (this) {
14287            config.reqTouchScreen = mConfiguration.touchscreen;
14288            config.reqKeyboardType = mConfiguration.keyboard;
14289            config.reqNavigation = mConfiguration.navigation;
14290            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14291                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14292                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14293            }
14294            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14295                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14296                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14297            }
14298            config.reqGlEsVersion = GL_ES_VERSION;
14299        }
14300        return config;
14301    }
14302
14303    ActivityStack getFocusedStack() {
14304        return mStackSupervisor.getFocusedStack();
14305    }
14306
14307    public Configuration getConfiguration() {
14308        Configuration ci;
14309        synchronized(this) {
14310            ci = new Configuration(mConfiguration);
14311        }
14312        return ci;
14313    }
14314
14315    public void updatePersistentConfiguration(Configuration values) {
14316        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14317                "updateConfiguration()");
14318        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14319                "updateConfiguration()");
14320        if (values == null) {
14321            throw new NullPointerException("Configuration must not be null");
14322        }
14323
14324        synchronized(this) {
14325            final long origId = Binder.clearCallingIdentity();
14326            updateConfigurationLocked(values, null, true, false);
14327            Binder.restoreCallingIdentity(origId);
14328        }
14329    }
14330
14331    public void updateConfiguration(Configuration values) {
14332        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14333                "updateConfiguration()");
14334
14335        synchronized(this) {
14336            if (values == null && mWindowManager != null) {
14337                // sentinel: fetch the current configuration from the window manager
14338                values = mWindowManager.computeNewConfiguration();
14339            }
14340
14341            if (mWindowManager != null) {
14342                mProcessList.applyDisplaySize(mWindowManager);
14343            }
14344
14345            final long origId = Binder.clearCallingIdentity();
14346            if (values != null) {
14347                Settings.System.clearConfiguration(values);
14348            }
14349            updateConfigurationLocked(values, null, false, false);
14350            Binder.restoreCallingIdentity(origId);
14351        }
14352    }
14353
14354    /**
14355     * Do either or both things: (1) change the current configuration, and (2)
14356     * make sure the given activity is running with the (now) current
14357     * configuration.  Returns true if the activity has been left running, or
14358     * false if <var>starting</var> is being destroyed to match the new
14359     * configuration.
14360     * @param persistent TODO
14361     */
14362    boolean updateConfigurationLocked(Configuration values,
14363            ActivityRecord starting, boolean persistent, boolean initLocale) {
14364        int changes = 0;
14365
14366        if (values != null) {
14367            Configuration newConfig = new Configuration(mConfiguration);
14368            changes = newConfig.updateFrom(values);
14369            if (changes != 0) {
14370                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14371                    Slog.i(TAG, "Updating configuration to: " + values);
14372                }
14373
14374                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14375
14376                if (values.locale != null && !initLocale) {
14377                    saveLocaleLocked(values.locale,
14378                                     !values.locale.equals(mConfiguration.locale),
14379                                     values.userSetLocale);
14380                }
14381
14382                mConfigurationSeq++;
14383                if (mConfigurationSeq <= 0) {
14384                    mConfigurationSeq = 1;
14385                }
14386                newConfig.seq = mConfigurationSeq;
14387                mConfiguration = newConfig;
14388                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14389
14390                final Configuration configCopy = new Configuration(mConfiguration);
14391
14392                // TODO: If our config changes, should we auto dismiss any currently
14393                // showing dialogs?
14394                mShowDialogs = shouldShowDialogs(newConfig);
14395
14396                AttributeCache ac = AttributeCache.instance();
14397                if (ac != null) {
14398                    ac.updateConfiguration(configCopy);
14399                }
14400
14401                // Make sure all resources in our process are updated
14402                // right now, so that anyone who is going to retrieve
14403                // resource values after we return will be sure to get
14404                // the new ones.  This is especially important during
14405                // boot, where the first config change needs to guarantee
14406                // all resources have that config before following boot
14407                // code is executed.
14408                mSystemThread.applyConfigurationToResources(configCopy);
14409
14410                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14411                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14412                    msg.obj = new Configuration(configCopy);
14413                    mHandler.sendMessage(msg);
14414                }
14415
14416                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14417                    ProcessRecord app = mLruProcesses.get(i);
14418                    try {
14419                        if (app.thread != null) {
14420                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14421                                    + app.processName + " new config " + mConfiguration);
14422                            app.thread.scheduleConfigurationChanged(configCopy);
14423                        }
14424                    } catch (Exception e) {
14425                    }
14426                }
14427                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14428                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14429                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14430                        | Intent.FLAG_RECEIVER_FOREGROUND);
14431                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14432                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14433                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14434                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14435                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14436                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14437                    broadcastIntentLocked(null, null, intent,
14438                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14439                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14440                }
14441            }
14442        }
14443
14444        boolean kept = true;
14445        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14446        // mainStack is null during startup.
14447        if (mainStack != null) {
14448            if (changes != 0 && starting == null) {
14449                // If the configuration changed, and the caller is not already
14450                // in the process of starting an activity, then find the top
14451                // activity to check if its configuration needs to change.
14452                starting = mainStack.topRunningActivityLocked(null);
14453            }
14454
14455            if (starting != null) {
14456                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14457                // And we need to make sure at this point that all other activities
14458                // are made visible with the correct configuration.
14459                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14460            }
14461        }
14462
14463        if (values != null && mWindowManager != null) {
14464            mWindowManager.setNewConfiguration(mConfiguration);
14465        }
14466
14467        return kept;
14468    }
14469
14470    /**
14471     * Decide based on the configuration whether we should shouw the ANR,
14472     * crash, etc dialogs.  The idea is that if there is no affordnace to
14473     * press the on-screen buttons, we shouldn't show the dialog.
14474     *
14475     * A thought: SystemUI might also want to get told about this, the Power
14476     * dialog / global actions also might want different behaviors.
14477     */
14478    private static final boolean shouldShowDialogs(Configuration config) {
14479        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14480                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14481    }
14482
14483    /**
14484     * Save the locale.  You must be inside a synchronized (this) block.
14485     */
14486    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14487        if(isDiff) {
14488            SystemProperties.set("user.language", l.getLanguage());
14489            SystemProperties.set("user.region", l.getCountry());
14490        }
14491
14492        if(isPersist) {
14493            SystemProperties.set("persist.sys.language", l.getLanguage());
14494            SystemProperties.set("persist.sys.country", l.getCountry());
14495            SystemProperties.set("persist.sys.localevar", l.getVariant());
14496        }
14497    }
14498
14499    @Override
14500    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14501        ActivityRecord srec = ActivityRecord.forToken(token);
14502        return srec != null && srec.task.affinity != null &&
14503                srec.task.affinity.equals(destAffinity);
14504    }
14505
14506    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14507            Intent resultData) {
14508
14509        synchronized (this) {
14510            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14511            if (stack != null) {
14512                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14513            }
14514            return false;
14515        }
14516    }
14517
14518    public int getLaunchedFromUid(IBinder activityToken) {
14519        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14520        if (srec == null) {
14521            return -1;
14522        }
14523        return srec.launchedFromUid;
14524    }
14525
14526    public String getLaunchedFromPackage(IBinder activityToken) {
14527        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14528        if (srec == null) {
14529            return null;
14530        }
14531        return srec.launchedFromPackage;
14532    }
14533
14534    // =========================================================
14535    // LIFETIME MANAGEMENT
14536    // =========================================================
14537
14538    // Returns which broadcast queue the app is the current [or imminent] receiver
14539    // on, or 'null' if the app is not an active broadcast recipient.
14540    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14541        BroadcastRecord r = app.curReceiver;
14542        if (r != null) {
14543            return r.queue;
14544        }
14545
14546        // It's not the current receiver, but it might be starting up to become one
14547        synchronized (this) {
14548            for (BroadcastQueue queue : mBroadcastQueues) {
14549                r = queue.mPendingBroadcast;
14550                if (r != null && r.curApp == app) {
14551                    // found it; report which queue it's in
14552                    return queue;
14553                }
14554            }
14555        }
14556
14557        return null;
14558    }
14559
14560    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14561            boolean doingAll, long now) {
14562        if (mAdjSeq == app.adjSeq) {
14563            // This adjustment has already been computed.
14564            return app.curRawAdj;
14565        }
14566
14567        if (app.thread == null) {
14568            app.adjSeq = mAdjSeq;
14569            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14570            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14571            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14572        }
14573
14574        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14575        app.adjSource = null;
14576        app.adjTarget = null;
14577        app.empty = false;
14578        app.cached = false;
14579
14580        final int activitiesSize = app.activities.size();
14581
14582        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14583            // The max adjustment doesn't allow this app to be anything
14584            // below foreground, so it is not worth doing work for it.
14585            app.adjType = "fixed";
14586            app.adjSeq = mAdjSeq;
14587            app.curRawAdj = app.maxAdj;
14588            app.foregroundActivities = false;
14589            app.keeping = true;
14590            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14591            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14592            // System processes can do UI, and when they do we want to have
14593            // them trim their memory after the user leaves the UI.  To
14594            // facilitate this, here we need to determine whether or not it
14595            // is currently showing UI.
14596            app.systemNoUi = true;
14597            if (app == TOP_APP) {
14598                app.systemNoUi = false;
14599            } else if (activitiesSize > 0) {
14600                for (int j = 0; j < activitiesSize; j++) {
14601                    final ActivityRecord r = app.activities.get(j);
14602                    if (r.visible) {
14603                        app.systemNoUi = false;
14604                    }
14605                }
14606            }
14607            if (!app.systemNoUi) {
14608                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14609            }
14610            return (app.curAdj=app.maxAdj);
14611        }
14612
14613        app.keeping = false;
14614        app.systemNoUi = false;
14615
14616        // Determine the importance of the process, starting with most
14617        // important to least, and assign an appropriate OOM adjustment.
14618        int adj;
14619        int schedGroup;
14620        int procState;
14621        boolean foregroundActivities = false;
14622        boolean interesting = false;
14623        BroadcastQueue queue;
14624        if (app == TOP_APP) {
14625            // The last app on the list is the foreground app.
14626            adj = ProcessList.FOREGROUND_APP_ADJ;
14627            schedGroup = Process.THREAD_GROUP_DEFAULT;
14628            app.adjType = "top-activity";
14629            foregroundActivities = true;
14630            interesting = true;
14631            procState = ActivityManager.PROCESS_STATE_TOP;
14632        } else if (app.instrumentationClass != null) {
14633            // Don't want to kill running instrumentation.
14634            adj = ProcessList.FOREGROUND_APP_ADJ;
14635            schedGroup = Process.THREAD_GROUP_DEFAULT;
14636            app.adjType = "instrumentation";
14637            interesting = true;
14638            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14639        } else if ((queue = isReceivingBroadcast(app)) != null) {
14640            // An app that is currently receiving a broadcast also
14641            // counts as being in the foreground for OOM killer purposes.
14642            // It's placed in a sched group based on the nature of the
14643            // broadcast as reflected by which queue it's active in.
14644            adj = ProcessList.FOREGROUND_APP_ADJ;
14645            schedGroup = (queue == mFgBroadcastQueue)
14646                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14647            app.adjType = "broadcast";
14648            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14649        } else if (app.executingServices.size() > 0) {
14650            // An app that is currently executing a service callback also
14651            // counts as being in the foreground.
14652            adj = ProcessList.FOREGROUND_APP_ADJ;
14653            schedGroup = app.execServicesFg ?
14654                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14655            app.adjType = "exec-service";
14656            procState = ActivityManager.PROCESS_STATE_SERVICE;
14657            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14658        } else {
14659            // As far as we know the process is empty.  We may change our mind later.
14660            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14661            // At this point we don't actually know the adjustment.  Use the cached adj
14662            // value that the caller wants us to.
14663            adj = cachedAdj;
14664            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14665            app.cached = true;
14666            app.empty = true;
14667            app.adjType = "cch-empty";
14668        }
14669
14670        // Examine all activities if not already foreground.
14671        if (!foregroundActivities && activitiesSize > 0) {
14672            for (int j = 0; j < activitiesSize; j++) {
14673                final ActivityRecord r = app.activities.get(j);
14674                if (r.app != app) {
14675                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14676                            + app + "?!?");
14677                    continue;
14678                }
14679                if (r.visible) {
14680                    // App has a visible activity; only upgrade adjustment.
14681                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14682                        adj = ProcessList.VISIBLE_APP_ADJ;
14683                        app.adjType = "visible";
14684                    }
14685                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14686                        procState = ActivityManager.PROCESS_STATE_TOP;
14687                    }
14688                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14689                    app.cached = false;
14690                    app.empty = false;
14691                    foregroundActivities = true;
14692                    break;
14693                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14694                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14695                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14696                        app.adjType = "pausing";
14697                    }
14698                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14699                        procState = ActivityManager.PROCESS_STATE_TOP;
14700                    }
14701                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14702                    app.cached = false;
14703                    app.empty = false;
14704                    foregroundActivities = true;
14705                } else if (r.state == ActivityState.STOPPING) {
14706                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14707                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14708                        app.adjType = "stopping";
14709                    }
14710                    // For the process state, we will at this point consider the
14711                    // process to be cached.  It will be cached either as an activity
14712                    // or empty depending on whether the activity is finishing.  We do
14713                    // this so that we can treat the process as cached for purposes of
14714                    // memory trimming (determing current memory level, trim command to
14715                    // send to process) since there can be an arbitrary number of stopping
14716                    // processes and they should soon all go into the cached state.
14717                    if (!r.finishing) {
14718                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14719                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14720                        }
14721                    }
14722                    app.cached = false;
14723                    app.empty = false;
14724                    foregroundActivities = true;
14725                } else {
14726                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14727                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14728                        app.adjType = "cch-act";
14729                    }
14730                }
14731            }
14732        }
14733
14734        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14735            if (app.foregroundServices) {
14736                // The user is aware of this app, so make it visible.
14737                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14738                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14739                app.cached = false;
14740                app.adjType = "fg-service";
14741                schedGroup = Process.THREAD_GROUP_DEFAULT;
14742            } else if (app.forcingToForeground != null) {
14743                // The user is aware of this app, so make it visible.
14744                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14745                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14746                app.cached = false;
14747                app.adjType = "force-fg";
14748                app.adjSource = app.forcingToForeground;
14749                schedGroup = Process.THREAD_GROUP_DEFAULT;
14750            }
14751        }
14752
14753        if (app.foregroundServices) {
14754            interesting = true;
14755        }
14756
14757        if (app == mHeavyWeightProcess) {
14758            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14759                // We don't want to kill the current heavy-weight process.
14760                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14761                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14762                app.cached = false;
14763                app.adjType = "heavy";
14764            }
14765            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14766                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14767            }
14768        }
14769
14770        if (app == mHomeProcess) {
14771            if (adj > ProcessList.HOME_APP_ADJ) {
14772                // This process is hosting what we currently consider to be the
14773                // home app, so we don't want to let it go into the background.
14774                adj = ProcessList.HOME_APP_ADJ;
14775                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14776                app.cached = false;
14777                app.adjType = "home";
14778            }
14779            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14780                procState = ActivityManager.PROCESS_STATE_HOME;
14781            }
14782        }
14783
14784        if (app == mPreviousProcess && app.activities.size() > 0) {
14785            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14786                // This was the previous process that showed UI to the user.
14787                // We want to try to keep it around more aggressively, to give
14788                // a good experience around switching between two apps.
14789                adj = ProcessList.PREVIOUS_APP_ADJ;
14790                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14791                app.cached = false;
14792                app.adjType = "previous";
14793            }
14794            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14795                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14796            }
14797        }
14798
14799        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14800                + " reason=" + app.adjType);
14801
14802        // By default, we use the computed adjustment.  It may be changed if
14803        // there are applications dependent on our services or providers, but
14804        // this gives us a baseline and makes sure we don't get into an
14805        // infinite recursion.
14806        app.adjSeq = mAdjSeq;
14807        app.curRawAdj = adj;
14808        app.hasStartedServices = false;
14809
14810        if (mBackupTarget != null && app == mBackupTarget.app) {
14811            // If possible we want to avoid killing apps while they're being backed up
14812            if (adj > ProcessList.BACKUP_APP_ADJ) {
14813                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14814                adj = ProcessList.BACKUP_APP_ADJ;
14815                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14816                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14817                }
14818                app.adjType = "backup";
14819                app.cached = false;
14820            }
14821            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14822                procState = ActivityManager.PROCESS_STATE_BACKUP;
14823            }
14824        }
14825
14826        boolean mayBeTop = false;
14827
14828        for (int is = app.services.size()-1;
14829                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14830                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14831                        || procState > ActivityManager.PROCESS_STATE_TOP);
14832                is--) {
14833            ServiceRecord s = app.services.valueAt(is);
14834            if (s.startRequested) {
14835                app.hasStartedServices = true;
14836                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14837                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14838                }
14839                if (app.hasShownUi && app != mHomeProcess) {
14840                    // If this process has shown some UI, let it immediately
14841                    // go to the LRU list because it may be pretty heavy with
14842                    // UI stuff.  We'll tag it with a label just to help
14843                    // debug and understand what is going on.
14844                    if (adj > ProcessList.SERVICE_ADJ) {
14845                        app.adjType = "cch-started-ui-services";
14846                    }
14847                } else {
14848                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14849                        // This service has seen some activity within
14850                        // recent memory, so we will keep its process ahead
14851                        // of the background processes.
14852                        if (adj > ProcessList.SERVICE_ADJ) {
14853                            adj = ProcessList.SERVICE_ADJ;
14854                            app.adjType = "started-services";
14855                            app.cached = false;
14856                        }
14857                    }
14858                    // If we have let the service slide into the background
14859                    // state, still have some text describing what it is doing
14860                    // even though the service no longer has an impact.
14861                    if (adj > ProcessList.SERVICE_ADJ) {
14862                        app.adjType = "cch-started-services";
14863                    }
14864                }
14865                // Don't kill this process because it is doing work; it
14866                // has said it is doing work.
14867                app.keeping = true;
14868            }
14869            for (int conni = s.connections.size()-1;
14870                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14871                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14872                            || procState > ActivityManager.PROCESS_STATE_TOP);
14873                    conni--) {
14874                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14875                for (int i = 0;
14876                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14877                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14878                                || procState > ActivityManager.PROCESS_STATE_TOP);
14879                        i++) {
14880                    // XXX should compute this based on the max of
14881                    // all connected clients.
14882                    ConnectionRecord cr = clist.get(i);
14883                    if (cr.binding.client == app) {
14884                        // Binding to ourself is not interesting.
14885                        continue;
14886                    }
14887                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14888                        ProcessRecord client = cr.binding.client;
14889                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14890                                TOP_APP, doingAll, now);
14891                        int clientProcState = client.curProcState;
14892                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14893                            // If the other app is cached for any reason, for purposes here
14894                            // we are going to consider it empty.  The specific cached state
14895                            // doesn't propagate except under certain conditions.
14896                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14897                        }
14898                        String adjType = null;
14899                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14900                            // Not doing bind OOM management, so treat
14901                            // this guy more like a started service.
14902                            if (app.hasShownUi && app != mHomeProcess) {
14903                                // If this process has shown some UI, let it immediately
14904                                // go to the LRU list because it may be pretty heavy with
14905                                // UI stuff.  We'll tag it with a label just to help
14906                                // debug and understand what is going on.
14907                                if (adj > clientAdj) {
14908                                    adjType = "cch-bound-ui-services";
14909                                }
14910                                app.cached = false;
14911                                clientAdj = adj;
14912                                clientProcState = procState;
14913                            } else {
14914                                if (now >= (s.lastActivity
14915                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14916                                    // This service has not seen activity within
14917                                    // recent memory, so allow it to drop to the
14918                                    // LRU list if there is no other reason to keep
14919                                    // it around.  We'll also tag it with a label just
14920                                    // to help debug and undertand what is going on.
14921                                    if (adj > clientAdj) {
14922                                        adjType = "cch-bound-services";
14923                                    }
14924                                    clientAdj = adj;
14925                                }
14926                            }
14927                        }
14928                        if (adj > clientAdj) {
14929                            // If this process has recently shown UI, and
14930                            // the process that is binding to it is less
14931                            // important than being visible, then we don't
14932                            // care about the binding as much as we care
14933                            // about letting this process get into the LRU
14934                            // list to be killed and restarted if needed for
14935                            // memory.
14936                            if (app.hasShownUi && app != mHomeProcess
14937                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14938                                adjType = "cch-bound-ui-services";
14939                            } else {
14940                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14941                                        |Context.BIND_IMPORTANT)) != 0) {
14942                                    adj = clientAdj;
14943                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14944                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14945                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14946                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14947                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
14948                                    adj = clientAdj;
14949                                } else {
14950                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14951                                        adj = ProcessList.VISIBLE_APP_ADJ;
14952                                    }
14953                                }
14954                                if (!client.cached) {
14955                                    app.cached = false;
14956                                }
14957                                if (client.keeping) {
14958                                    app.keeping = true;
14959                                }
14960                                adjType = "service";
14961                            }
14962                        }
14963                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14964                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14965                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14966                            }
14967                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14968                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14969                                    // Special handling of clients who are in the top state.
14970                                    // We *may* want to consider this process to be in the
14971                                    // top state as well, but only if there is not another
14972                                    // reason for it to be running.  Being on the top is a
14973                                    // special state, meaning you are specifically running
14974                                    // for the current top app.  If the process is already
14975                                    // running in the background for some other reason, it
14976                                    // is more important to continue considering it to be
14977                                    // in the background state.
14978                                    mayBeTop = true;
14979                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14980                                } else {
14981                                    // Special handling for above-top states (persistent
14982                                    // processes).  These should not bring the current process
14983                                    // into the top state, since they are not on top.  Instead
14984                                    // give them the best state after that.
14985                                    clientProcState =
14986                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14987                                }
14988                            }
14989                        } else {
14990                            if (clientProcState <
14991                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14992                                clientProcState =
14993                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14994                            }
14995                        }
14996                        if (procState > clientProcState) {
14997                            procState = clientProcState;
14998                        }
14999                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15000                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15001                            app.pendingUiClean = true;
15002                        }
15003                        if (adjType != null) {
15004                            app.adjType = adjType;
15005                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15006                                    .REASON_SERVICE_IN_USE;
15007                            app.adjSource = cr.binding.client;
15008                            app.adjSourceOom = clientAdj;
15009                            app.adjTarget = s.name;
15010                        }
15011                    }
15012                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15013                        app.treatLikeActivity = true;
15014                    }
15015                    final ActivityRecord a = cr.activity;
15016                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15017                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15018                                (a.visible || a.state == ActivityState.RESUMED
15019                                 || a.state == ActivityState.PAUSING)) {
15020                            adj = ProcessList.FOREGROUND_APP_ADJ;
15021                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15022                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15023                            }
15024                            app.cached = false;
15025                            app.adjType = "service";
15026                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15027                                    .REASON_SERVICE_IN_USE;
15028                            app.adjSource = a;
15029                            app.adjSourceOom = adj;
15030                            app.adjTarget = s.name;
15031                        }
15032                    }
15033                }
15034            }
15035        }
15036
15037        for (int provi = app.pubProviders.size()-1;
15038                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15039                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15040                        || procState > ActivityManager.PROCESS_STATE_TOP);
15041                provi--) {
15042            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15043            for (int i = cpr.connections.size()-1;
15044                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15045                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15046                            || procState > ActivityManager.PROCESS_STATE_TOP);
15047                    i--) {
15048                ContentProviderConnection conn = cpr.connections.get(i);
15049                ProcessRecord client = conn.client;
15050                if (client == app) {
15051                    // Being our own client is not interesting.
15052                    continue;
15053                }
15054                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15055                int clientProcState = client.curProcState;
15056                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15057                    // If the other app is cached for any reason, for purposes here
15058                    // we are going to consider it empty.
15059                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15060                }
15061                if (adj > clientAdj) {
15062                    if (app.hasShownUi && app != mHomeProcess
15063                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15064                        app.adjType = "cch-ui-provider";
15065                    } else {
15066                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15067                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15068                        app.adjType = "provider";
15069                    }
15070                    app.cached &= client.cached;
15071                    app.keeping |= client.keeping;
15072                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15073                            .REASON_PROVIDER_IN_USE;
15074                    app.adjSource = client;
15075                    app.adjSourceOom = clientAdj;
15076                    app.adjTarget = cpr.name;
15077                }
15078                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15079                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15080                        // Special handling of clients who are in the top state.
15081                        // We *may* want to consider this process to be in the
15082                        // top state as well, but only if there is not another
15083                        // reason for it to be running.  Being on the top is a
15084                        // special state, meaning you are specifically running
15085                        // for the current top app.  If the process is already
15086                        // running in the background for some other reason, it
15087                        // is more important to continue considering it to be
15088                        // in the background state.
15089                        mayBeTop = true;
15090                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15091                    } else {
15092                        // Special handling for above-top states (persistent
15093                        // processes).  These should not bring the current process
15094                        // into the top state, since they are not on top.  Instead
15095                        // give them the best state after that.
15096                        clientProcState =
15097                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15098                    }
15099                }
15100                if (procState > clientProcState) {
15101                    procState = clientProcState;
15102                }
15103                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15104                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15105                }
15106            }
15107            // If the provider has external (non-framework) process
15108            // dependencies, ensure that its adjustment is at least
15109            // FOREGROUND_APP_ADJ.
15110            if (cpr.hasExternalProcessHandles()) {
15111                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15112                    adj = ProcessList.FOREGROUND_APP_ADJ;
15113                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15114                    app.cached = false;
15115                    app.keeping = true;
15116                    app.adjType = "provider";
15117                    app.adjTarget = cpr.name;
15118                }
15119                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15120                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15121                }
15122            }
15123        }
15124
15125        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15126            // A client of one of our services or providers is in the top state.  We
15127            // *may* want to be in the top state, but not if we are already running in
15128            // the background for some other reason.  For the decision here, we are going
15129            // to pick out a few specific states that we want to remain in when a client
15130            // is top (states that tend to be longer-term) and otherwise allow it to go
15131            // to the top state.
15132            switch (procState) {
15133                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15134                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15135                case ActivityManager.PROCESS_STATE_SERVICE:
15136                    // These all are longer-term states, so pull them up to the top
15137                    // of the background states, but not all the way to the top state.
15138                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15139                    break;
15140                default:
15141                    // Otherwise, top is a better choice, so take it.
15142                    procState = ActivityManager.PROCESS_STATE_TOP;
15143                    break;
15144            }
15145        }
15146
15147        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15148            if (app.hasClientActivities) {
15149                // This is a cached process, but with client activities.  Mark it so.
15150                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15151                app.adjType = "cch-client-act";
15152            } else if (app.treatLikeActivity) {
15153                // This is a cached process, but somebody wants us to treat it like it has
15154                // an activity, okay!
15155                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15156                app.adjType = "cch-as-act";
15157            }
15158        }
15159
15160        if (adj == ProcessList.SERVICE_ADJ) {
15161            if (doingAll) {
15162                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15163                mNewNumServiceProcs++;
15164                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15165                if (!app.serviceb) {
15166                    // This service isn't far enough down on the LRU list to
15167                    // normally be a B service, but if we are low on RAM and it
15168                    // is large we want to force it down since we would prefer to
15169                    // keep launcher over it.
15170                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15171                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15172                        app.serviceHighRam = true;
15173                        app.serviceb = true;
15174                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15175                    } else {
15176                        mNewNumAServiceProcs++;
15177                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15178                    }
15179                } else {
15180                    app.serviceHighRam = false;
15181                }
15182            }
15183            if (app.serviceb) {
15184                adj = ProcessList.SERVICE_B_ADJ;
15185            }
15186        }
15187
15188        app.curRawAdj = adj;
15189
15190        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15191        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15192        if (adj > app.maxAdj) {
15193            adj = app.maxAdj;
15194            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15195                schedGroup = Process.THREAD_GROUP_DEFAULT;
15196            }
15197        }
15198        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15199            app.keeping = true;
15200        }
15201
15202        // Do final modification to adj.  Everything we do between here and applying
15203        // the final setAdj must be done in this function, because we will also use
15204        // it when computing the final cached adj later.  Note that we don't need to
15205        // worry about this for max adj above, since max adj will always be used to
15206        // keep it out of the cached vaues.
15207        app.curAdj = app.modifyRawOomAdj(adj);
15208        app.curSchedGroup = schedGroup;
15209        app.curProcState = procState;
15210        app.foregroundActivities = foregroundActivities;
15211
15212        return app.curRawAdj;
15213    }
15214
15215    /**
15216     * Schedule PSS collection of a process.
15217     */
15218    void requestPssLocked(ProcessRecord proc, int procState) {
15219        if (mPendingPssProcesses.contains(proc)) {
15220            return;
15221        }
15222        if (mPendingPssProcesses.size() == 0) {
15223            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15224        }
15225        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15226        proc.pssProcState = procState;
15227        mPendingPssProcesses.add(proc);
15228    }
15229
15230    /**
15231     * Schedule PSS collection of all processes.
15232     */
15233    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15234        if (!always) {
15235            if (now < (mLastFullPssTime +
15236                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15237                return;
15238            }
15239        }
15240        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15241        mLastFullPssTime = now;
15242        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15243        mPendingPssProcesses.clear();
15244        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15245            ProcessRecord app = mLruProcesses.get(i);
15246            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15247                app.pssProcState = app.setProcState;
15248                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15249                        isSleeping(), now);
15250                mPendingPssProcesses.add(app);
15251            }
15252        }
15253        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15254    }
15255
15256    /**
15257     * Ask a given process to GC right now.
15258     */
15259    final void performAppGcLocked(ProcessRecord app) {
15260        try {
15261            app.lastRequestedGc = SystemClock.uptimeMillis();
15262            if (app.thread != null) {
15263                if (app.reportLowMemory) {
15264                    app.reportLowMemory = false;
15265                    app.thread.scheduleLowMemory();
15266                } else {
15267                    app.thread.processInBackground();
15268                }
15269            }
15270        } catch (Exception e) {
15271            // whatever.
15272        }
15273    }
15274
15275    /**
15276     * Returns true if things are idle enough to perform GCs.
15277     */
15278    private final boolean canGcNowLocked() {
15279        boolean processingBroadcasts = false;
15280        for (BroadcastQueue q : mBroadcastQueues) {
15281            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15282                processingBroadcasts = true;
15283            }
15284        }
15285        return !processingBroadcasts
15286                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15287    }
15288
15289    /**
15290     * Perform GCs on all processes that are waiting for it, but only
15291     * if things are idle.
15292     */
15293    final void performAppGcsLocked() {
15294        final int N = mProcessesToGc.size();
15295        if (N <= 0) {
15296            return;
15297        }
15298        if (canGcNowLocked()) {
15299            while (mProcessesToGc.size() > 0) {
15300                ProcessRecord proc = mProcessesToGc.remove(0);
15301                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15302                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15303                            <= SystemClock.uptimeMillis()) {
15304                        // To avoid spamming the system, we will GC processes one
15305                        // at a time, waiting a few seconds between each.
15306                        performAppGcLocked(proc);
15307                        scheduleAppGcsLocked();
15308                        return;
15309                    } else {
15310                        // It hasn't been long enough since we last GCed this
15311                        // process...  put it in the list to wait for its time.
15312                        addProcessToGcListLocked(proc);
15313                        break;
15314                    }
15315                }
15316            }
15317
15318            scheduleAppGcsLocked();
15319        }
15320    }
15321
15322    /**
15323     * If all looks good, perform GCs on all processes waiting for them.
15324     */
15325    final void performAppGcsIfAppropriateLocked() {
15326        if (canGcNowLocked()) {
15327            performAppGcsLocked();
15328            return;
15329        }
15330        // Still not idle, wait some more.
15331        scheduleAppGcsLocked();
15332    }
15333
15334    /**
15335     * Schedule the execution of all pending app GCs.
15336     */
15337    final void scheduleAppGcsLocked() {
15338        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15339
15340        if (mProcessesToGc.size() > 0) {
15341            // Schedule a GC for the time to the next process.
15342            ProcessRecord proc = mProcessesToGc.get(0);
15343            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15344
15345            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15346            long now = SystemClock.uptimeMillis();
15347            if (when < (now+GC_TIMEOUT)) {
15348                when = now + GC_TIMEOUT;
15349            }
15350            mHandler.sendMessageAtTime(msg, when);
15351        }
15352    }
15353
15354    /**
15355     * Add a process to the array of processes waiting to be GCed.  Keeps the
15356     * list in sorted order by the last GC time.  The process can't already be
15357     * on the list.
15358     */
15359    final void addProcessToGcListLocked(ProcessRecord proc) {
15360        boolean added = false;
15361        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15362            if (mProcessesToGc.get(i).lastRequestedGc <
15363                    proc.lastRequestedGc) {
15364                added = true;
15365                mProcessesToGc.add(i+1, proc);
15366                break;
15367            }
15368        }
15369        if (!added) {
15370            mProcessesToGc.add(0, proc);
15371        }
15372    }
15373
15374    /**
15375     * Set up to ask a process to GC itself.  This will either do it
15376     * immediately, or put it on the list of processes to gc the next
15377     * time things are idle.
15378     */
15379    final void scheduleAppGcLocked(ProcessRecord app) {
15380        long now = SystemClock.uptimeMillis();
15381        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15382            return;
15383        }
15384        if (!mProcessesToGc.contains(app)) {
15385            addProcessToGcListLocked(app);
15386            scheduleAppGcsLocked();
15387        }
15388    }
15389
15390    final void checkExcessivePowerUsageLocked(boolean doKills) {
15391        updateCpuStatsNow();
15392
15393        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15394        boolean doWakeKills = doKills;
15395        boolean doCpuKills = doKills;
15396        if (mLastPowerCheckRealtime == 0) {
15397            doWakeKills = false;
15398        }
15399        if (mLastPowerCheckUptime == 0) {
15400            doCpuKills = false;
15401        }
15402        if (stats.isScreenOn()) {
15403            doWakeKills = false;
15404        }
15405        final long curRealtime = SystemClock.elapsedRealtime();
15406        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15407        final long curUptime = SystemClock.uptimeMillis();
15408        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15409        mLastPowerCheckRealtime = curRealtime;
15410        mLastPowerCheckUptime = curUptime;
15411        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15412            doWakeKills = false;
15413        }
15414        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15415            doCpuKills = false;
15416        }
15417        int i = mLruProcesses.size();
15418        while (i > 0) {
15419            i--;
15420            ProcessRecord app = mLruProcesses.get(i);
15421            if (!app.keeping) {
15422                long wtime;
15423                synchronized (stats) {
15424                    wtime = stats.getProcessWakeTime(app.info.uid,
15425                            app.pid, curRealtime);
15426                }
15427                long wtimeUsed = wtime - app.lastWakeTime;
15428                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15429                if (DEBUG_POWER) {
15430                    StringBuilder sb = new StringBuilder(128);
15431                    sb.append("Wake for ");
15432                    app.toShortString(sb);
15433                    sb.append(": over ");
15434                    TimeUtils.formatDuration(realtimeSince, sb);
15435                    sb.append(" used ");
15436                    TimeUtils.formatDuration(wtimeUsed, sb);
15437                    sb.append(" (");
15438                    sb.append((wtimeUsed*100)/realtimeSince);
15439                    sb.append("%)");
15440                    Slog.i(TAG, sb.toString());
15441                    sb.setLength(0);
15442                    sb.append("CPU for ");
15443                    app.toShortString(sb);
15444                    sb.append(": over ");
15445                    TimeUtils.formatDuration(uptimeSince, sb);
15446                    sb.append(" used ");
15447                    TimeUtils.formatDuration(cputimeUsed, sb);
15448                    sb.append(" (");
15449                    sb.append((cputimeUsed*100)/uptimeSince);
15450                    sb.append("%)");
15451                    Slog.i(TAG, sb.toString());
15452                }
15453                // If a process has held a wake lock for more
15454                // than 50% of the time during this period,
15455                // that sounds bad.  Kill!
15456                if (doWakeKills && realtimeSince > 0
15457                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15458                    synchronized (stats) {
15459                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15460                                realtimeSince, wtimeUsed);
15461                    }
15462                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15463                            + " during " + realtimeSince);
15464                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15465                } else if (doCpuKills && uptimeSince > 0
15466                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15467                    synchronized (stats) {
15468                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15469                                uptimeSince, cputimeUsed);
15470                    }
15471                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15472                            + " during " + uptimeSince);
15473                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15474                } else {
15475                    app.lastWakeTime = wtime;
15476                    app.lastCpuTime = app.curCpuTime;
15477                }
15478            }
15479        }
15480    }
15481
15482    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15483            ProcessRecord TOP_APP, boolean doingAll, long now) {
15484        boolean success = true;
15485
15486        if (app.curRawAdj != app.setRawAdj) {
15487            if (wasKeeping && !app.keeping) {
15488                // This app is no longer something we want to keep.  Note
15489                // its current wake lock time to later know to kill it if
15490                // it is not behaving well.
15491                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15492                synchronized (stats) {
15493                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15494                            app.pid, SystemClock.elapsedRealtime());
15495                }
15496                app.lastCpuTime = app.curCpuTime;
15497            }
15498
15499            app.setRawAdj = app.curRawAdj;
15500        }
15501
15502        int changes = 0;
15503
15504        if (app.curAdj != app.setAdj) {
15505            ProcessList.setOomAdj(app.pid, app.curAdj);
15506            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15507                TAG, "Set " + app.pid + " " + app.processName +
15508                " adj " + app.curAdj + ": " + app.adjType);
15509            app.setAdj = app.curAdj;
15510        }
15511
15512        if (app.setSchedGroup != app.curSchedGroup) {
15513            app.setSchedGroup = app.curSchedGroup;
15514            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15515                    "Setting process group of " + app.processName
15516                    + " to " + app.curSchedGroup);
15517            if (app.waitingToKill != null &&
15518                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15519                killUnneededProcessLocked(app, app.waitingToKill);
15520                success = false;
15521            } else {
15522                if (true) {
15523                    long oldId = Binder.clearCallingIdentity();
15524                    try {
15525                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15526                    } catch (Exception e) {
15527                        Slog.w(TAG, "Failed setting process group of " + app.pid
15528                                + " to " + app.curSchedGroup);
15529                        e.printStackTrace();
15530                    } finally {
15531                        Binder.restoreCallingIdentity(oldId);
15532                    }
15533                } else {
15534                    if (app.thread != null) {
15535                        try {
15536                            app.thread.setSchedulingGroup(app.curSchedGroup);
15537                        } catch (RemoteException e) {
15538                        }
15539                    }
15540                }
15541                Process.setSwappiness(app.pid,
15542                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15543            }
15544        }
15545        if (app.repForegroundActivities != app.foregroundActivities) {
15546            app.repForegroundActivities = app.foregroundActivities;
15547            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15548        }
15549        if (app.repProcState != app.curProcState) {
15550            app.repProcState = app.curProcState;
15551            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
15552            if (app.thread != null) {
15553                try {
15554                    if (false) {
15555                        //RuntimeException h = new RuntimeException("here");
15556                        Slog.i(TAG, "Sending new process state " + app.repProcState
15557                                + " to " + app /*, h*/);
15558                    }
15559                    app.thread.setProcessState(app.repProcState);
15560                } catch (RemoteException e) {
15561                }
15562            }
15563        }
15564        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15565                app.setProcState)) {
15566            app.lastStateTime = now;
15567            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15568                    isSleeping(), now);
15569            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15570                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15571                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15572                    + (app.nextPssTime-now) + ": " + app);
15573        } else {
15574            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15575                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15576                requestPssLocked(app, app.setProcState);
15577                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15578                        isSleeping(), now);
15579            } else if (false && DEBUG_PSS) {
15580                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15581            }
15582        }
15583        if (app.setProcState != app.curProcState) {
15584            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15585                    "Proc state change of " + app.processName
15586                    + " to " + app.curProcState);
15587            app.setProcState = app.curProcState;
15588            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15589                app.notCachedSinceIdle = false;
15590            }
15591            if (!doingAll) {
15592                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15593            } else {
15594                app.procStateChanged = true;
15595            }
15596        }
15597
15598        if (changes != 0) {
15599            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15600            int i = mPendingProcessChanges.size()-1;
15601            ProcessChangeItem item = null;
15602            while (i >= 0) {
15603                item = mPendingProcessChanges.get(i);
15604                if (item.pid == app.pid) {
15605                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15606                    break;
15607                }
15608                i--;
15609            }
15610            if (i < 0) {
15611                // No existing item in pending changes; need a new one.
15612                final int NA = mAvailProcessChanges.size();
15613                if (NA > 0) {
15614                    item = mAvailProcessChanges.remove(NA-1);
15615                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15616                } else {
15617                    item = new ProcessChangeItem();
15618                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15619                }
15620                item.changes = 0;
15621                item.pid = app.pid;
15622                item.uid = app.info.uid;
15623                if (mPendingProcessChanges.size() == 0) {
15624                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15625                            "*** Enqueueing dispatch processes changed!");
15626                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15627                }
15628                mPendingProcessChanges.add(item);
15629            }
15630            item.changes |= changes;
15631            item.processState = app.repProcState;
15632            item.foregroundActivities = app.repForegroundActivities;
15633            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
15634                    + Integer.toHexString(System.identityHashCode(item))
15635                    + " " + app.toShortString() + ": changes=" + item.changes
15636                    + " procState=" + item.processState
15637                    + " foreground=" + item.foregroundActivities
15638                    + " type=" + app.adjType + " source=" + app.adjSource
15639                    + " target=" + app.adjTarget);
15640        }
15641
15642        return success;
15643    }
15644
15645    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15646        if (proc.thread != null && proc.baseProcessTracker != null) {
15647            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15648        }
15649    }
15650
15651    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15652            ProcessRecord TOP_APP, boolean doingAll, long now) {
15653        if (app.thread == null) {
15654            return false;
15655        }
15656
15657        final boolean wasKeeping = app.keeping;
15658
15659        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15660
15661        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now);
15662    }
15663
15664    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15665            boolean oomAdj) {
15666        if (isForeground != proc.foregroundServices) {
15667            proc.foregroundServices = isForeground;
15668            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15669                    proc.info.uid);
15670            if (isForeground) {
15671                if (curProcs == null) {
15672                    curProcs = new ArrayList<ProcessRecord>();
15673                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15674                }
15675                if (!curProcs.contains(proc)) {
15676                    curProcs.add(proc);
15677                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15678                            proc.info.packageName, proc.info.uid);
15679                }
15680            } else {
15681                if (curProcs != null) {
15682                    if (curProcs.remove(proc)) {
15683                        mBatteryStatsService.noteEvent(
15684                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15685                                proc.info.packageName, proc.info.uid);
15686                        if (curProcs.size() <= 0) {
15687                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15688                        }
15689                    }
15690                }
15691            }
15692            if (oomAdj) {
15693                updateOomAdjLocked();
15694            }
15695        }
15696    }
15697
15698    private final ActivityRecord resumedAppLocked() {
15699        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15700        String pkg;
15701        int uid;
15702        if (act != null && !act.sleeping) {
15703            pkg = act.packageName;
15704            uid = act.info.applicationInfo.uid;
15705        } else {
15706            pkg = null;
15707            uid = -1;
15708        }
15709        // Has the UID or resumed package name changed?
15710        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15711                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15712            if (mCurResumedPackage != null) {
15713                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15714                        mCurResumedPackage, mCurResumedUid);
15715            }
15716            mCurResumedPackage = pkg;
15717            mCurResumedUid = uid;
15718            if (mCurResumedPackage != null) {
15719                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15720                        mCurResumedPackage, mCurResumedUid);
15721            }
15722        }
15723        return act;
15724    }
15725
15726    final boolean updateOomAdjLocked(ProcessRecord app) {
15727        final ActivityRecord TOP_ACT = resumedAppLocked();
15728        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15729        final boolean wasCached = app.cached;
15730
15731        mAdjSeq++;
15732
15733        // This is the desired cached adjusment we want to tell it to use.
15734        // If our app is currently cached, we know it, and that is it.  Otherwise,
15735        // we don't know it yet, and it needs to now be cached we will then
15736        // need to do a complete oom adj.
15737        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15738                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15739        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
15740                SystemClock.uptimeMillis());
15741        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15742            // Changed to/from cached state, so apps after it in the LRU
15743            // list may also be changed.
15744            updateOomAdjLocked();
15745        }
15746        return success;
15747    }
15748
15749    final void updateOomAdjLocked() {
15750        final ActivityRecord TOP_ACT = resumedAppLocked();
15751        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15752        final long now = SystemClock.uptimeMillis();
15753        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15754        final int N = mLruProcesses.size();
15755
15756        if (false) {
15757            RuntimeException e = new RuntimeException();
15758            e.fillInStackTrace();
15759            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15760        }
15761
15762        mAdjSeq++;
15763        mNewNumServiceProcs = 0;
15764        mNewNumAServiceProcs = 0;
15765
15766        final int emptyProcessLimit;
15767        final int cachedProcessLimit;
15768        if (mProcessLimit <= 0) {
15769            emptyProcessLimit = cachedProcessLimit = 0;
15770        } else if (mProcessLimit == 1) {
15771            emptyProcessLimit = 1;
15772            cachedProcessLimit = 0;
15773        } else {
15774            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15775            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15776        }
15777
15778        // Let's determine how many processes we have running vs.
15779        // how many slots we have for background processes; we may want
15780        // to put multiple processes in a slot of there are enough of
15781        // them.
15782        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15783                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15784        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15785        if (numEmptyProcs > cachedProcessLimit) {
15786            // If there are more empty processes than our limit on cached
15787            // processes, then use the cached process limit for the factor.
15788            // This ensures that the really old empty processes get pushed
15789            // down to the bottom, so if we are running low on memory we will
15790            // have a better chance at keeping around more cached processes
15791            // instead of a gazillion empty processes.
15792            numEmptyProcs = cachedProcessLimit;
15793        }
15794        int emptyFactor = numEmptyProcs/numSlots;
15795        if (emptyFactor < 1) emptyFactor = 1;
15796        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15797        if (cachedFactor < 1) cachedFactor = 1;
15798        int stepCached = 0;
15799        int stepEmpty = 0;
15800        int numCached = 0;
15801        int numEmpty = 0;
15802        int numTrimming = 0;
15803
15804        mNumNonCachedProcs = 0;
15805        mNumCachedHiddenProcs = 0;
15806
15807        // First update the OOM adjustment for each of the
15808        // application processes based on their current state.
15809        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15810        int nextCachedAdj = curCachedAdj+1;
15811        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15812        int nextEmptyAdj = curEmptyAdj+2;
15813        for (int i=N-1; i>=0; i--) {
15814            ProcessRecord app = mLruProcesses.get(i);
15815            if (!app.killedByAm && app.thread != null) {
15816                app.procStateChanged = false;
15817                final boolean wasKeeping = app.keeping;
15818                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15819
15820                // If we haven't yet assigned the final cached adj
15821                // to the process, do that now.
15822                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15823                    switch (app.curProcState) {
15824                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15825                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15826                            // This process is a cached process holding activities...
15827                            // assign it the next cached value for that type, and then
15828                            // step that cached level.
15829                            app.curRawAdj = curCachedAdj;
15830                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15831                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15832                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15833                                    + ")");
15834                            if (curCachedAdj != nextCachedAdj) {
15835                                stepCached++;
15836                                if (stepCached >= cachedFactor) {
15837                                    stepCached = 0;
15838                                    curCachedAdj = nextCachedAdj;
15839                                    nextCachedAdj += 2;
15840                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15841                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15842                                    }
15843                                }
15844                            }
15845                            break;
15846                        default:
15847                            // For everything else, assign next empty cached process
15848                            // level and bump that up.  Note that this means that
15849                            // long-running services that have dropped down to the
15850                            // cached level will be treated as empty (since their process
15851                            // state is still as a service), which is what we want.
15852                            app.curRawAdj = curEmptyAdj;
15853                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15854                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15855                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15856                                    + ")");
15857                            if (curEmptyAdj != nextEmptyAdj) {
15858                                stepEmpty++;
15859                                if (stepEmpty >= emptyFactor) {
15860                                    stepEmpty = 0;
15861                                    curEmptyAdj = nextEmptyAdj;
15862                                    nextEmptyAdj += 2;
15863                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15864                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15865                                    }
15866                                }
15867                            }
15868                            break;
15869                    }
15870                }
15871
15872                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now);
15873
15874                // Count the number of process types.
15875                switch (app.curProcState) {
15876                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15877                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15878                        mNumCachedHiddenProcs++;
15879                        numCached++;
15880                        if (numCached > cachedProcessLimit) {
15881                            killUnneededProcessLocked(app, "cached #" + numCached);
15882                        }
15883                        break;
15884                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15885                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15886                                && app.lastActivityTime < oldTime) {
15887                            killUnneededProcessLocked(app, "empty for "
15888                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15889                                    / 1000) + "s");
15890                        } else {
15891                            numEmpty++;
15892                            if (numEmpty > emptyProcessLimit) {
15893                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15894                            }
15895                        }
15896                        break;
15897                    default:
15898                        mNumNonCachedProcs++;
15899                        break;
15900                }
15901
15902                if (app.isolated && app.services.size() <= 0) {
15903                    // If this is an isolated process, and there are no
15904                    // services running in it, then the process is no longer
15905                    // needed.  We agressively kill these because we can by
15906                    // definition not re-use the same process again, and it is
15907                    // good to avoid having whatever code was running in them
15908                    // left sitting around after no longer needed.
15909                    killUnneededProcessLocked(app, "isolated not needed");
15910                }
15911
15912                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15913                        && !app.killedByAm) {
15914                    numTrimming++;
15915                }
15916            }
15917        }
15918
15919        mNumServiceProcs = mNewNumServiceProcs;
15920
15921        // Now determine the memory trimming level of background processes.
15922        // Unfortunately we need to start at the back of the list to do this
15923        // properly.  We only do this if the number of background apps we
15924        // are managing to keep around is less than half the maximum we desire;
15925        // if we are keeping a good number around, we'll let them use whatever
15926        // memory they want.
15927        final int numCachedAndEmpty = numCached + numEmpty;
15928        int memFactor;
15929        if (numCached <= ProcessList.TRIM_CACHED_APPS
15930                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
15931            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
15932                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
15933            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
15934                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
15935            } else {
15936                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
15937            }
15938        } else {
15939            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
15940        }
15941        // We always allow the memory level to go up (better).  We only allow it to go
15942        // down if we are in a state where that is allowed, *and* the total number of processes
15943        // has gone down since last time.
15944        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
15945                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
15946                + " last=" + mLastNumProcesses);
15947        if (memFactor > mLastMemoryLevel) {
15948            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
15949                memFactor = mLastMemoryLevel;
15950                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
15951            }
15952        }
15953        mLastMemoryLevel = memFactor;
15954        mLastNumProcesses = mLruProcesses.size();
15955        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
15956        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
15957        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
15958            if (mLowRamStartTime == 0) {
15959                mLowRamStartTime = now;
15960            }
15961            int step = 0;
15962            int fgTrimLevel;
15963            switch (memFactor) {
15964                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15965                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
15966                    break;
15967                case ProcessStats.ADJ_MEM_FACTOR_LOW:
15968                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
15969                    break;
15970                default:
15971                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
15972                    break;
15973            }
15974            int factor = numTrimming/3;
15975            int minFactor = 2;
15976            if (mHomeProcess != null) minFactor++;
15977            if (mPreviousProcess != null) minFactor++;
15978            if (factor < minFactor) factor = minFactor;
15979            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
15980            for (int i=N-1; i>=0; i--) {
15981                ProcessRecord app = mLruProcesses.get(i);
15982                if (allChanged || app.procStateChanged) {
15983                    setProcessTrackerState(app, trackerMemFactor, now);
15984                    app.procStateChanged = false;
15985                }
15986                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15987                        && !app.killedByAm) {
15988                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
15989                        try {
15990                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15991                                    "Trimming memory of " + app.processName
15992                                    + " to " + curLevel);
15993                            app.thread.scheduleTrimMemory(curLevel);
15994                        } catch (RemoteException e) {
15995                        }
15996                        if (false) {
15997                            // For now we won't do this; our memory trimming seems
15998                            // to be good enough at this point that destroying
15999                            // activities causes more harm than good.
16000                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16001                                    && app != mHomeProcess && app != mPreviousProcess) {
16002                                // Need to do this on its own message because the stack may not
16003                                // be in a consistent state at this point.
16004                                // For these apps we will also finish their activities
16005                                // to help them free memory.
16006                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16007                            }
16008                        }
16009                    }
16010                    app.trimMemoryLevel = curLevel;
16011                    step++;
16012                    if (step >= factor) {
16013                        step = 0;
16014                        switch (curLevel) {
16015                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16016                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16017                                break;
16018                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16019                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16020                                break;
16021                        }
16022                    }
16023                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16024                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16025                            && app.thread != null) {
16026                        try {
16027                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16028                                    "Trimming memory of heavy-weight " + app.processName
16029                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16030                            app.thread.scheduleTrimMemory(
16031                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16032                        } catch (RemoteException e) {
16033                        }
16034                    }
16035                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16036                } else {
16037                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16038                            || app.systemNoUi) && app.pendingUiClean) {
16039                        // If this application is now in the background and it
16040                        // had done UI, then give it the special trim level to
16041                        // have it free UI resources.
16042                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16043                        if (app.trimMemoryLevel < level && app.thread != null) {
16044                            try {
16045                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16046                                        "Trimming memory of bg-ui " + app.processName
16047                                        + " to " + level);
16048                                app.thread.scheduleTrimMemory(level);
16049                            } catch (RemoteException e) {
16050                            }
16051                        }
16052                        app.pendingUiClean = false;
16053                    }
16054                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16055                        try {
16056                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16057                                    "Trimming memory of fg " + app.processName
16058                                    + " to " + fgTrimLevel);
16059                            app.thread.scheduleTrimMemory(fgTrimLevel);
16060                        } catch (RemoteException e) {
16061                        }
16062                    }
16063                    app.trimMemoryLevel = fgTrimLevel;
16064                }
16065            }
16066        } else {
16067            if (mLowRamStartTime != 0) {
16068                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16069                mLowRamStartTime = 0;
16070            }
16071            for (int i=N-1; i>=0; i--) {
16072                ProcessRecord app = mLruProcesses.get(i);
16073                if (allChanged || app.procStateChanged) {
16074                    setProcessTrackerState(app, trackerMemFactor, now);
16075                    app.procStateChanged = false;
16076                }
16077                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16078                        || app.systemNoUi) && app.pendingUiClean) {
16079                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16080                            && app.thread != null) {
16081                        try {
16082                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16083                                    "Trimming memory of ui hidden " + app.processName
16084                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16085                            app.thread.scheduleTrimMemory(
16086                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16087                        } catch (RemoteException e) {
16088                        }
16089                    }
16090                    app.pendingUiClean = false;
16091                }
16092                app.trimMemoryLevel = 0;
16093            }
16094        }
16095
16096        if (mAlwaysFinishActivities) {
16097            // Need to do this on its own message because the stack may not
16098            // be in a consistent state at this point.
16099            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16100        }
16101
16102        if (allChanged) {
16103            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16104        }
16105
16106        if (mProcessStats.shouldWriteNowLocked(now)) {
16107            mHandler.post(new Runnable() {
16108                @Override public void run() {
16109                    synchronized (ActivityManagerService.this) {
16110                        mProcessStats.writeStateAsyncLocked();
16111                    }
16112                }
16113            });
16114        }
16115
16116        if (DEBUG_OOM_ADJ) {
16117            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16118        }
16119    }
16120
16121    final void trimApplications() {
16122        synchronized (this) {
16123            int i;
16124
16125            // First remove any unused application processes whose package
16126            // has been removed.
16127            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16128                final ProcessRecord app = mRemovedProcesses.get(i);
16129                if (app.activities.size() == 0
16130                        && app.curReceiver == null && app.services.size() == 0) {
16131                    Slog.i(
16132                        TAG, "Exiting empty application process "
16133                        + app.processName + " ("
16134                        + (app.thread != null ? app.thread.asBinder() : null)
16135                        + ")\n");
16136                    if (app.pid > 0 && app.pid != MY_PID) {
16137                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16138                                app.processName, app.setAdj, "empty");
16139                        app.killedByAm = true;
16140                        Process.killProcessQuiet(app.pid);
16141                    } else {
16142                        try {
16143                            app.thread.scheduleExit();
16144                        } catch (Exception e) {
16145                            // Ignore exceptions.
16146                        }
16147                    }
16148                    cleanUpApplicationRecordLocked(app, false, true, -1);
16149                    mRemovedProcesses.remove(i);
16150
16151                    if (app.persistent) {
16152                        if (app.persistent) {
16153                            addAppLocked(app.info, false);
16154                        }
16155                    }
16156                }
16157            }
16158
16159            // Now update the oom adj for all processes.
16160            updateOomAdjLocked();
16161        }
16162    }
16163
16164    /** This method sends the specified signal to each of the persistent apps */
16165    public void signalPersistentProcesses(int sig) throws RemoteException {
16166        if (sig != Process.SIGNAL_USR1) {
16167            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16168        }
16169
16170        synchronized (this) {
16171            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16172                    != PackageManager.PERMISSION_GRANTED) {
16173                throw new SecurityException("Requires permission "
16174                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16175            }
16176
16177            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16178                ProcessRecord r = mLruProcesses.get(i);
16179                if (r.thread != null && r.persistent) {
16180                    Process.sendSignal(r.pid, sig);
16181                }
16182            }
16183        }
16184    }
16185
16186    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16187        if (proc == null || proc == mProfileProc) {
16188            proc = mProfileProc;
16189            path = mProfileFile;
16190            profileType = mProfileType;
16191            clearProfilerLocked();
16192        }
16193        if (proc == null) {
16194            return;
16195        }
16196        try {
16197            proc.thread.profilerControl(false, path, null, profileType);
16198        } catch (RemoteException e) {
16199            throw new IllegalStateException("Process disappeared");
16200        }
16201    }
16202
16203    private void clearProfilerLocked() {
16204        if (mProfileFd != null) {
16205            try {
16206                mProfileFd.close();
16207            } catch (IOException e) {
16208            }
16209        }
16210        mProfileApp = null;
16211        mProfileProc = null;
16212        mProfileFile = null;
16213        mProfileType = 0;
16214        mAutoStopProfiler = false;
16215    }
16216
16217    public boolean profileControl(String process, int userId, boolean start,
16218            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16219
16220        try {
16221            synchronized (this) {
16222                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16223                // its own permission.
16224                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16225                        != PackageManager.PERMISSION_GRANTED) {
16226                    throw new SecurityException("Requires permission "
16227                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16228                }
16229
16230                if (start && fd == null) {
16231                    throw new IllegalArgumentException("null fd");
16232                }
16233
16234                ProcessRecord proc = null;
16235                if (process != null) {
16236                    proc = findProcessLocked(process, userId, "profileControl");
16237                }
16238
16239                if (start && (proc == null || proc.thread == null)) {
16240                    throw new IllegalArgumentException("Unknown process: " + process);
16241                }
16242
16243                if (start) {
16244                    stopProfilerLocked(null, null, 0);
16245                    setProfileApp(proc.info, proc.processName, path, fd, false);
16246                    mProfileProc = proc;
16247                    mProfileType = profileType;
16248                    try {
16249                        fd = fd.dup();
16250                    } catch (IOException e) {
16251                        fd = null;
16252                    }
16253                    proc.thread.profilerControl(start, path, fd, profileType);
16254                    fd = null;
16255                    mProfileFd = null;
16256                } else {
16257                    stopProfilerLocked(proc, path, profileType);
16258                    if (fd != null) {
16259                        try {
16260                            fd.close();
16261                        } catch (IOException e) {
16262                        }
16263                    }
16264                }
16265
16266                return true;
16267            }
16268        } catch (RemoteException e) {
16269            throw new IllegalStateException("Process disappeared");
16270        } finally {
16271            if (fd != null) {
16272                try {
16273                    fd.close();
16274                } catch (IOException e) {
16275                }
16276            }
16277        }
16278    }
16279
16280    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16281        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16282                userId, true, true, callName, null);
16283        ProcessRecord proc = null;
16284        try {
16285            int pid = Integer.parseInt(process);
16286            synchronized (mPidsSelfLocked) {
16287                proc = mPidsSelfLocked.get(pid);
16288            }
16289        } catch (NumberFormatException e) {
16290        }
16291
16292        if (proc == null) {
16293            ArrayMap<String, SparseArray<ProcessRecord>> all
16294                    = mProcessNames.getMap();
16295            SparseArray<ProcessRecord> procs = all.get(process);
16296            if (procs != null && procs.size() > 0) {
16297                proc = procs.valueAt(0);
16298                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16299                    for (int i=1; i<procs.size(); i++) {
16300                        ProcessRecord thisProc = procs.valueAt(i);
16301                        if (thisProc.userId == userId) {
16302                            proc = thisProc;
16303                            break;
16304                        }
16305                    }
16306                }
16307            }
16308        }
16309
16310        return proc;
16311    }
16312
16313    public boolean dumpHeap(String process, int userId, boolean managed,
16314            String path, ParcelFileDescriptor fd) throws RemoteException {
16315
16316        try {
16317            synchronized (this) {
16318                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16319                // its own permission (same as profileControl).
16320                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16321                        != PackageManager.PERMISSION_GRANTED) {
16322                    throw new SecurityException("Requires permission "
16323                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16324                }
16325
16326                if (fd == null) {
16327                    throw new IllegalArgumentException("null fd");
16328                }
16329
16330                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16331                if (proc == null || proc.thread == null) {
16332                    throw new IllegalArgumentException("Unknown process: " + process);
16333                }
16334
16335                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16336                if (!isDebuggable) {
16337                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16338                        throw new SecurityException("Process not debuggable: " + proc);
16339                    }
16340                }
16341
16342                proc.thread.dumpHeap(managed, path, fd);
16343                fd = null;
16344                return true;
16345            }
16346        } catch (RemoteException e) {
16347            throw new IllegalStateException("Process disappeared");
16348        } finally {
16349            if (fd != null) {
16350                try {
16351                    fd.close();
16352                } catch (IOException e) {
16353                }
16354            }
16355        }
16356    }
16357
16358    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16359    public void monitor() {
16360        synchronized (this) { }
16361    }
16362
16363    void onCoreSettingsChange(Bundle settings) {
16364        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16365            ProcessRecord processRecord = mLruProcesses.get(i);
16366            try {
16367                if (processRecord.thread != null) {
16368                    processRecord.thread.setCoreSettings(settings);
16369                }
16370            } catch (RemoteException re) {
16371                /* ignore */
16372            }
16373        }
16374    }
16375
16376    // Multi-user methods
16377
16378    /**
16379     * Start user, if its not already running, but don't bring it to foreground.
16380     */
16381    @Override
16382    public boolean startUserInBackground(final int userId) {
16383        return startUser(userId, /* foreground */ false);
16384    }
16385
16386    /**
16387     * Refreshes the list of users related to the current user when either a
16388     * user switch happens or when a new related user is started in the
16389     * background.
16390     */
16391    private void updateCurrentProfileIdsLocked() {
16392        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16393                mCurrentUserId, false /* enabledOnly */);
16394        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16395        for (int i = 0; i < currentProfileIds.length; i++) {
16396            currentProfileIds[i] = profiles.get(i).id;
16397        }
16398        mCurrentProfileIds = currentProfileIds;
16399    }
16400
16401    private Set getProfileIdsLocked(int userId) {
16402        Set userIds = new HashSet<Integer>();
16403        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16404                userId, false /* enabledOnly */);
16405        for (UserInfo user : profiles) {
16406            userIds.add(Integer.valueOf(user.id));
16407        }
16408        return userIds;
16409    }
16410
16411    @Override
16412    public boolean switchUser(final int userId) {
16413        return startUser(userId, /* foregound */ true);
16414    }
16415
16416    private boolean startUser(final int userId, boolean foreground) {
16417        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16418                != PackageManager.PERMISSION_GRANTED) {
16419            String msg = "Permission Denial: switchUser() from pid="
16420                    + Binder.getCallingPid()
16421                    + ", uid=" + Binder.getCallingUid()
16422                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16423            Slog.w(TAG, msg);
16424            throw new SecurityException(msg);
16425        }
16426
16427        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16428
16429        final long ident = Binder.clearCallingIdentity();
16430        try {
16431            synchronized (this) {
16432                final int oldUserId = mCurrentUserId;
16433                if (oldUserId == userId) {
16434                    return true;
16435                }
16436
16437                mStackSupervisor.setLockTaskModeLocked(null);
16438
16439                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16440                if (userInfo == null) {
16441                    Slog.w(TAG, "No user info for user #" + userId);
16442                    return false;
16443                }
16444
16445                if (foreground) {
16446                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16447                            R.anim.screen_user_enter);
16448                }
16449
16450                boolean needStart = false;
16451
16452                // If the user we are switching to is not currently started, then
16453                // we need to start it now.
16454                if (mStartedUsers.get(userId) == null) {
16455                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16456                    updateStartedUserArrayLocked();
16457                    needStart = true;
16458                }
16459
16460                final Integer userIdInt = Integer.valueOf(userId);
16461                mUserLru.remove(userIdInt);
16462                mUserLru.add(userIdInt);
16463
16464                if (foreground) {
16465                    mCurrentUserId = userId;
16466                    updateCurrentProfileIdsLocked();
16467                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16468                    // Once the internal notion of the active user has switched, we lock the device
16469                    // with the option to show the user switcher on the keyguard.
16470                    mWindowManager.lockNow(null);
16471                } else {
16472                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16473                    updateCurrentProfileIdsLocked();
16474                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16475                    mUserLru.remove(currentUserIdInt);
16476                    mUserLru.add(currentUserIdInt);
16477                }
16478
16479                final UserStartedState uss = mStartedUsers.get(userId);
16480
16481                // Make sure user is in the started state.  If it is currently
16482                // stopping, we need to knock that off.
16483                if (uss.mState == UserStartedState.STATE_STOPPING) {
16484                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16485                    // so we can just fairly silently bring the user back from
16486                    // the almost-dead.
16487                    uss.mState = UserStartedState.STATE_RUNNING;
16488                    updateStartedUserArrayLocked();
16489                    needStart = true;
16490                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16491                    // This means ACTION_SHUTDOWN has been sent, so we will
16492                    // need to treat this as a new boot of the user.
16493                    uss.mState = UserStartedState.STATE_BOOTING;
16494                    updateStartedUserArrayLocked();
16495                    needStart = true;
16496                }
16497
16498                if (uss.mState == UserStartedState.STATE_BOOTING) {
16499                    // Booting up a new user, need to tell system services about it.
16500                    // Note that this is on the same handler as scheduling of broadcasts,
16501                    // which is important because it needs to go first.
16502                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
16503                }
16504
16505                if (foreground) {
16506                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId));
16507                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16508                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16509                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16510                            oldUserId, userId, uss));
16511                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16512                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16513                }
16514
16515                if (needStart) {
16516                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16517                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16518                            | Intent.FLAG_RECEIVER_FOREGROUND);
16519                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16520                    broadcastIntentLocked(null, null, intent,
16521                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16522                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16523                }
16524
16525                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16526                    if (userId != 0) {
16527                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16528                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16529                        broadcastIntentLocked(null, null, intent, null,
16530                                new IIntentReceiver.Stub() {
16531                                    public void performReceive(Intent intent, int resultCode,
16532                                            String data, Bundle extras, boolean ordered,
16533                                            boolean sticky, int sendingUser) {
16534                                        userInitialized(uss, userId);
16535                                    }
16536                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16537                                true, false, MY_PID, Process.SYSTEM_UID,
16538                                userId);
16539                        uss.initializing = true;
16540                    } else {
16541                        getUserManagerLocked().makeInitialized(userInfo.id);
16542                    }
16543                }
16544
16545                if (foreground) {
16546                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16547                    if (homeInFront) {
16548                        startHomeActivityLocked(userId);
16549                    } else {
16550                        mStackSupervisor.resumeTopActivitiesLocked();
16551                    }
16552                    EventLogTags.writeAmSwitchUser(userId);
16553                    getUserManagerLocked().userForeground(userId);
16554                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16555                }
16556
16557                if (needStart) {
16558                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16559                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16560                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16561                    broadcastIntentLocked(null, null, intent,
16562                            null, new IIntentReceiver.Stub() {
16563                                @Override
16564                                public void performReceive(Intent intent, int resultCode, String data,
16565                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16566                                        throws RemoteException {
16567                                }
16568                            }, 0, null, null,
16569                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16570                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16571                }
16572            }
16573        } finally {
16574            Binder.restoreCallingIdentity(ident);
16575        }
16576
16577        return true;
16578    }
16579
16580    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16581        long ident = Binder.clearCallingIdentity();
16582        try {
16583            Intent intent;
16584            if (oldUserId >= 0) {
16585                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16586                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16587                        | Intent.FLAG_RECEIVER_FOREGROUND);
16588                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16589                broadcastIntentLocked(null, null, intent,
16590                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16591                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16592            }
16593            if (newUserId >= 0) {
16594                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16595                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16596                        | Intent.FLAG_RECEIVER_FOREGROUND);
16597                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16598                broadcastIntentLocked(null, null, intent,
16599                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16600                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16601                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16602                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16603                        | Intent.FLAG_RECEIVER_FOREGROUND);
16604                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16605                broadcastIntentLocked(null, null, intent,
16606                        null, null, 0, null, null,
16607                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16608                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16609            }
16610        } finally {
16611            Binder.restoreCallingIdentity(ident);
16612        }
16613    }
16614
16615    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16616            final int newUserId) {
16617        final int N = mUserSwitchObservers.beginBroadcast();
16618        if (N > 0) {
16619            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16620                int mCount = 0;
16621                @Override
16622                public void sendResult(Bundle data) throws RemoteException {
16623                    synchronized (ActivityManagerService.this) {
16624                        if (mCurUserSwitchCallback == this) {
16625                            mCount++;
16626                            if (mCount == N) {
16627                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16628                            }
16629                        }
16630                    }
16631                }
16632            };
16633            synchronized (this) {
16634                uss.switching = true;
16635                mCurUserSwitchCallback = callback;
16636            }
16637            for (int i=0; i<N; i++) {
16638                try {
16639                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16640                            newUserId, callback);
16641                } catch (RemoteException e) {
16642                }
16643            }
16644        } else {
16645            synchronized (this) {
16646                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16647            }
16648        }
16649        mUserSwitchObservers.finishBroadcast();
16650    }
16651
16652    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16653        synchronized (this) {
16654            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16655            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16656        }
16657    }
16658
16659    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16660        mCurUserSwitchCallback = null;
16661        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16662        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16663                oldUserId, newUserId, uss));
16664    }
16665
16666    void userInitialized(UserStartedState uss, int newUserId) {
16667        completeSwitchAndInitalize(uss, newUserId, true, false);
16668    }
16669
16670    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16671        completeSwitchAndInitalize(uss, newUserId, false, true);
16672    }
16673
16674    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16675            boolean clearInitializing, boolean clearSwitching) {
16676        boolean unfrozen = false;
16677        synchronized (this) {
16678            if (clearInitializing) {
16679                uss.initializing = false;
16680                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16681            }
16682            if (clearSwitching) {
16683                uss.switching = false;
16684            }
16685            if (!uss.switching && !uss.initializing) {
16686                mWindowManager.stopFreezingScreen();
16687                unfrozen = true;
16688            }
16689        }
16690        if (unfrozen) {
16691            final int N = mUserSwitchObservers.beginBroadcast();
16692            for (int i=0; i<N; i++) {
16693                try {
16694                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16695                } catch (RemoteException e) {
16696                }
16697            }
16698            mUserSwitchObservers.finishBroadcast();
16699        }
16700    }
16701
16702    void scheduleStartProfilesLocked() {
16703        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
16704            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
16705                    DateUtils.SECOND_IN_MILLIS);
16706        }
16707    }
16708
16709    void startProfilesLocked() {
16710        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
16711        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16712                mCurrentUserId, false /* enabledOnly */);
16713        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
16714        for (UserInfo user : profiles) {
16715            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
16716                    && user.id != mCurrentUserId) {
16717                toStart.add(user);
16718            }
16719        }
16720        final int n = toStart.size();
16721        int i = 0;
16722        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
16723            startUserInBackground(toStart.get(i).id);
16724        }
16725        if (i < n) {
16726            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
16727        }
16728    }
16729
16730    void finishUserSwitch(UserStartedState uss) {
16731        synchronized (this) {
16732            if (uss.mState == UserStartedState.STATE_BOOTING
16733                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16734                uss.mState = UserStartedState.STATE_RUNNING;
16735                final int userId = uss.mHandle.getIdentifier();
16736                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16737                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16738                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16739                broadcastIntentLocked(null, null, intent,
16740                        null, null, 0, null, null,
16741                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16742                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16743            }
16744
16745            startProfilesLocked();
16746
16747            int num = mUserLru.size();
16748            int i = 0;
16749            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16750                Integer oldUserId = mUserLru.get(i);
16751                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16752                if (oldUss == null) {
16753                    // Shouldn't happen, but be sane if it does.
16754                    mUserLru.remove(i);
16755                    num--;
16756                    continue;
16757                }
16758                if (oldUss.mState == UserStartedState.STATE_STOPPING
16759                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16760                    // This user is already stopping, doesn't count.
16761                    num--;
16762                    i++;
16763                    continue;
16764                }
16765                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16766                    // Owner and current can't be stopped, but count as running.
16767                    i++;
16768                    continue;
16769                }
16770                // This is a user to be stopped.
16771                stopUserLocked(oldUserId, null);
16772                num--;
16773                i++;
16774            }
16775        }
16776    }
16777
16778    @Override
16779    public int stopUser(final int userId, final IStopUserCallback callback) {
16780        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16781                != PackageManager.PERMISSION_GRANTED) {
16782            String msg = "Permission Denial: switchUser() from pid="
16783                    + Binder.getCallingPid()
16784                    + ", uid=" + Binder.getCallingUid()
16785                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16786            Slog.w(TAG, msg);
16787            throw new SecurityException(msg);
16788        }
16789        if (userId <= 0) {
16790            throw new IllegalArgumentException("Can't stop primary user " + userId);
16791        }
16792        synchronized (this) {
16793            return stopUserLocked(userId, callback);
16794        }
16795    }
16796
16797    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16798        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
16799        if (mCurrentUserId == userId) {
16800            return ActivityManager.USER_OP_IS_CURRENT;
16801        }
16802
16803        final UserStartedState uss = mStartedUsers.get(userId);
16804        if (uss == null) {
16805            // User is not started, nothing to do...  but we do need to
16806            // callback if requested.
16807            if (callback != null) {
16808                mHandler.post(new Runnable() {
16809                    @Override
16810                    public void run() {
16811                        try {
16812                            callback.userStopped(userId);
16813                        } catch (RemoteException e) {
16814                        }
16815                    }
16816                });
16817            }
16818            return ActivityManager.USER_OP_SUCCESS;
16819        }
16820
16821        if (callback != null) {
16822            uss.mStopCallbacks.add(callback);
16823        }
16824
16825        if (uss.mState != UserStartedState.STATE_STOPPING
16826                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16827            uss.mState = UserStartedState.STATE_STOPPING;
16828            updateStartedUserArrayLocked();
16829
16830            long ident = Binder.clearCallingIdentity();
16831            try {
16832                // We are going to broadcast ACTION_USER_STOPPING and then
16833                // once that is done send a final ACTION_SHUTDOWN and then
16834                // stop the user.
16835                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16836                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16837                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16838                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16839                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16840                // This is the result receiver for the final shutdown broadcast.
16841                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16842                    @Override
16843                    public void performReceive(Intent intent, int resultCode, String data,
16844                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16845                        finishUserStop(uss);
16846                    }
16847                };
16848                // This is the result receiver for the initial stopping broadcast.
16849                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16850                    @Override
16851                    public void performReceive(Intent intent, int resultCode, String data,
16852                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16853                        // On to the next.
16854                        synchronized (ActivityManagerService.this) {
16855                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16856                                // Whoops, we are being started back up.  Abort, abort!
16857                                return;
16858                            }
16859                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16860                        }
16861                        mSystemServiceManager.stopUser(userId);
16862                        broadcastIntentLocked(null, null, shutdownIntent,
16863                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16864                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16865                    }
16866                };
16867                // Kick things off.
16868                broadcastIntentLocked(null, null, stoppingIntent,
16869                        null, stoppingReceiver, 0, null, null,
16870                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16871                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16872            } finally {
16873                Binder.restoreCallingIdentity(ident);
16874            }
16875        }
16876
16877        return ActivityManager.USER_OP_SUCCESS;
16878    }
16879
16880    void finishUserStop(UserStartedState uss) {
16881        final int userId = uss.mHandle.getIdentifier();
16882        boolean stopped;
16883        ArrayList<IStopUserCallback> callbacks;
16884        synchronized (this) {
16885            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16886            if (mStartedUsers.get(userId) != uss) {
16887                stopped = false;
16888            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16889                stopped = false;
16890            } else {
16891                stopped = true;
16892                // User can no longer run.
16893                mStartedUsers.remove(userId);
16894                mUserLru.remove(Integer.valueOf(userId));
16895                updateStartedUserArrayLocked();
16896
16897                // Clean up all state and processes associated with the user.
16898                // Kill all the processes for the user.
16899                forceStopUserLocked(userId, "finish user");
16900            }
16901        }
16902
16903        for (int i=0; i<callbacks.size(); i++) {
16904            try {
16905                if (stopped) callbacks.get(i).userStopped(userId);
16906                else callbacks.get(i).userStopAborted(userId);
16907            } catch (RemoteException e) {
16908            }
16909        }
16910
16911        if (stopped) {
16912            mSystemServiceManager.cleanupUser(userId);
16913            synchronized (this) {
16914                mStackSupervisor.removeUserLocked(userId);
16915            }
16916        }
16917    }
16918
16919    @Override
16920    public UserInfo getCurrentUser() {
16921        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16922                != PackageManager.PERMISSION_GRANTED) && (
16923                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16924                != PackageManager.PERMISSION_GRANTED)) {
16925            String msg = "Permission Denial: getCurrentUser() from pid="
16926                    + Binder.getCallingPid()
16927                    + ", uid=" + Binder.getCallingUid()
16928                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16929            Slog.w(TAG, msg);
16930            throw new SecurityException(msg);
16931        }
16932        synchronized (this) {
16933            return getUserManagerLocked().getUserInfo(mCurrentUserId);
16934        }
16935    }
16936
16937    int getCurrentUserIdLocked() {
16938        return mCurrentUserId;
16939    }
16940
16941    @Override
16942    public boolean isUserRunning(int userId, boolean orStopped) {
16943        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16944                != PackageManager.PERMISSION_GRANTED) {
16945            String msg = "Permission Denial: isUserRunning() from pid="
16946                    + Binder.getCallingPid()
16947                    + ", uid=" + Binder.getCallingUid()
16948                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16949            Slog.w(TAG, msg);
16950            throw new SecurityException(msg);
16951        }
16952        synchronized (this) {
16953            return isUserRunningLocked(userId, orStopped);
16954        }
16955    }
16956
16957    boolean isUserRunningLocked(int userId, boolean orStopped) {
16958        UserStartedState state = mStartedUsers.get(userId);
16959        if (state == null) {
16960            return false;
16961        }
16962        if (orStopped) {
16963            return true;
16964        }
16965        return state.mState != UserStartedState.STATE_STOPPING
16966                && state.mState != UserStartedState.STATE_SHUTDOWN;
16967    }
16968
16969    @Override
16970    public int[] getRunningUserIds() {
16971        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16972                != PackageManager.PERMISSION_GRANTED) {
16973            String msg = "Permission Denial: isUserRunning() from pid="
16974                    + Binder.getCallingPid()
16975                    + ", uid=" + Binder.getCallingUid()
16976                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16977            Slog.w(TAG, msg);
16978            throw new SecurityException(msg);
16979        }
16980        synchronized (this) {
16981            return mStartedUserArray;
16982        }
16983    }
16984
16985    private void updateStartedUserArrayLocked() {
16986        int num = 0;
16987        for (int i=0; i<mStartedUsers.size();  i++) {
16988            UserStartedState uss = mStartedUsers.valueAt(i);
16989            // This list does not include stopping users.
16990            if (uss.mState != UserStartedState.STATE_STOPPING
16991                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16992                num++;
16993            }
16994        }
16995        mStartedUserArray = new int[num];
16996        num = 0;
16997        for (int i=0; i<mStartedUsers.size();  i++) {
16998            UserStartedState uss = mStartedUsers.valueAt(i);
16999            if (uss.mState != UserStartedState.STATE_STOPPING
17000                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17001                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17002                num++;
17003            }
17004        }
17005    }
17006
17007    @Override
17008    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17009        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
17010                != PackageManager.PERMISSION_GRANTED) {
17011            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17012                    + Binder.getCallingPid()
17013                    + ", uid=" + Binder.getCallingUid()
17014                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
17015            Slog.w(TAG, msg);
17016            throw new SecurityException(msg);
17017        }
17018
17019        mUserSwitchObservers.register(observer);
17020    }
17021
17022    @Override
17023    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17024        mUserSwitchObservers.unregister(observer);
17025    }
17026
17027    private boolean userExists(int userId) {
17028        if (userId == 0) {
17029            return true;
17030        }
17031        UserManagerService ums = getUserManagerLocked();
17032        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17033    }
17034
17035    int[] getUsersLocked() {
17036        UserManagerService ums = getUserManagerLocked();
17037        return ums != null ? ums.getUserIds() : new int[] { 0 };
17038    }
17039
17040    UserManagerService getUserManagerLocked() {
17041        if (mUserManager == null) {
17042            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17043            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17044        }
17045        return mUserManager;
17046    }
17047
17048    private int applyUserId(int uid, int userId) {
17049        return UserHandle.getUid(userId, uid);
17050    }
17051
17052    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17053        if (info == null) return null;
17054        ApplicationInfo newInfo = new ApplicationInfo(info);
17055        newInfo.uid = applyUserId(info.uid, userId);
17056        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17057                + info.packageName;
17058        return newInfo;
17059    }
17060
17061    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17062        if (aInfo == null
17063                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17064            return aInfo;
17065        }
17066
17067        ActivityInfo info = new ActivityInfo(aInfo);
17068        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17069        return info;
17070    }
17071
17072    private final class LocalService extends ActivityManagerInternal {
17073        @Override
17074        public void goingToSleep() {
17075            ActivityManagerService.this.goingToSleep();
17076        }
17077
17078        @Override
17079        public void wakingUp() {
17080            ActivityManagerService.this.wakingUp();
17081        }
17082    }
17083}
17084