ActivityManagerService.java revision 734983fff35d9ed2b7a9848bdfbca401887d0dd8
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.readIntAttribute;
21import static com.android.internal.util.XmlUtils.readLongAttribute;
22import static com.android.internal.util.XmlUtils.writeIntAttribute;
23import static com.android.internal.util.XmlUtils.writeLongAttribute;
24import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
25import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
26import static org.xmlpull.v1.XmlPullParser.START_TAG;
27
28import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
29
30import android.app.AppOpsManager;
31import android.app.IActivityContainer;
32import android.app.IActivityContainerCallback;
33import android.appwidget.AppWidgetManager;
34import android.graphics.Rect;
35import android.os.BatteryStats;
36import android.util.ArrayMap;
37import com.android.internal.R;
38import com.android.internal.annotations.GuardedBy;
39import com.android.internal.app.IAppOpsService;
40import com.android.internal.app.ProcessMap;
41import com.android.internal.app.ProcessStats;
42import com.android.internal.os.BackgroundThread;
43import com.android.internal.os.BatteryStatsImpl;
44import com.android.internal.os.ProcessCpuTracker;
45import com.android.internal.os.TransferPipe;
46import com.android.internal.util.FastPrintWriter;
47import com.android.internal.util.FastXmlSerializer;
48import com.android.internal.util.MemInfoReader;
49import com.android.internal.util.Preconditions;
50import com.android.server.AppOpsService;
51import com.android.server.AttributeCache;
52import com.android.server.IntentResolver;
53import com.android.server.ServiceThread;
54import com.android.server.SystemService;
55import com.android.server.Watchdog;
56import com.android.server.am.ActivityStack.ActivityState;
57import com.android.server.firewall.IntentFirewall;
58import com.android.server.pm.UserManagerService;
59import com.android.server.wm.AppTransition;
60import com.android.server.wm.WindowManagerService;
61import com.google.android.collect.Lists;
62import com.google.android.collect.Maps;
63
64import dalvik.system.Zygote;
65
66import libcore.io.IoUtils;
67
68import org.xmlpull.v1.XmlPullParser;
69import org.xmlpull.v1.XmlPullParserException;
70import org.xmlpull.v1.XmlSerializer;
71
72import android.app.Activity;
73import android.app.ActivityManager;
74import android.app.ActivityManager.RunningTaskInfo;
75import android.app.ActivityManager.StackInfo;
76import android.app.ActivityManagerNative;
77import android.app.ActivityOptions;
78import android.app.ActivityThread;
79import android.app.AlertDialog;
80import android.app.AppGlobals;
81import android.app.ApplicationErrorReport;
82import android.app.Dialog;
83import android.app.IActivityController;
84import android.app.IApplicationThread;
85import android.app.IInstrumentationWatcher;
86import android.app.INotificationManager;
87import android.app.IProcessObserver;
88import android.app.IServiceConnection;
89import android.app.IStopUserCallback;
90import android.app.IThumbnailReceiver;
91import android.app.IUiAutomationConnection;
92import android.app.IUserSwitchObserver;
93import android.app.Instrumentation;
94import android.app.Notification;
95import android.app.NotificationManager;
96import android.app.PendingIntent;
97import android.app.backup.IBackupManager;
98import android.content.ActivityNotFoundException;
99import android.content.BroadcastReceiver;
100import android.content.ClipData;
101import android.content.ComponentCallbacks2;
102import android.content.ComponentName;
103import android.content.ContentProvider;
104import android.content.ContentResolver;
105import android.content.Context;
106import android.content.DialogInterface;
107import android.content.IContentProvider;
108import android.content.IIntentReceiver;
109import android.content.IIntentSender;
110import android.content.Intent;
111import android.content.IntentFilter;
112import android.content.IntentSender;
113import android.content.pm.ActivityInfo;
114import android.content.pm.ApplicationInfo;
115import android.content.pm.ConfigurationInfo;
116import android.content.pm.IPackageDataObserver;
117import android.content.pm.IPackageManager;
118import android.content.pm.InstrumentationInfo;
119import android.content.pm.PackageInfo;
120import android.content.pm.PackageManager;
121import android.content.pm.ParceledListSlice;
122import android.content.pm.UserInfo;
123import android.content.pm.PackageManager.NameNotFoundException;
124import android.content.pm.PathPermission;
125import android.content.pm.ProviderInfo;
126import android.content.pm.ResolveInfo;
127import android.content.pm.ServiceInfo;
128import android.content.res.CompatibilityInfo;
129import android.content.res.Configuration;
130import android.graphics.Bitmap;
131import android.net.Proxy;
132import android.net.ProxyProperties;
133import android.net.Uri;
134import android.os.Binder;
135import android.os.Build;
136import android.os.Bundle;
137import android.os.Debug;
138import android.os.DropBoxManager;
139import android.os.Environment;
140import android.os.FactoryTest;
141import android.os.FileObserver;
142import android.os.FileUtils;
143import android.os.Handler;
144import android.os.IBinder;
145import android.os.IPermissionController;
146import android.os.IRemoteCallback;
147import android.os.IUserManager;
148import android.os.Looper;
149import android.os.Message;
150import android.os.Parcel;
151import android.os.ParcelFileDescriptor;
152import android.os.Process;
153import android.os.RemoteCallbackList;
154import android.os.RemoteException;
155import android.os.SELinux;
156import android.os.ServiceManager;
157import android.os.StrictMode;
158import android.os.SystemClock;
159import android.os.SystemProperties;
160import android.os.UpdateLock;
161import android.os.UserHandle;
162import android.provider.Settings;
163import android.text.format.DateUtils;
164import android.text.format.Time;
165import android.util.AtomicFile;
166import android.util.EventLog;
167import android.util.Log;
168import android.util.Pair;
169import android.util.PrintWriterPrinter;
170import android.util.Slog;
171import android.util.SparseArray;
172import android.util.TimeUtils;
173import android.util.Xml;
174import android.view.Gravity;
175import android.view.LayoutInflater;
176import android.view.View;
177import android.view.WindowManager;
178
179import java.io.BufferedInputStream;
180import java.io.BufferedOutputStream;
181import java.io.DataInputStream;
182import java.io.DataOutputStream;
183import java.io.File;
184import java.io.FileDescriptor;
185import java.io.FileInputStream;
186import java.io.FileNotFoundException;
187import java.io.FileOutputStream;
188import java.io.IOException;
189import java.io.InputStreamReader;
190import java.io.PrintWriter;
191import java.io.StringWriter;
192import java.lang.ref.WeakReference;
193import java.util.ArrayList;
194import java.util.Arrays;
195import java.util.Collections;
196import java.util.Comparator;
197import java.util.HashMap;
198import java.util.HashSet;
199import java.util.Iterator;
200import java.util.List;
201import java.util.Locale;
202import java.util.Map;
203import java.util.Set;
204import java.util.concurrent.atomic.AtomicBoolean;
205import java.util.concurrent.atomic.AtomicLong;
206
207public final class ActivityManagerService extends ActivityManagerNative
208        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
209    private static final String USER_DATA_DIR = "/data/user/";
210    static final String TAG = "ActivityManager";
211    static final String TAG_MU = "ActivityManagerServiceMU";
212    static final boolean DEBUG = false;
213    static final boolean localLOGV = DEBUG;
214    static final boolean DEBUG_BACKUP = localLOGV || false;
215    static final boolean DEBUG_BROADCAST = localLOGV || false;
216    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
217    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
218    static final boolean DEBUG_CLEANUP = localLOGV || false;
219    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
220    static final boolean DEBUG_FOCUS = false;
221    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
222    static final boolean DEBUG_MU = localLOGV || false;
223    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
224    static final boolean DEBUG_LRU = localLOGV || false;
225    static final boolean DEBUG_PAUSE = localLOGV || false;
226    static final boolean DEBUG_POWER = localLOGV || false;
227    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
228    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
229    static final boolean DEBUG_PROCESSES = localLOGV || false;
230    static final boolean DEBUG_PROVIDER = localLOGV || false;
231    static final boolean DEBUG_RESULTS = localLOGV || false;
232    static final boolean DEBUG_SERVICE = localLOGV || false;
233    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
234    static final boolean DEBUG_STACK = localLOGV || false;
235    static final boolean DEBUG_SWITCH = localLOGV || false;
236    static final boolean DEBUG_TASKS = localLOGV || false;
237    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
238    static final boolean DEBUG_TRANSITION = localLOGV || false;
239    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
240    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
241    static final boolean DEBUG_VISBILITY = localLOGV || false;
242    static final boolean DEBUG_PSS = localLOGV || false;
243    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
244    static final boolean VALIDATE_TOKENS = false;
245    static final boolean SHOW_ACTIVITY_START_TIME = true;
246
247    // Control over CPU and battery monitoring.
248    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
249    static final boolean MONITOR_CPU_USAGE = true;
250    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
251    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
252    static final boolean MONITOR_THREAD_CPU_USAGE = false;
253
254    // The flags that are set for all calls we make to the package manager.
255    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
256
257    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
258
259    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
260
261    // Maximum number of recent tasks that we can remember.
262    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20;
263
264    // Amount of time after a call to stopAppSwitches() during which we will
265    // prevent further untrusted switches from happening.
266    static final long APP_SWITCH_DELAY_TIME = 5*1000;
267
268    // How long we wait for a launched process to attach to the activity manager
269    // before we decide it's never going to come up for real.
270    static final int PROC_START_TIMEOUT = 10*1000;
271
272    // How long we wait for a launched process to attach to the activity manager
273    // before we decide it's never going to come up for real, when the process was
274    // started with a wrapper for instrumentation (such as Valgrind) because it
275    // could take much longer than usual.
276    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
277
278    // How long to wait after going idle before forcing apps to GC.
279    static final int GC_TIMEOUT = 5*1000;
280
281    // The minimum amount of time between successive GC requests for a process.
282    static final int GC_MIN_INTERVAL = 60*1000;
283
284    // The minimum amount of time between successive PSS requests for a process.
285    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
286
287    // The minimum amount of time between successive PSS requests for a process
288    // when the request is due to the memory state being lowered.
289    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
290
291    // The rate at which we check for apps using excessive power -- 15 mins.
292    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
293
294    // The minimum sample duration we will allow before deciding we have
295    // enough data on wake locks to start killing things.
296    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
297
298    // The minimum sample duration we will allow before deciding we have
299    // enough data on CPU usage to start killing things.
300    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
301
302    // How long we allow a receiver to run before giving up on it.
303    static final int BROADCAST_FG_TIMEOUT = 10*1000;
304    static final int BROADCAST_BG_TIMEOUT = 60*1000;
305
306    // How long we wait until we timeout on key dispatching.
307    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
308
309    // How long we wait until we timeout on key dispatching during instrumentation.
310    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
311
312    // Amount of time we wait for observers to handle a user switch before
313    // giving up on them and unfreezing the screen.
314    static final int USER_SWITCH_TIMEOUT = 2*1000;
315
316    // Maximum number of users we allow to be running at a time.
317    static final int MAX_RUNNING_USERS = 3;
318
319    // How long to wait in getAssistContextExtras for the activity and foreground services
320    // to respond with the result.
321    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
322
323    // Maximum number of persisted Uri grants a package is allowed
324    static final int MAX_PERSISTED_URI_GRANTS = 128;
325
326    static final int MY_PID = Process.myPid();
327
328    static final String[] EMPTY_STRING_ARRAY = new String[0];
329
330    // How many bytes to write into the dropbox log before truncating
331    static final int DROPBOX_MAX_SIZE = 256 * 1024;
332
333    /** Run all ActivityStacks through this */
334    ActivityStackSupervisor mStackSupervisor;
335
336    public IntentFirewall mIntentFirewall;
337
338    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
339    // default actuion automatically.  Important for devices without direct input
340    // devices.
341    private boolean mShowDialogs = true;
342
343    /**
344     * Description of a request to start a new activity, which has been held
345     * due to app switches being disabled.
346     */
347    static class PendingActivityLaunch {
348        final ActivityRecord r;
349        final ActivityRecord sourceRecord;
350        final int startFlags;
351        final ActivityStack stack;
352
353        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
354                int _startFlags, ActivityStack _stack) {
355            r = _r;
356            sourceRecord = _sourceRecord;
357            startFlags = _startFlags;
358            stack = _stack;
359        }
360    }
361
362    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
363            = new ArrayList<PendingActivityLaunch>();
364
365    BroadcastQueue mFgBroadcastQueue;
366    BroadcastQueue mBgBroadcastQueue;
367    // Convenient for easy iteration over the queues. Foreground is first
368    // so that dispatch of foreground broadcasts gets precedence.
369    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
370
371    BroadcastQueue broadcastQueueForIntent(Intent intent) {
372        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
373        if (DEBUG_BACKGROUND_BROADCAST) {
374            Slog.i(TAG, "Broadcast intent " + intent + " on "
375                    + (isFg ? "foreground" : "background")
376                    + " queue");
377        }
378        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
379    }
380
381    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
382        for (BroadcastQueue queue : mBroadcastQueues) {
383            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
384            if (r != null) {
385                return r;
386            }
387        }
388        return null;
389    }
390
391    /**
392     * Activity we have told the window manager to have key focus.
393     */
394    ActivityRecord mFocusedActivity = null;
395
396    /**
397     * List of intents that were used to start the most recent tasks.
398     */
399    private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
400
401    public class PendingAssistExtras extends Binder implements Runnable {
402        public final ActivityRecord activity;
403        public boolean haveResult = false;
404        public Bundle result = null;
405        public PendingAssistExtras(ActivityRecord _activity) {
406            activity = _activity;
407        }
408        @Override
409        public void run() {
410            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
411            synchronized (this) {
412                haveResult = true;
413                notifyAll();
414            }
415        }
416    }
417
418    final ArrayList<PendingAssistExtras> mPendingAssistExtras
419            = new ArrayList<PendingAssistExtras>();
420
421    /**
422     * Process management.
423     */
424    final ProcessList mProcessList = new ProcessList();
425
426    /**
427     * All of the applications we currently have running organized by name.
428     * The keys are strings of the application package name (as
429     * returned by the package manager), and the keys are ApplicationRecord
430     * objects.
431     */
432    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
433
434    /**
435     * Tracking long-term execution of processes to look for abuse and other
436     * bad app behavior.
437     */
438    final ProcessStatsService mProcessStats;
439
440    /**
441     * The currently running isolated processes.
442     */
443    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
444
445    /**
446     * Counter for assigning isolated process uids, to avoid frequently reusing the
447     * same ones.
448     */
449    int mNextIsolatedProcessUid = 0;
450
451    /**
452     * The currently running heavy-weight process, if any.
453     */
454    ProcessRecord mHeavyWeightProcess = null;
455
456    /**
457     * The last time that various processes have crashed.
458     */
459    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
460
461    /**
462     * Information about a process that is currently marked as bad.
463     */
464    static final class BadProcessInfo {
465        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
466            this.time = time;
467            this.shortMsg = shortMsg;
468            this.longMsg = longMsg;
469            this.stack = stack;
470        }
471
472        final long time;
473        final String shortMsg;
474        final String longMsg;
475        final String stack;
476    }
477
478    /**
479     * Set of applications that we consider to be bad, and will reject
480     * incoming broadcasts from (which the user has no control over).
481     * Processes are added to this set when they have crashed twice within
482     * a minimum amount of time; they are removed from it when they are
483     * later restarted (hopefully due to some user action).  The value is the
484     * time it was added to the list.
485     */
486    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
487
488    /**
489     * All of the processes we currently have running organized by pid.
490     * The keys are the pid running the application.
491     *
492     * <p>NOTE: This object is protected by its own lock, NOT the global
493     * activity manager lock!
494     */
495    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
496
497    /**
498     * All of the processes that have been forced to be foreground.  The key
499     * is the pid of the caller who requested it (we hold a death
500     * link on it).
501     */
502    abstract class ForegroundToken implements IBinder.DeathRecipient {
503        int pid;
504        IBinder token;
505    }
506    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
507
508    /**
509     * List of records for processes that someone had tried to start before the
510     * system was ready.  We don't start them at that point, but ensure they
511     * are started by the time booting is complete.
512     */
513    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
514
515    /**
516     * List of persistent applications that are in the process
517     * of being started.
518     */
519    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
520
521    /**
522     * Processes that are being forcibly torn down.
523     */
524    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
525
526    /**
527     * List of running applications, sorted by recent usage.
528     * The first entry in the list is the least recently used.
529     */
530    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
531
532    /**
533     * Where in mLruProcesses that the processes hosting activities start.
534     */
535    int mLruProcessActivityStart = 0;
536
537    /**
538     * Where in mLruProcesses that the processes hosting services start.
539     * This is after (lower index) than mLruProcessesActivityStart.
540     */
541    int mLruProcessServiceStart = 0;
542
543    /**
544     * List of processes that should gc as soon as things are idle.
545     */
546    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
547
548    /**
549     * Processes we want to collect PSS data from.
550     */
551    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
552
553    /**
554     * Last time we requested PSS data of all processes.
555     */
556    long mLastFullPssTime = SystemClock.uptimeMillis();
557
558    /**
559     * This is the process holding what we currently consider to be
560     * the "home" activity.
561     */
562    ProcessRecord mHomeProcess;
563
564    /**
565     * This is the process holding the activity the user last visited that
566     * is in a different process from the one they are currently in.
567     */
568    ProcessRecord mPreviousProcess;
569
570    /**
571     * The time at which the previous process was last visible.
572     */
573    long mPreviousProcessVisibleTime;
574
575    /**
576     * Which uses have been started, so are allowed to run code.
577     */
578    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
579
580    /**
581     * LRU list of history of current users.  Most recently current is at the end.
582     */
583    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
584
585    /**
586     * Constant array of the users that are currently started.
587     */
588    int[] mStartedUserArray = new int[] { 0 };
589
590    /**
591     * Registered observers of the user switching mechanics.
592     */
593    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
594            = new RemoteCallbackList<IUserSwitchObserver>();
595
596    /**
597     * Currently active user switch.
598     */
599    Object mCurUserSwitchCallback;
600
601    /**
602     * Packages that the user has asked to have run in screen size
603     * compatibility mode instead of filling the screen.
604     */
605    final CompatModePackages mCompatModePackages;
606
607    /**
608     * Set of IntentSenderRecord objects that are currently active.
609     */
610    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
611            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
612
613    /**
614     * Fingerprints (hashCode()) of stack traces that we've
615     * already logged DropBox entries for.  Guarded by itself.  If
616     * something (rogue user app) forces this over
617     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
618     */
619    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
620    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
621
622    /**
623     * Strict Mode background batched logging state.
624     *
625     * The string buffer is guarded by itself, and its lock is also
626     * used to determine if another batched write is already
627     * in-flight.
628     */
629    private final StringBuilder mStrictModeBuffer = new StringBuilder();
630
631    /**
632     * Keeps track of all IIntentReceivers that have been registered for
633     * broadcasts.  Hash keys are the receiver IBinder, hash value is
634     * a ReceiverList.
635     */
636    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
637            new HashMap<IBinder, ReceiverList>();
638
639    /**
640     * Resolver for broadcast intents to registered receivers.
641     * Holds BroadcastFilter (subclass of IntentFilter).
642     */
643    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
644            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
645        @Override
646        protected boolean allowFilterResult(
647                BroadcastFilter filter, List<BroadcastFilter> dest) {
648            IBinder target = filter.receiverList.receiver.asBinder();
649            for (int i=dest.size()-1; i>=0; i--) {
650                if (dest.get(i).receiverList.receiver.asBinder() == target) {
651                    return false;
652                }
653            }
654            return true;
655        }
656
657        @Override
658        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
659            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
660                    || userId == filter.owningUserId) {
661                return super.newResult(filter, match, userId);
662            }
663            return null;
664        }
665
666        @Override
667        protected BroadcastFilter[] newArray(int size) {
668            return new BroadcastFilter[size];
669        }
670
671        @Override
672        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
673            return packageName.equals(filter.packageName);
674        }
675    };
676
677    /**
678     * State of all active sticky broadcasts per user.  Keys are the action of the
679     * sticky Intent, values are an ArrayList of all broadcasted intents with
680     * that action (which should usually be one).  The SparseArray is keyed
681     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
682     * for stickies that are sent to all users.
683     */
684    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
685            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
686
687    final ActiveServices mServices;
688
689    /**
690     * Backup/restore process management
691     */
692    String mBackupAppName = null;
693    BackupRecord mBackupTarget = null;
694
695    /**
696     * List of PendingThumbnailsRecord objects of clients who are still
697     * waiting to receive all of the thumbnails for a task.
698     */
699    final ArrayList<PendingThumbnailsRecord> mPendingThumbnails =
700            new ArrayList<PendingThumbnailsRecord>();
701
702    final ProviderMap mProviderMap;
703
704    /**
705     * List of content providers who have clients waiting for them.  The
706     * application is currently being launched and the provider will be
707     * removed from this list once it is published.
708     */
709    final ArrayList<ContentProviderRecord> mLaunchingProviders
710            = new ArrayList<ContentProviderRecord>();
711
712    /**
713     * File storing persisted {@link #mGrantedUriPermissions}.
714     */
715    private final AtomicFile mGrantFile;
716
717    /** XML constants used in {@link #mGrantFile} */
718    private static final String TAG_URI_GRANTS = "uri-grants";
719    private static final String TAG_URI_GRANT = "uri-grant";
720    private static final String ATTR_USER_HANDLE = "userHandle";
721    private static final String ATTR_SOURCE_PKG = "sourcePkg";
722    private static final String ATTR_TARGET_PKG = "targetPkg";
723    private static final String ATTR_URI = "uri";
724    private static final String ATTR_MODE_FLAGS = "modeFlags";
725    private static final String ATTR_CREATED_TIME = "createdTime";
726
727    /**
728     * Global set of specific {@link Uri} permissions that have been granted.
729     * This optimized lookup structure maps from {@link UriPermission#targetUid}
730     * to {@link UriPermission#uri} to {@link UriPermission}.
731     */
732    @GuardedBy("this")
733    private final SparseArray<ArrayMap<Uri, UriPermission>>
734            mGrantedUriPermissions = new SparseArray<ArrayMap<Uri, UriPermission>>();
735
736    CoreSettingsObserver mCoreSettingsObserver;
737
738    /**
739     * Thread-local storage used to carry caller permissions over through
740     * indirect content-provider access.
741     */
742    private class Identity {
743        public int pid;
744        public int uid;
745
746        Identity(int _pid, int _uid) {
747            pid = _pid;
748            uid = _uid;
749        }
750    }
751
752    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
753
754    /**
755     * All information we have collected about the runtime performance of
756     * any user id that can impact battery performance.
757     */
758    final BatteryStatsService mBatteryStatsService;
759
760    /**
761     * Information about component usage
762     */
763    final UsageStatsService mUsageStatsService;
764
765    /**
766     * Information about and control over application operations
767     */
768    final AppOpsService mAppOpsService;
769
770    /**
771     * Current configuration information.  HistoryRecord objects are given
772     * a reference to this object to indicate which configuration they are
773     * currently running in, so this object must be kept immutable.
774     */
775    Configuration mConfiguration = new Configuration();
776
777    /**
778     * Current sequencing integer of the configuration, for skipping old
779     * configurations.
780     */
781    int mConfigurationSeq = 0;
782
783    /**
784     * Hardware-reported OpenGLES version.
785     */
786    final int GL_ES_VERSION;
787
788    /**
789     * List of initialization arguments to pass to all processes when binding applications to them.
790     * For example, references to the commonly used services.
791     */
792    HashMap<String, IBinder> mAppBindArgs;
793
794    /**
795     * Temporary to avoid allocations.  Protected by main lock.
796     */
797    final StringBuilder mStringBuilder = new StringBuilder(256);
798
799    /**
800     * Used to control how we initialize the service.
801     */
802    boolean mStartRunning = false;
803    ComponentName mTopComponent;
804    String mTopAction;
805    String mTopData;
806    boolean mProcessesReady = false;
807    boolean mSystemReady = false;
808    boolean mBooting = false;
809    boolean mWaitingUpdate = false;
810    boolean mDidUpdate = false;
811    boolean mOnBattery = false;
812    boolean mLaunchWarningShown = false;
813
814    Context mContext;
815
816    int mFactoryTest;
817
818    boolean mCheckedForSetup;
819
820    /**
821     * The time at which we will allow normal application switches again,
822     * after a call to {@link #stopAppSwitches()}.
823     */
824    long mAppSwitchesAllowedTime;
825
826    /**
827     * This is set to true after the first switch after mAppSwitchesAllowedTime
828     * is set; any switches after that will clear the time.
829     */
830    boolean mDidAppSwitch;
831
832    /**
833     * Last time (in realtime) at which we checked for power usage.
834     */
835    long mLastPowerCheckRealtime;
836
837    /**
838     * Last time (in uptime) at which we checked for power usage.
839     */
840    long mLastPowerCheckUptime;
841
842    /**
843     * Set while we are wanting to sleep, to prevent any
844     * activities from being started/resumed.
845     */
846    boolean mSleeping = false;
847
848    /**
849     * State of external calls telling us if the device is asleep.
850     */
851    boolean mWentToSleep = false;
852
853    /**
854     * State of external call telling us if the lock screen is shown.
855     */
856    boolean mLockScreenShown = false;
857
858    /**
859     * Set if we are shutting down the system, similar to sleeping.
860     */
861    boolean mShuttingDown = false;
862
863    /**
864     * Current sequence id for oom_adj computation traversal.
865     */
866    int mAdjSeq = 0;
867
868    /**
869     * Current sequence id for process LRU updating.
870     */
871    int mLruSeq = 0;
872
873    /**
874     * Keep track of the non-cached/empty process we last found, to help
875     * determine how to distribute cached/empty processes next time.
876     */
877    int mNumNonCachedProcs = 0;
878
879    /**
880     * Keep track of the number of cached hidden procs, to balance oom adj
881     * distribution between those and empty procs.
882     */
883    int mNumCachedHiddenProcs = 0;
884
885    /**
886     * Keep track of the number of service processes we last found, to
887     * determine on the next iteration which should be B services.
888     */
889    int mNumServiceProcs = 0;
890    int mNewNumAServiceProcs = 0;
891    int mNewNumServiceProcs = 0;
892
893    /**
894     * Allow the current computed overall memory level of the system to go down?
895     * This is set to false when we are killing processes for reasons other than
896     * memory management, so that the now smaller process list will not be taken as
897     * an indication that memory is tighter.
898     */
899    boolean mAllowLowerMemLevel = false;
900
901    /**
902     * The last computed memory level, for holding when we are in a state that
903     * processes are going away for other reasons.
904     */
905    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
906
907    /**
908     * The last total number of process we have, to determine if changes actually look
909     * like a shrinking number of process due to lower RAM.
910     */
911    int mLastNumProcesses;
912
913    /**
914     * The uptime of the last time we performed idle maintenance.
915     */
916    long mLastIdleTime = SystemClock.uptimeMillis();
917
918    /**
919     * Total time spent with RAM that has been added in the past since the last idle time.
920     */
921    long mLowRamTimeSinceLastIdle = 0;
922
923    /**
924     * If RAM is currently low, when that horrible situation started.
925     */
926    long mLowRamStartTime = 0;
927
928    /**
929     * For reporting to battery stats the current top application.
930     */
931    private String mCurResumedPackage = null;
932    private int mCurResumedUid = -1;
933
934    /**
935     * For reporting to battery stats the apps currently running foreground
936     * service.  The ProcessMap is package/uid tuples; each of these contain
937     * an array of the currently foreground processes.
938     */
939    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
940            = new ProcessMap<ArrayList<ProcessRecord>>();
941
942    /**
943     * This is set if we had to do a delayed dexopt of an app before launching
944     * it, to increasing the ANR timeouts in that case.
945     */
946    boolean mDidDexOpt;
947
948    String mDebugApp = null;
949    boolean mWaitForDebugger = false;
950    boolean mDebugTransient = false;
951    String mOrigDebugApp = null;
952    boolean mOrigWaitForDebugger = false;
953    boolean mAlwaysFinishActivities = false;
954    IActivityController mController = null;
955    String mProfileApp = null;
956    ProcessRecord mProfileProc = null;
957    String mProfileFile;
958    ParcelFileDescriptor mProfileFd;
959    int mProfileType = 0;
960    boolean mAutoStopProfiler = false;
961    String mOpenGlTraceApp = null;
962
963    static class ProcessChangeItem {
964        static final int CHANGE_ACTIVITIES = 1<<0;
965        static final int CHANGE_IMPORTANCE= 1<<1;
966        int changes;
967        int uid;
968        int pid;
969        int importance;
970        boolean foregroundActivities;
971    }
972
973    final RemoteCallbackList<IProcessObserver> mProcessObservers
974            = new RemoteCallbackList<IProcessObserver>();
975    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
976
977    final ArrayList<ProcessChangeItem> mPendingProcessChanges
978            = new ArrayList<ProcessChangeItem>();
979    final ArrayList<ProcessChangeItem> mAvailProcessChanges
980            = new ArrayList<ProcessChangeItem>();
981
982    /**
983     * Runtime CPU use collection thread.  This object's lock is used to
984     * protect all related state.
985     */
986    final Thread mProcessCpuThread;
987
988    /**
989     * Used to collect process stats when showing not responding dialog.
990     * Protected by mProcessCpuThread.
991     */
992    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
993            MONITOR_THREAD_CPU_USAGE);
994    final AtomicLong mLastCpuTime = new AtomicLong(0);
995    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
996
997    long mLastWriteTime = 0;
998
999    /**
1000     * Used to retain an update lock when the foreground activity is in
1001     * immersive mode.
1002     */
1003    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1004
1005    /**
1006     * Set to true after the system has finished booting.
1007     */
1008    boolean mBooted = false;
1009
1010    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1011    int mProcessLimitOverride = -1;
1012
1013    WindowManagerService mWindowManager;
1014
1015    final ActivityThread mSystemThread;
1016
1017    int mCurrentUserId = 0;
1018    int[] mRelatedUserIds = new int[0]; // Accessed by ActivityStack
1019    private UserManagerService mUserManager;
1020
1021    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1022        final ProcessRecord mApp;
1023        final int mPid;
1024        final IApplicationThread mAppThread;
1025
1026        AppDeathRecipient(ProcessRecord app, int pid,
1027                IApplicationThread thread) {
1028            if (localLOGV) Slog.v(
1029                TAG, "New death recipient " + this
1030                + " for thread " + thread.asBinder());
1031            mApp = app;
1032            mPid = pid;
1033            mAppThread = thread;
1034        }
1035
1036        @Override
1037        public void binderDied() {
1038            if (localLOGV) Slog.v(
1039                TAG, "Death received in " + this
1040                + " for thread " + mAppThread.asBinder());
1041            synchronized(ActivityManagerService.this) {
1042                appDiedLocked(mApp, mPid, mAppThread);
1043            }
1044        }
1045    }
1046
1047    static final int SHOW_ERROR_MSG = 1;
1048    static final int SHOW_NOT_RESPONDING_MSG = 2;
1049    static final int SHOW_FACTORY_ERROR_MSG = 3;
1050    static final int UPDATE_CONFIGURATION_MSG = 4;
1051    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1052    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1053    static final int SERVICE_TIMEOUT_MSG = 12;
1054    static final int UPDATE_TIME_ZONE = 13;
1055    static final int SHOW_UID_ERROR_MSG = 14;
1056    static final int IM_FEELING_LUCKY_MSG = 15;
1057    static final int PROC_START_TIMEOUT_MSG = 20;
1058    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1059    static final int KILL_APPLICATION_MSG = 22;
1060    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1061    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1062    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1063    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1064    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1065    static final int CLEAR_DNS_CACHE_MSG = 28;
1066    static final int UPDATE_HTTP_PROXY_MSG = 29;
1067    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1068    static final int DISPATCH_PROCESSES_CHANGED = 31;
1069    static final int DISPATCH_PROCESS_DIED = 32;
1070    static final int REPORT_MEM_USAGE_MSG = 33;
1071    static final int REPORT_USER_SWITCH_MSG = 34;
1072    static final int CONTINUE_USER_SWITCH_MSG = 35;
1073    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1074    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1075    static final int PERSIST_URI_GRANTS_MSG = 38;
1076    static final int REQUEST_ALL_PSS_MSG = 39;
1077    static final int START_RELATED_USERS_MSG = 40;
1078
1079    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1080    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1081    static final int FIRST_COMPAT_MODE_MSG = 300;
1082    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1083
1084    AlertDialog mUidAlert;
1085    CompatModeDialog mCompatModeDialog;
1086    long mLastMemUsageReportTime = 0;
1087
1088    /**
1089     * Flag whether the current user is a "monkey", i.e. whether
1090     * the UI is driven by a UI automation tool.
1091     */
1092    private boolean mUserIsMonkey;
1093
1094    final ServiceThread mHandlerThread;
1095    final MainHandler mHandler;
1096
1097    final class MainHandler extends Handler {
1098        public MainHandler(Looper looper) {
1099            super(looper, null, true);
1100        }
1101
1102        @Override
1103        public void handleMessage(Message msg) {
1104            switch (msg.what) {
1105            case SHOW_ERROR_MSG: {
1106                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1107                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1108                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1109                synchronized (ActivityManagerService.this) {
1110                    ProcessRecord proc = (ProcessRecord)data.get("app");
1111                    AppErrorResult res = (AppErrorResult) data.get("result");
1112                    if (proc != null && proc.crashDialog != null) {
1113                        Slog.e(TAG, "App already has crash dialog: " + proc);
1114                        if (res != null) {
1115                            res.set(0);
1116                        }
1117                        return;
1118                    }
1119                    if (!showBackground && UserHandle.getAppId(proc.uid)
1120                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1121                            && proc.pid != MY_PID) {
1122                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1123                        if (res != null) {
1124                            res.set(0);
1125                        }
1126                        return;
1127                    }
1128                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1129                        Dialog d = new AppErrorDialog(mContext,
1130                                ActivityManagerService.this, res, proc);
1131                        d.show();
1132                        proc.crashDialog = d;
1133                    } else {
1134                        // The device is asleep, so just pretend that the user
1135                        // saw a crash dialog and hit "force quit".
1136                        if (res != null) {
1137                            res.set(0);
1138                        }
1139                    }
1140                }
1141
1142                ensureBootCompleted();
1143            } break;
1144            case SHOW_NOT_RESPONDING_MSG: {
1145                synchronized (ActivityManagerService.this) {
1146                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1147                    ProcessRecord proc = (ProcessRecord)data.get("app");
1148                    if (proc != null && proc.anrDialog != null) {
1149                        Slog.e(TAG, "App already has anr dialog: " + proc);
1150                        return;
1151                    }
1152
1153                    Intent intent = new Intent("android.intent.action.ANR");
1154                    if (!mProcessesReady) {
1155                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1156                                | Intent.FLAG_RECEIVER_FOREGROUND);
1157                    }
1158                    broadcastIntentLocked(null, null, intent,
1159                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1160                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1161
1162                    if (mShowDialogs) {
1163                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1164                                mContext, proc, (ActivityRecord)data.get("activity"),
1165                                msg.arg1 != 0);
1166                        d.show();
1167                        proc.anrDialog = d;
1168                    } else {
1169                        // Just kill the app if there is no dialog to be shown.
1170                        killAppAtUsersRequest(proc, null);
1171                    }
1172                }
1173
1174                ensureBootCompleted();
1175            } break;
1176            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1177                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1178                synchronized (ActivityManagerService.this) {
1179                    ProcessRecord proc = (ProcessRecord) data.get("app");
1180                    if (proc == null) {
1181                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1182                        break;
1183                    }
1184                    if (proc.crashDialog != null) {
1185                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1186                        return;
1187                    }
1188                    AppErrorResult res = (AppErrorResult) data.get("result");
1189                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1190                        Dialog d = new StrictModeViolationDialog(mContext,
1191                                ActivityManagerService.this, res, proc);
1192                        d.show();
1193                        proc.crashDialog = d;
1194                    } else {
1195                        // The device is asleep, so just pretend that the user
1196                        // saw a crash dialog and hit "force quit".
1197                        res.set(0);
1198                    }
1199                }
1200                ensureBootCompleted();
1201            } break;
1202            case SHOW_FACTORY_ERROR_MSG: {
1203                Dialog d = new FactoryErrorDialog(
1204                    mContext, msg.getData().getCharSequence("msg"));
1205                d.show();
1206                ensureBootCompleted();
1207            } break;
1208            case UPDATE_CONFIGURATION_MSG: {
1209                final ContentResolver resolver = mContext.getContentResolver();
1210                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1211            } break;
1212            case GC_BACKGROUND_PROCESSES_MSG: {
1213                synchronized (ActivityManagerService.this) {
1214                    performAppGcsIfAppropriateLocked();
1215                }
1216            } break;
1217            case WAIT_FOR_DEBUGGER_MSG: {
1218                synchronized (ActivityManagerService.this) {
1219                    ProcessRecord app = (ProcessRecord)msg.obj;
1220                    if (msg.arg1 != 0) {
1221                        if (!app.waitedForDebugger) {
1222                            Dialog d = new AppWaitingForDebuggerDialog(
1223                                    ActivityManagerService.this,
1224                                    mContext, app);
1225                            app.waitDialog = d;
1226                            app.waitedForDebugger = true;
1227                            d.show();
1228                        }
1229                    } else {
1230                        if (app.waitDialog != null) {
1231                            app.waitDialog.dismiss();
1232                            app.waitDialog = null;
1233                        }
1234                    }
1235                }
1236            } break;
1237            case SERVICE_TIMEOUT_MSG: {
1238                if (mDidDexOpt) {
1239                    mDidDexOpt = false;
1240                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1241                    nmsg.obj = msg.obj;
1242                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1243                    return;
1244                }
1245                mServices.serviceTimeout((ProcessRecord)msg.obj);
1246            } break;
1247            case UPDATE_TIME_ZONE: {
1248                synchronized (ActivityManagerService.this) {
1249                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1250                        ProcessRecord r = mLruProcesses.get(i);
1251                        if (r.thread != null) {
1252                            try {
1253                                r.thread.updateTimeZone();
1254                            } catch (RemoteException ex) {
1255                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1256                            }
1257                        }
1258                    }
1259                }
1260            } break;
1261            case CLEAR_DNS_CACHE_MSG: {
1262                synchronized (ActivityManagerService.this) {
1263                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1264                        ProcessRecord r = mLruProcesses.get(i);
1265                        if (r.thread != null) {
1266                            try {
1267                                r.thread.clearDnsCache();
1268                            } catch (RemoteException ex) {
1269                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1270                            }
1271                        }
1272                    }
1273                }
1274            } break;
1275            case UPDATE_HTTP_PROXY_MSG: {
1276                ProxyProperties proxy = (ProxyProperties)msg.obj;
1277                String host = "";
1278                String port = "";
1279                String exclList = "";
1280                String pacFileUrl = null;
1281                if (proxy != null) {
1282                    host = proxy.getHost();
1283                    port = Integer.toString(proxy.getPort());
1284                    exclList = proxy.getExclusionList();
1285                    pacFileUrl = proxy.getPacFileUrl();
1286                }
1287                synchronized (ActivityManagerService.this) {
1288                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1289                        ProcessRecord r = mLruProcesses.get(i);
1290                        if (r.thread != null) {
1291                            try {
1292                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1293                            } catch (RemoteException ex) {
1294                                Slog.w(TAG, "Failed to update http proxy for: " +
1295                                        r.info.processName);
1296                            }
1297                        }
1298                    }
1299                }
1300            } break;
1301            case SHOW_UID_ERROR_MSG: {
1302                String title = "System UIDs Inconsistent";
1303                String text = "UIDs on the system are inconsistent, you need to wipe your"
1304                        + " data partition or your device will be unstable.";
1305                Log.e(TAG, title + ": " + text);
1306                if (mShowDialogs) {
1307                    // XXX This is a temporary dialog, no need to localize.
1308                    AlertDialog d = new BaseErrorDialog(mContext);
1309                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1310                    d.setCancelable(false);
1311                    d.setTitle(title);
1312                    d.setMessage(text);
1313                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1314                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1315                    mUidAlert = d;
1316                    d.show();
1317                }
1318            } break;
1319            case IM_FEELING_LUCKY_MSG: {
1320                if (mUidAlert != null) {
1321                    mUidAlert.dismiss();
1322                    mUidAlert = null;
1323                }
1324            } break;
1325            case PROC_START_TIMEOUT_MSG: {
1326                if (mDidDexOpt) {
1327                    mDidDexOpt = false;
1328                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1329                    nmsg.obj = msg.obj;
1330                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1331                    return;
1332                }
1333                ProcessRecord app = (ProcessRecord)msg.obj;
1334                synchronized (ActivityManagerService.this) {
1335                    processStartTimedOutLocked(app);
1336                }
1337            } break;
1338            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1339                synchronized (ActivityManagerService.this) {
1340                    doPendingActivityLaunchesLocked(true);
1341                }
1342            } break;
1343            case KILL_APPLICATION_MSG: {
1344                synchronized (ActivityManagerService.this) {
1345                    int appid = msg.arg1;
1346                    boolean restart = (msg.arg2 == 1);
1347                    Bundle bundle = (Bundle)msg.obj;
1348                    String pkg = bundle.getString("pkg");
1349                    String reason = bundle.getString("reason");
1350                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1351                            false, UserHandle.USER_ALL, reason);
1352                }
1353            } break;
1354            case FINALIZE_PENDING_INTENT_MSG: {
1355                ((PendingIntentRecord)msg.obj).completeFinalize();
1356            } break;
1357            case POST_HEAVY_NOTIFICATION_MSG: {
1358                INotificationManager inm = NotificationManager.getService();
1359                if (inm == null) {
1360                    return;
1361                }
1362
1363                ActivityRecord root = (ActivityRecord)msg.obj;
1364                ProcessRecord process = root.app;
1365                if (process == null) {
1366                    return;
1367                }
1368
1369                try {
1370                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1371                    String text = mContext.getString(R.string.heavy_weight_notification,
1372                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1373                    Notification notification = new Notification();
1374                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1375                    notification.when = 0;
1376                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1377                    notification.tickerText = text;
1378                    notification.defaults = 0; // please be quiet
1379                    notification.sound = null;
1380                    notification.vibrate = null;
1381                    notification.setLatestEventInfo(context, text,
1382                            mContext.getText(R.string.heavy_weight_notification_detail),
1383                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1384                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1385                                    new UserHandle(root.userId)));
1386
1387                    try {
1388                        int[] outId = new int[1];
1389                        inm.enqueueNotificationWithTag("android", "android", null,
1390                                R.string.heavy_weight_notification,
1391                                notification, outId, root.userId);
1392                    } catch (RuntimeException e) {
1393                        Slog.w(ActivityManagerService.TAG,
1394                                "Error showing notification for heavy-weight app", e);
1395                    } catch (RemoteException e) {
1396                    }
1397                } catch (NameNotFoundException e) {
1398                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1399                }
1400            } break;
1401            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1402                INotificationManager inm = NotificationManager.getService();
1403                if (inm == null) {
1404                    return;
1405                }
1406                try {
1407                    inm.cancelNotificationWithTag("android", null,
1408                            R.string.heavy_weight_notification,  msg.arg1);
1409                } catch (RuntimeException e) {
1410                    Slog.w(ActivityManagerService.TAG,
1411                            "Error canceling notification for service", e);
1412                } catch (RemoteException e) {
1413                }
1414            } break;
1415            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1416                synchronized (ActivityManagerService.this) {
1417                    checkExcessivePowerUsageLocked(true);
1418                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1419                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1420                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1421                }
1422            } break;
1423            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1424                synchronized (ActivityManagerService.this) {
1425                    ActivityRecord ar = (ActivityRecord)msg.obj;
1426                    if (mCompatModeDialog != null) {
1427                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1428                                ar.info.applicationInfo.packageName)) {
1429                            return;
1430                        }
1431                        mCompatModeDialog.dismiss();
1432                        mCompatModeDialog = null;
1433                    }
1434                    if (ar != null && false) {
1435                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1436                                ar.packageName)) {
1437                            int mode = mCompatModePackages.computeCompatModeLocked(
1438                                    ar.info.applicationInfo);
1439                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1440                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1441                                mCompatModeDialog = new CompatModeDialog(
1442                                        ActivityManagerService.this, mContext,
1443                                        ar.info.applicationInfo);
1444                                mCompatModeDialog.show();
1445                            }
1446                        }
1447                    }
1448                }
1449                break;
1450            }
1451            case DISPATCH_PROCESSES_CHANGED: {
1452                dispatchProcessesChanged();
1453                break;
1454            }
1455            case DISPATCH_PROCESS_DIED: {
1456                final int pid = msg.arg1;
1457                final int uid = msg.arg2;
1458                dispatchProcessDied(pid, uid);
1459                break;
1460            }
1461            case REPORT_MEM_USAGE_MSG: {
1462                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1463                Thread thread = new Thread() {
1464                    @Override public void run() {
1465                        final SparseArray<ProcessMemInfo> infoMap
1466                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1467                        for (int i=0, N=memInfos.size(); i<N; i++) {
1468                            ProcessMemInfo mi = memInfos.get(i);
1469                            infoMap.put(mi.pid, mi);
1470                        }
1471                        updateCpuStatsNow();
1472                        synchronized (mProcessCpuThread) {
1473                            final int N = mProcessCpuTracker.countStats();
1474                            for (int i=0; i<N; i++) {
1475                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1476                                if (st.vsize > 0) {
1477                                    long pss = Debug.getPss(st.pid, null);
1478                                    if (pss > 0) {
1479                                        if (infoMap.indexOfKey(st.pid) < 0) {
1480                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1481                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1482                                            mi.pss = pss;
1483                                            memInfos.add(mi);
1484                                        }
1485                                    }
1486                                }
1487                            }
1488                        }
1489
1490                        long totalPss = 0;
1491                        for (int i=0, N=memInfos.size(); i<N; i++) {
1492                            ProcessMemInfo mi = memInfos.get(i);
1493                            if (mi.pss == 0) {
1494                                mi.pss = Debug.getPss(mi.pid, null);
1495                            }
1496                            totalPss += mi.pss;
1497                        }
1498                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1499                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1500                                if (lhs.oomAdj != rhs.oomAdj) {
1501                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1502                                }
1503                                if (lhs.pss != rhs.pss) {
1504                                    return lhs.pss < rhs.pss ? 1 : -1;
1505                                }
1506                                return 0;
1507                            }
1508                        });
1509
1510                        StringBuilder tag = new StringBuilder(128);
1511                        StringBuilder stack = new StringBuilder(128);
1512                        tag.append("Low on memory -- ");
1513                        appendMemBucket(tag, totalPss, "total", false);
1514                        appendMemBucket(stack, totalPss, "total", true);
1515
1516                        StringBuilder logBuilder = new StringBuilder(1024);
1517                        logBuilder.append("Low on memory:\n");
1518
1519                        boolean firstLine = true;
1520                        int lastOomAdj = Integer.MIN_VALUE;
1521                        for (int i=0, N=memInfos.size(); i<N; i++) {
1522                            ProcessMemInfo mi = memInfos.get(i);
1523
1524                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1525                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1526                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1527                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1528                                if (lastOomAdj != mi.oomAdj) {
1529                                    lastOomAdj = mi.oomAdj;
1530                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1531                                        tag.append(" / ");
1532                                    }
1533                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1534                                        if (firstLine) {
1535                                            stack.append(":");
1536                                            firstLine = false;
1537                                        }
1538                                        stack.append("\n\t at ");
1539                                    } else {
1540                                        stack.append("$");
1541                                    }
1542                                } else {
1543                                    tag.append(" ");
1544                                    stack.append("$");
1545                                }
1546                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1547                                    appendMemBucket(tag, mi.pss, mi.name, false);
1548                                }
1549                                appendMemBucket(stack, mi.pss, mi.name, true);
1550                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1551                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1552                                    stack.append("(");
1553                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1554                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1555                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1556                                            stack.append(":");
1557                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1558                                        }
1559                                    }
1560                                    stack.append(")");
1561                                }
1562                            }
1563
1564                            logBuilder.append("  ");
1565                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1566                            logBuilder.append(' ');
1567                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1568                            logBuilder.append(' ');
1569                            ProcessList.appendRamKb(logBuilder, mi.pss);
1570                            logBuilder.append(" kB: ");
1571                            logBuilder.append(mi.name);
1572                            logBuilder.append(" (");
1573                            logBuilder.append(mi.pid);
1574                            logBuilder.append(") ");
1575                            logBuilder.append(mi.adjType);
1576                            logBuilder.append('\n');
1577                            if (mi.adjReason != null) {
1578                                logBuilder.append("                      ");
1579                                logBuilder.append(mi.adjReason);
1580                                logBuilder.append('\n');
1581                            }
1582                        }
1583
1584                        logBuilder.append("           ");
1585                        ProcessList.appendRamKb(logBuilder, totalPss);
1586                        logBuilder.append(" kB: TOTAL\n");
1587
1588                        long[] infos = new long[Debug.MEMINFO_COUNT];
1589                        Debug.getMemInfo(infos);
1590                        logBuilder.append("  MemInfo: ");
1591                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1592                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1593                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1594                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1595                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1596                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1597                            logBuilder.append("  ZRAM: ");
1598                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1599                            logBuilder.append(" kB RAM, ");
1600                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1601                            logBuilder.append(" kB swap total, ");
1602                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1603                            logBuilder.append(" kB swap free\n");
1604                        }
1605                        Slog.i(TAG, logBuilder.toString());
1606
1607                        StringBuilder dropBuilder = new StringBuilder(1024);
1608                        /*
1609                        StringWriter oomSw = new StringWriter();
1610                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1611                        StringWriter catSw = new StringWriter();
1612                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1613                        String[] emptyArgs = new String[] { };
1614                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1615                        oomPw.flush();
1616                        String oomString = oomSw.toString();
1617                        */
1618                        dropBuilder.append(stack);
1619                        dropBuilder.append('\n');
1620                        dropBuilder.append('\n');
1621                        dropBuilder.append(logBuilder);
1622                        dropBuilder.append('\n');
1623                        /*
1624                        dropBuilder.append(oomString);
1625                        dropBuilder.append('\n');
1626                        */
1627                        StringWriter catSw = new StringWriter();
1628                        synchronized (ActivityManagerService.this) {
1629                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1630                            String[] emptyArgs = new String[] { };
1631                            catPw.println();
1632                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1633                            catPw.println();
1634                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1635                                    false, false, null);
1636                            catPw.println();
1637                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1638                            catPw.flush();
1639                        }
1640                        dropBuilder.append(catSw.toString());
1641                        addErrorToDropBox("lowmem", null, "system_server", null,
1642                                null, tag.toString(), dropBuilder.toString(), null, null);
1643                        //Slog.i(TAG, "Sent to dropbox:");
1644                        //Slog.i(TAG, dropBuilder.toString());
1645                        synchronized (ActivityManagerService.this) {
1646                            long now = SystemClock.uptimeMillis();
1647                            if (mLastMemUsageReportTime < now) {
1648                                mLastMemUsageReportTime = now;
1649                            }
1650                        }
1651                    }
1652                };
1653                thread.start();
1654                break;
1655            }
1656            case REPORT_USER_SWITCH_MSG: {
1657                dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1658                break;
1659            }
1660            case CONTINUE_USER_SWITCH_MSG: {
1661                continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1662                break;
1663            }
1664            case USER_SWITCH_TIMEOUT_MSG: {
1665                timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1666                break;
1667            }
1668            case IMMERSIVE_MODE_LOCK_MSG: {
1669                final boolean nextState = (msg.arg1 != 0);
1670                if (mUpdateLock.isHeld() != nextState) {
1671                    if (DEBUG_IMMERSIVE) {
1672                        final ActivityRecord r = (ActivityRecord) msg.obj;
1673                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1674                    }
1675                    if (nextState) {
1676                        mUpdateLock.acquire();
1677                    } else {
1678                        mUpdateLock.release();
1679                    }
1680                }
1681                break;
1682            }
1683            case PERSIST_URI_GRANTS_MSG: {
1684                writeGrantedUriPermissions();
1685                break;
1686            }
1687            case REQUEST_ALL_PSS_MSG: {
1688                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1689                break;
1690            }
1691            case START_RELATED_USERS_MSG: {
1692                synchronized (ActivityManagerService.this) {
1693                    startRelatedUsersLocked();
1694                }
1695                break;
1696            }
1697            }
1698        }
1699    };
1700
1701    static final int COLLECT_PSS_BG_MSG = 1;
1702
1703    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1704        @Override
1705        public void handleMessage(Message msg) {
1706            switch (msg.what) {
1707            case COLLECT_PSS_BG_MSG: {
1708                int i=0, num=0;
1709                long start = SystemClock.uptimeMillis();
1710                long[] tmp = new long[1];
1711                do {
1712                    ProcessRecord proc;
1713                    int procState;
1714                    int pid;
1715                    synchronized (ActivityManagerService.this) {
1716                        if (i >= mPendingPssProcesses.size()) {
1717                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1718                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1719                            mPendingPssProcesses.clear();
1720                            return;
1721                        }
1722                        proc = mPendingPssProcesses.get(i);
1723                        procState = proc.pssProcState;
1724                        if (proc.thread != null && procState == proc.setProcState) {
1725                            pid = proc.pid;
1726                        } else {
1727                            proc = null;
1728                            pid = 0;
1729                        }
1730                        i++;
1731                    }
1732                    if (proc != null) {
1733                        long pss = Debug.getPss(pid, tmp);
1734                        synchronized (ActivityManagerService.this) {
1735                            if (proc.thread != null && proc.setProcState == procState
1736                                    && proc.pid == pid) {
1737                                num++;
1738                                proc.lastPssTime = SystemClock.uptimeMillis();
1739                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1740                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1741                                        + ": " + pss + " lastPss=" + proc.lastPss
1742                                        + " state=" + ProcessList.makeProcStateString(procState));
1743                                if (proc.initialIdlePss == 0) {
1744                                    proc.initialIdlePss = pss;
1745                                }
1746                                proc.lastPss = pss;
1747                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1748                                    proc.lastCachedPss = pss;
1749                                }
1750                            }
1751                        }
1752                    }
1753                } while (true);
1754            }
1755            }
1756        }
1757    };
1758
1759    public void setSystemProcess() {
1760        try {
1761            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1762            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1763            ServiceManager.addService("meminfo", new MemBinder(this));
1764            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1765            ServiceManager.addService("dbinfo", new DbBinder(this));
1766            if (MONITOR_CPU_USAGE) {
1767                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1768            }
1769            ServiceManager.addService("permission", new PermissionController(this));
1770
1771            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1772                    "android", STOCK_PM_FLAGS);
1773            mSystemThread.installSystemApplicationInfo(info);
1774
1775            synchronized (this) {
1776                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
1777                app.persistent = true;
1778                app.pid = MY_PID;
1779                app.maxAdj = ProcessList.SYSTEM_ADJ;
1780                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1781                mProcessNames.put(app.processName, app.uid, app);
1782                synchronized (mPidsSelfLocked) {
1783                    mPidsSelfLocked.put(app.pid, app);
1784                }
1785                updateLruProcessLocked(app, false, null);
1786                updateOomAdjLocked();
1787            }
1788        } catch (PackageManager.NameNotFoundException e) {
1789            throw new RuntimeException(
1790                    "Unable to find android system package", e);
1791        }
1792    }
1793
1794    public void setWindowManager(WindowManagerService wm) {
1795        mWindowManager = wm;
1796        mStackSupervisor.setWindowManager(wm);
1797    }
1798
1799    public void startObservingNativeCrashes() {
1800        final NativeCrashListener ncl = new NativeCrashListener(this);
1801        ncl.start();
1802    }
1803
1804    public IAppOpsService getAppOpsService() {
1805        return mAppOpsService;
1806    }
1807
1808    static class MemBinder extends Binder {
1809        ActivityManagerService mActivityManagerService;
1810        MemBinder(ActivityManagerService activityManagerService) {
1811            mActivityManagerService = activityManagerService;
1812        }
1813
1814        @Override
1815        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1816            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1817                    != PackageManager.PERMISSION_GRANTED) {
1818                pw.println("Permission Denial: can't dump meminfo from from pid="
1819                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1820                        + " without permission " + android.Manifest.permission.DUMP);
1821                return;
1822            }
1823
1824            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1825        }
1826    }
1827
1828    static class GraphicsBinder extends Binder {
1829        ActivityManagerService mActivityManagerService;
1830        GraphicsBinder(ActivityManagerService activityManagerService) {
1831            mActivityManagerService = activityManagerService;
1832        }
1833
1834        @Override
1835        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1836            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1837                    != PackageManager.PERMISSION_GRANTED) {
1838                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1839                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1840                        + " without permission " + android.Manifest.permission.DUMP);
1841                return;
1842            }
1843
1844            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1845        }
1846    }
1847
1848    static class DbBinder extends Binder {
1849        ActivityManagerService mActivityManagerService;
1850        DbBinder(ActivityManagerService activityManagerService) {
1851            mActivityManagerService = activityManagerService;
1852        }
1853
1854        @Override
1855        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1856            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1857                    != PackageManager.PERMISSION_GRANTED) {
1858                pw.println("Permission Denial: can't dump dbinfo from from pid="
1859                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1860                        + " without permission " + android.Manifest.permission.DUMP);
1861                return;
1862            }
1863
1864            mActivityManagerService.dumpDbInfo(fd, pw, args);
1865        }
1866    }
1867
1868    static class CpuBinder extends Binder {
1869        ActivityManagerService mActivityManagerService;
1870        CpuBinder(ActivityManagerService activityManagerService) {
1871            mActivityManagerService = activityManagerService;
1872        }
1873
1874        @Override
1875        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1876            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1877                    != PackageManager.PERMISSION_GRANTED) {
1878                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1879                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1880                        + " without permission " + android.Manifest.permission.DUMP);
1881                return;
1882            }
1883
1884            synchronized (mActivityManagerService.mProcessCpuThread) {
1885                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
1886                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
1887                        SystemClock.uptimeMillis()));
1888            }
1889        }
1890    }
1891
1892    public static final class Lifecycle extends SystemService {
1893        private final ActivityManagerService mService;
1894
1895        public Lifecycle(Context context) {
1896            super(context);
1897            mService = new ActivityManagerService(context);
1898        }
1899
1900        @Override
1901        public void onStart() {
1902            mService.start();
1903        }
1904
1905        public ActivityManagerService getService() {
1906            return mService;
1907        }
1908    }
1909
1910    // Note: This method is invoked on the main thread but may need to attach various
1911    // handlers to other threads.  So take care to be explicit about the looper.
1912    public ActivityManagerService(Context systemContext) {
1913        mContext = systemContext;
1914        mFactoryTest = FactoryTest.getMode();
1915        mSystemThread = ActivityThread.currentActivityThread();
1916
1917        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1918
1919        mHandlerThread = new ServiceThread(TAG,
1920                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
1921        mHandlerThread.start();
1922        mHandler = new MainHandler(mHandlerThread.getLooper());
1923
1924        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
1925                "foreground", BROADCAST_FG_TIMEOUT, false);
1926        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
1927                "background", BROADCAST_BG_TIMEOUT, true);
1928        mBroadcastQueues[0] = mFgBroadcastQueue;
1929        mBroadcastQueues[1] = mBgBroadcastQueue;
1930
1931        mServices = new ActiveServices(this);
1932        mProviderMap = new ProviderMap(this);
1933
1934        // TODO: Move creation of battery stats service outside of activity manager service.
1935        File dataDir = Environment.getDataDirectory();
1936        File systemDir = new File(dataDir, "system");
1937        systemDir.mkdirs();
1938        mBatteryStatsService = new BatteryStatsService(new File(
1939                systemDir, "batterystats.bin").toString(), mHandler);
1940        mBatteryStatsService.getActiveStatistics().readLocked();
1941        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1942        mOnBattery = DEBUG_POWER ? true
1943                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1944        mBatteryStatsService.getActiveStatistics().setCallback(this);
1945
1946        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
1947
1948        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
1949        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
1950
1951        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
1952
1953        // User 0 is the first and only user that runs at boot.
1954        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
1955        mUserLru.add(Integer.valueOf(0));
1956        updateStartedUserArrayLocked();
1957
1958        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1959            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1960
1961        mConfiguration.setToDefaults();
1962        mConfiguration.setLocale(Locale.getDefault());
1963
1964        mConfigurationSeq = mConfiguration.seq = 1;
1965        mProcessCpuTracker.init();
1966
1967        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
1968        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
1969        mStackSupervisor = new ActivityStackSupervisor(this);
1970
1971        mProcessCpuThread = new Thread("CpuTracker") {
1972            @Override
1973            public void run() {
1974                while (true) {
1975                    try {
1976                        try {
1977                            synchronized(this) {
1978                                final long now = SystemClock.uptimeMillis();
1979                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1980                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1981                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1982                                //        + ", write delay=" + nextWriteDelay);
1983                                if (nextWriteDelay < nextCpuDelay) {
1984                                    nextCpuDelay = nextWriteDelay;
1985                                }
1986                                if (nextCpuDelay > 0) {
1987                                    mProcessCpuMutexFree.set(true);
1988                                    this.wait(nextCpuDelay);
1989                                }
1990                            }
1991                        } catch (InterruptedException e) {
1992                        }
1993                        updateCpuStatsNow();
1994                    } catch (Exception e) {
1995                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
1996                    }
1997                }
1998            }
1999        };
2000
2001        Watchdog.getInstance().addMonitor(this);
2002        Watchdog.getInstance().addThread(mHandler);
2003    }
2004
2005    private void start() {
2006        mProcessCpuThread.start();
2007
2008        mBatteryStatsService.publish(mContext);
2009        mUsageStatsService.publish(mContext);
2010        mAppOpsService.publish(mContext);
2011        startRunning(null, null, null, null);
2012    }
2013
2014    @Override
2015    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2016            throws RemoteException {
2017        if (code == SYSPROPS_TRANSACTION) {
2018            // We need to tell all apps about the system property change.
2019            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2020            synchronized(this) {
2021                final int NP = mProcessNames.getMap().size();
2022                for (int ip=0; ip<NP; ip++) {
2023                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2024                    final int NA = apps.size();
2025                    for (int ia=0; ia<NA; ia++) {
2026                        ProcessRecord app = apps.valueAt(ia);
2027                        if (app.thread != null) {
2028                            procs.add(app.thread.asBinder());
2029                        }
2030                    }
2031                }
2032            }
2033
2034            int N = procs.size();
2035            for (int i=0; i<N; i++) {
2036                Parcel data2 = Parcel.obtain();
2037                try {
2038                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2039                } catch (RemoteException e) {
2040                }
2041                data2.recycle();
2042            }
2043        }
2044        try {
2045            return super.onTransact(code, data, reply, flags);
2046        } catch (RuntimeException e) {
2047            // The activity manager only throws security exceptions, so let's
2048            // log all others.
2049            if (!(e instanceof SecurityException)) {
2050                Slog.wtf(TAG, "Activity Manager Crash", e);
2051            }
2052            throw e;
2053        }
2054    }
2055
2056    void updateCpuStats() {
2057        final long now = SystemClock.uptimeMillis();
2058        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2059            return;
2060        }
2061        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2062            synchronized (mProcessCpuThread) {
2063                mProcessCpuThread.notify();
2064            }
2065        }
2066    }
2067
2068    void updateCpuStatsNow() {
2069        synchronized (mProcessCpuThread) {
2070            mProcessCpuMutexFree.set(false);
2071            final long now = SystemClock.uptimeMillis();
2072            boolean haveNewCpuStats = false;
2073
2074            if (MONITOR_CPU_USAGE &&
2075                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2076                mLastCpuTime.set(now);
2077                haveNewCpuStats = true;
2078                mProcessCpuTracker.update();
2079                //Slog.i(TAG, mProcessCpu.printCurrentState());
2080                //Slog.i(TAG, "Total CPU usage: "
2081                //        + mProcessCpu.getTotalCpuPercent() + "%");
2082
2083                // Slog the cpu usage if the property is set.
2084                if ("true".equals(SystemProperties.get("events.cpu"))) {
2085                    int user = mProcessCpuTracker.getLastUserTime();
2086                    int system = mProcessCpuTracker.getLastSystemTime();
2087                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2088                    int irq = mProcessCpuTracker.getLastIrqTime();
2089                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2090                    int idle = mProcessCpuTracker.getLastIdleTime();
2091
2092                    int total = user + system + iowait + irq + softIrq + idle;
2093                    if (total == 0) total = 1;
2094
2095                    EventLog.writeEvent(EventLogTags.CPU,
2096                            ((user+system+iowait+irq+softIrq) * 100) / total,
2097                            (user * 100) / total,
2098                            (system * 100) / total,
2099                            (iowait * 100) / total,
2100                            (irq * 100) / total,
2101                            (softIrq * 100) / total);
2102                }
2103            }
2104
2105            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2106            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2107            synchronized(bstats) {
2108                synchronized(mPidsSelfLocked) {
2109                    if (haveNewCpuStats) {
2110                        if (mOnBattery) {
2111                            int perc = bstats.startAddingCpuLocked();
2112                            int totalUTime = 0;
2113                            int totalSTime = 0;
2114                            final int N = mProcessCpuTracker.countStats();
2115                            for (int i=0; i<N; i++) {
2116                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2117                                if (!st.working) {
2118                                    continue;
2119                                }
2120                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2121                                int otherUTime = (st.rel_utime*perc)/100;
2122                                int otherSTime = (st.rel_stime*perc)/100;
2123                                totalUTime += otherUTime;
2124                                totalSTime += otherSTime;
2125                                if (pr != null) {
2126                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2127                                    if (ps == null || !ps.isActive()) {
2128                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2129                                                pr.info.uid, pr.processName);
2130                                    }
2131                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2132                                            st.rel_stime-otherSTime);
2133                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2134                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2135                                } else {
2136                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2137                                    if (ps == null || !ps.isActive()) {
2138                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2139                                                bstats.mapUid(st.uid), st.name);
2140                                    }
2141                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2142                                            st.rel_stime-otherSTime);
2143                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2144                                }
2145                            }
2146                            bstats.finishAddingCpuLocked(perc, totalUTime,
2147                                    totalSTime, cpuSpeedTimes);
2148                        }
2149                    }
2150                }
2151
2152                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2153                    mLastWriteTime = now;
2154                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2155                }
2156            }
2157        }
2158    }
2159
2160    @Override
2161    public void batteryNeedsCpuUpdate() {
2162        updateCpuStatsNow();
2163    }
2164
2165    @Override
2166    public void batteryPowerChanged(boolean onBattery) {
2167        // When plugging in, update the CPU stats first before changing
2168        // the plug state.
2169        updateCpuStatsNow();
2170        synchronized (this) {
2171            synchronized(mPidsSelfLocked) {
2172                mOnBattery = DEBUG_POWER ? true : onBattery;
2173            }
2174        }
2175    }
2176
2177    /**
2178     * Initialize the application bind args. These are passed to each
2179     * process when the bindApplication() IPC is sent to the process. They're
2180     * lazily setup to make sure the services are running when they're asked for.
2181     */
2182    private HashMap<String, IBinder> getCommonServicesLocked() {
2183        if (mAppBindArgs == null) {
2184            mAppBindArgs = new HashMap<String, IBinder>();
2185
2186            // Setup the application init args
2187            mAppBindArgs.put("package", ServiceManager.getService("package"));
2188            mAppBindArgs.put("window", ServiceManager.getService("window"));
2189            mAppBindArgs.put(Context.ALARM_SERVICE,
2190                    ServiceManager.getService(Context.ALARM_SERVICE));
2191        }
2192        return mAppBindArgs;
2193    }
2194
2195    final void setFocusedActivityLocked(ActivityRecord r) {
2196        if (mFocusedActivity != r) {
2197            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2198            mFocusedActivity = r;
2199            mStackSupervisor.setFocusedStack(r);
2200            if (r != null) {
2201                mWindowManager.setFocusedApp(r.appToken, true);
2202            }
2203            applyUpdateLockStateLocked(r);
2204        }
2205    }
2206
2207    @Override
2208    public void setFocusedStack(int stackId) {
2209        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2210        synchronized (ActivityManagerService.this) {
2211            ActivityStack stack = mStackSupervisor.getStack(stackId);
2212            if (stack != null) {
2213                ActivityRecord r = stack.topRunningActivityLocked(null);
2214                if (r != null) {
2215                    setFocusedActivityLocked(r);
2216                }
2217            }
2218        }
2219    }
2220
2221    @Override
2222    public void notifyActivityDrawn(IBinder token) {
2223        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2224        synchronized (this) {
2225            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2226            if (r != null) {
2227                r.task.stack.notifyActivityDrawnLocked(r);
2228            }
2229        }
2230    }
2231
2232    final void applyUpdateLockStateLocked(ActivityRecord r) {
2233        // Modifications to the UpdateLock state are done on our handler, outside
2234        // the activity manager's locks.  The new state is determined based on the
2235        // state *now* of the relevant activity record.  The object is passed to
2236        // the handler solely for logging detail, not to be consulted/modified.
2237        final boolean nextState = r != null && r.immersive;
2238        mHandler.sendMessage(
2239                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2240    }
2241
2242    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2243        Message msg = Message.obtain();
2244        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2245        msg.obj = r.task.askedCompatMode ? null : r;
2246        mHandler.sendMessage(msg);
2247    }
2248
2249    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2250            String what, Object obj, ProcessRecord srcApp) {
2251        app.lastActivityTime = now;
2252
2253        if (app.activities.size() > 0) {
2254            // Don't want to touch dependent processes that are hosting activities.
2255            return index;
2256        }
2257
2258        int lrui = mLruProcesses.lastIndexOf(app);
2259        if (lrui < 0) {
2260            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2261                    + what + " " + obj + " from " + srcApp);
2262            return index;
2263        }
2264
2265        if (lrui >= index) {
2266            // Don't want to cause this to move dependent processes *back* in the
2267            // list as if they were less frequently used.
2268            return index;
2269        }
2270
2271        if (lrui >= mLruProcessActivityStart) {
2272            // Don't want to touch dependent processes that are hosting activities.
2273            return index;
2274        }
2275
2276        mLruProcesses.remove(lrui);
2277        if (index > 0) {
2278            index--;
2279        }
2280        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2281                + " in LRU list: " + app);
2282        mLruProcesses.add(index, app);
2283        return index;
2284    }
2285
2286    final void removeLruProcessLocked(ProcessRecord app) {
2287        int lrui = mLruProcesses.lastIndexOf(app);
2288        if (lrui >= 0) {
2289            if (lrui <= mLruProcessActivityStart) {
2290                mLruProcessActivityStart--;
2291            }
2292            if (lrui <= mLruProcessServiceStart) {
2293                mLruProcessServiceStart--;
2294            }
2295            mLruProcesses.remove(lrui);
2296        }
2297    }
2298
2299    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2300            ProcessRecord client) {
2301        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities;
2302        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2303        if (!activityChange && hasActivity) {
2304            // The process has activties, so we are only going to allow activity-based
2305            // adjustments move it.  It should be kept in the front of the list with other
2306            // processes that have activities, and we don't want those to change their
2307            // order except due to activity operations.
2308            return;
2309        }
2310
2311        mLruSeq++;
2312        final long now = SystemClock.uptimeMillis();
2313        app.lastActivityTime = now;
2314
2315        // First a quick reject: if the app is already at the position we will
2316        // put it, then there is nothing to do.
2317        if (hasActivity) {
2318            final int N = mLruProcesses.size();
2319            if (N > 0 && mLruProcesses.get(N-1) == app) {
2320                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2321                return;
2322            }
2323        } else {
2324            if (mLruProcessServiceStart > 0
2325                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2326                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2327                return;
2328            }
2329        }
2330
2331        int lrui = mLruProcesses.lastIndexOf(app);
2332
2333        if (app.persistent && lrui >= 0) {
2334            // We don't care about the position of persistent processes, as long as
2335            // they are in the list.
2336            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2337            return;
2338        }
2339
2340        /* In progress: compute new position first, so we can avoid doing work
2341           if the process is not actually going to move.  Not yet working.
2342        int addIndex;
2343        int nextIndex;
2344        boolean inActivity = false, inService = false;
2345        if (hasActivity) {
2346            // Process has activities, put it at the very tipsy-top.
2347            addIndex = mLruProcesses.size();
2348            nextIndex = mLruProcessServiceStart;
2349            inActivity = true;
2350        } else if (hasService) {
2351            // Process has services, put it at the top of the service list.
2352            addIndex = mLruProcessActivityStart;
2353            nextIndex = mLruProcessServiceStart;
2354            inActivity = true;
2355            inService = true;
2356        } else  {
2357            // Process not otherwise of interest, it goes to the top of the non-service area.
2358            addIndex = mLruProcessServiceStart;
2359            if (client != null) {
2360                int clientIndex = mLruProcesses.lastIndexOf(client);
2361                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2362                        + app);
2363                if (clientIndex >= 0 && addIndex > clientIndex) {
2364                    addIndex = clientIndex;
2365                }
2366            }
2367            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2368        }
2369
2370        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2371                + mLruProcessActivityStart + "): " + app);
2372        */
2373
2374        if (lrui >= 0) {
2375            if (lrui < mLruProcessActivityStart) {
2376                mLruProcessActivityStart--;
2377            }
2378            if (lrui < mLruProcessServiceStart) {
2379                mLruProcessServiceStart--;
2380            }
2381            /*
2382            if (addIndex > lrui) {
2383                addIndex--;
2384            }
2385            if (nextIndex > lrui) {
2386                nextIndex--;
2387            }
2388            */
2389            mLruProcesses.remove(lrui);
2390        }
2391
2392        /*
2393        mLruProcesses.add(addIndex, app);
2394        if (inActivity) {
2395            mLruProcessActivityStart++;
2396        }
2397        if (inService) {
2398            mLruProcessActivityStart++;
2399        }
2400        */
2401
2402        int nextIndex;
2403        if (hasActivity) {
2404            final int N = mLruProcesses.size();
2405            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2406                // Process doesn't have activities, but has clients with
2407                // activities...  move it up, but one below the top (the top
2408                // should always have a real activity).
2409                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2410                mLruProcesses.add(N-1, app);
2411                // To keep it from spamming the LRU list (by making a bunch of clients),
2412                // we will push down any other entries owned by the app.
2413                final int uid = app.info.uid;
2414                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2415                    ProcessRecord subProc = mLruProcesses.get(i);
2416                    if (subProc.info.uid == uid) {
2417                        // We want to push this one down the list.  If the process after
2418                        // it is for the same uid, however, don't do so, because we don't
2419                        // want them internally to be re-ordered.
2420                        if (mLruProcesses.get(i-1).info.uid != uid) {
2421                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2422                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2423                            ProcessRecord tmp = mLruProcesses.get(i);
2424                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2425                            mLruProcesses.set(i-1, tmp);
2426                            i--;
2427                        }
2428                    } else {
2429                        // A gap, we can stop here.
2430                        break;
2431                    }
2432                }
2433            } else {
2434                // Process has activities, put it at the very tipsy-top.
2435                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2436                mLruProcesses.add(app);
2437            }
2438            nextIndex = mLruProcessServiceStart;
2439        } else if (hasService) {
2440            // Process has services, put it at the top of the service list.
2441            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2442            mLruProcesses.add(mLruProcessActivityStart, app);
2443            nextIndex = mLruProcessServiceStart;
2444            mLruProcessActivityStart++;
2445        } else  {
2446            // Process not otherwise of interest, it goes to the top of the non-service area.
2447            int index = mLruProcessServiceStart;
2448            if (client != null) {
2449                // If there is a client, don't allow the process to be moved up higher
2450                // in the list than that client.
2451                int clientIndex = mLruProcesses.lastIndexOf(client);
2452                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2453                        + " when updating " + app);
2454                if (clientIndex <= lrui) {
2455                    // Don't allow the client index restriction to push it down farther in the
2456                    // list than it already is.
2457                    clientIndex = lrui;
2458                }
2459                if (clientIndex >= 0 && index > clientIndex) {
2460                    index = clientIndex;
2461                }
2462            }
2463            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2464            mLruProcesses.add(index, app);
2465            nextIndex = index-1;
2466            mLruProcessActivityStart++;
2467            mLruProcessServiceStart++;
2468        }
2469
2470        // If the app is currently using a content provider or service,
2471        // bump those processes as well.
2472        for (int j=app.connections.size()-1; j>=0; j--) {
2473            ConnectionRecord cr = app.connections.valueAt(j);
2474            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2475                    && cr.binding.service.app != null
2476                    && cr.binding.service.app.lruSeq != mLruSeq
2477                    && !cr.binding.service.app.persistent) {
2478                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2479                        "service connection", cr, app);
2480            }
2481        }
2482        for (int j=app.conProviders.size()-1; j>=0; j--) {
2483            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2484            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2485                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2486                        "provider reference", cpr, app);
2487            }
2488        }
2489    }
2490
2491    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2492        if (uid == Process.SYSTEM_UID) {
2493            // The system gets to run in any process.  If there are multiple
2494            // processes with the same uid, just pick the first (this
2495            // should never happen).
2496            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2497            if (procs == null) return null;
2498            final int N = procs.size();
2499            for (int i = 0; i < N; i++) {
2500                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2501            }
2502        }
2503        ProcessRecord proc = mProcessNames.get(processName, uid);
2504        if (false && proc != null && !keepIfLarge
2505                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2506                && proc.lastCachedPss >= 4000) {
2507            // Turn this condition on to cause killing to happen regularly, for testing.
2508            if (proc.baseProcessTracker != null) {
2509                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2510            }
2511            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2512                    + "k from cached");
2513        } else if (proc != null && !keepIfLarge
2514                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2515                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2516            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2517            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2518                if (proc.baseProcessTracker != null) {
2519                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2520                }
2521                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2522                        + "k from cached");
2523            }
2524        }
2525        return proc;
2526    }
2527
2528    void ensurePackageDexOpt(String packageName) {
2529        IPackageManager pm = AppGlobals.getPackageManager();
2530        try {
2531            if (pm.performDexOpt(packageName)) {
2532                mDidDexOpt = true;
2533            }
2534        } catch (RemoteException e) {
2535        }
2536    }
2537
2538    boolean isNextTransitionForward() {
2539        int transit = mWindowManager.getPendingAppTransition();
2540        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2541                || transit == AppTransition.TRANSIT_TASK_OPEN
2542                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2543    }
2544
2545    final ProcessRecord startProcessLocked(String processName,
2546            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2547            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2548            boolean isolated, boolean keepIfLarge) {
2549        ProcessRecord app;
2550        if (!isolated) {
2551            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2552        } else {
2553            // If this is an isolated process, it can't re-use an existing process.
2554            app = null;
2555        }
2556        // We don't have to do anything more if:
2557        // (1) There is an existing application record; and
2558        // (2) The caller doesn't think it is dead, OR there is no thread
2559        //     object attached to it so we know it couldn't have crashed; and
2560        // (3) There is a pid assigned to it, so it is either starting or
2561        //     already running.
2562        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2563                + " app=" + app + " knownToBeDead=" + knownToBeDead
2564                + " thread=" + (app != null ? app.thread : null)
2565                + " pid=" + (app != null ? app.pid : -1));
2566        if (app != null && app.pid > 0) {
2567            if (!knownToBeDead || app.thread == null) {
2568                // We already have the app running, or are waiting for it to
2569                // come up (we have a pid but not yet its thread), so keep it.
2570                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2571                // If this is a new package in the process, add the package to the list
2572                app.addPackage(info.packageName, mProcessStats);
2573                return app;
2574            }
2575
2576            // An application record is attached to a previous process,
2577            // clean it up now.
2578            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2579            handleAppDiedLocked(app, true, true);
2580        }
2581
2582        String hostingNameStr = hostingName != null
2583                ? hostingName.flattenToShortString() : null;
2584
2585        if (!isolated) {
2586            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2587                // If we are in the background, then check to see if this process
2588                // is bad.  If so, we will just silently fail.
2589                if (mBadProcesses.get(info.processName, info.uid) != null) {
2590                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2591                            + "/" + info.processName);
2592                    return null;
2593                }
2594            } else {
2595                // When the user is explicitly starting a process, then clear its
2596                // crash count so that we won't make it bad until they see at
2597                // least one crash dialog again, and make the process good again
2598                // if it had been bad.
2599                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2600                        + "/" + info.processName);
2601                mProcessCrashTimes.remove(info.processName, info.uid);
2602                if (mBadProcesses.get(info.processName, info.uid) != null) {
2603                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2604                            UserHandle.getUserId(info.uid), info.uid,
2605                            info.processName);
2606                    mBadProcesses.remove(info.processName, info.uid);
2607                    if (app != null) {
2608                        app.bad = false;
2609                    }
2610                }
2611            }
2612        }
2613
2614        if (app == null) {
2615            app = newProcessRecordLocked(info, processName, isolated);
2616            if (app == null) {
2617                Slog.w(TAG, "Failed making new process record for "
2618                        + processName + "/" + info.uid + " isolated=" + isolated);
2619                return null;
2620            }
2621            mProcessNames.put(processName, app.uid, app);
2622            if (isolated) {
2623                mIsolatedProcesses.put(app.uid, app);
2624            }
2625        } else {
2626            // If this is a new package in the process, add the package to the list
2627            app.addPackage(info.packageName, mProcessStats);
2628        }
2629
2630        // If the system is not ready yet, then hold off on starting this
2631        // process until it is.
2632        if (!mProcessesReady
2633                && !isAllowedWhileBooting(info)
2634                && !allowWhileBooting) {
2635            if (!mProcessesOnHold.contains(app)) {
2636                mProcessesOnHold.add(app);
2637            }
2638            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2639            return app;
2640        }
2641
2642        startProcessLocked(app, hostingType, hostingNameStr);
2643        return (app.pid != 0) ? app : null;
2644    }
2645
2646    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2647        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2648    }
2649
2650    private final void startProcessLocked(ProcessRecord app,
2651            String hostingType, String hostingNameStr) {
2652        if (app.pid > 0 && app.pid != MY_PID) {
2653            synchronized (mPidsSelfLocked) {
2654                mPidsSelfLocked.remove(app.pid);
2655                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2656            }
2657            app.setPid(0);
2658        }
2659
2660        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2661                "startProcessLocked removing on hold: " + app);
2662        mProcessesOnHold.remove(app);
2663
2664        updateCpuStats();
2665
2666        try {
2667            int uid = app.uid;
2668
2669            int[] gids = null;
2670            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2671            if (!app.isolated) {
2672                int[] permGids = null;
2673                try {
2674                    final PackageManager pm = mContext.getPackageManager();
2675                    permGids = pm.getPackageGids(app.info.packageName);
2676
2677                    if (Environment.isExternalStorageEmulated()) {
2678                        if (pm.checkPermission(
2679                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2680                                app.info.packageName) == PERMISSION_GRANTED) {
2681                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2682                        } else {
2683                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2684                        }
2685                    }
2686                } catch (PackageManager.NameNotFoundException e) {
2687                    Slog.w(TAG, "Unable to retrieve gids", e);
2688                }
2689
2690                /*
2691                 * Add shared application GID so applications can share some
2692                 * resources like shared libraries
2693                 */
2694                if (permGids == null) {
2695                    gids = new int[1];
2696                } else {
2697                    gids = new int[permGids.length + 1];
2698                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2699                }
2700                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2701            }
2702            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2703                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2704                        && mTopComponent != null
2705                        && app.processName.equals(mTopComponent.getPackageName())) {
2706                    uid = 0;
2707                }
2708                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2709                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2710                    uid = 0;
2711                }
2712            }
2713            int debugFlags = 0;
2714            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2715                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2716                // Also turn on CheckJNI for debuggable apps. It's quite
2717                // awkward to turn on otherwise.
2718                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2719            }
2720            // Run the app in safe mode if its manifest requests so or the
2721            // system is booted in safe mode.
2722            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2723                Zygote.systemInSafeMode == true) {
2724                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2725            }
2726            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2727                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2728            }
2729            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2730                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2731            }
2732            if ("1".equals(SystemProperties.get("debug.assert"))) {
2733                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2734            }
2735
2736            // Start the process.  It will either succeed and return a result containing
2737            // the PID of the new process, or else throw a RuntimeException.
2738            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2739                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2740                    app.info.targetSdkVersion, app.info.seinfo, null);
2741
2742            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2743            synchronized (bs) {
2744                if (bs.isOnBattery()) {
2745                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2746                }
2747            }
2748
2749            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2750                    UserHandle.getUserId(uid), startResult.pid, uid,
2751                    app.processName, hostingType,
2752                    hostingNameStr != null ? hostingNameStr : "");
2753
2754            if (app.persistent) {
2755                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2756            }
2757
2758            StringBuilder buf = mStringBuilder;
2759            buf.setLength(0);
2760            buf.append("Start proc ");
2761            buf.append(app.processName);
2762            buf.append(" for ");
2763            buf.append(hostingType);
2764            if (hostingNameStr != null) {
2765                buf.append(" ");
2766                buf.append(hostingNameStr);
2767            }
2768            buf.append(": pid=");
2769            buf.append(startResult.pid);
2770            buf.append(" uid=");
2771            buf.append(uid);
2772            buf.append(" gids={");
2773            if (gids != null) {
2774                for (int gi=0; gi<gids.length; gi++) {
2775                    if (gi != 0) buf.append(", ");
2776                    buf.append(gids[gi]);
2777
2778                }
2779            }
2780            buf.append("}");
2781            Slog.i(TAG, buf.toString());
2782            app.setPid(startResult.pid);
2783            app.usingWrapper = startResult.usingWrapper;
2784            app.removed = false;
2785            synchronized (mPidsSelfLocked) {
2786                this.mPidsSelfLocked.put(startResult.pid, app);
2787                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2788                msg.obj = app;
2789                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2790                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2791            }
2792            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
2793                    app.processName, app.info.uid);
2794            if (app.isolated) {
2795                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2796            }
2797        } catch (RuntimeException e) {
2798            // XXX do better error recovery.
2799            app.setPid(0);
2800            Slog.e(TAG, "Failure starting process " + app.processName, e);
2801        }
2802    }
2803
2804    void updateUsageStats(ActivityRecord component, boolean resumed) {
2805        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
2806        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2807        if (resumed) {
2808            mUsageStatsService.noteResumeComponent(component.realActivity);
2809            synchronized (stats) {
2810                stats.noteActivityResumedLocked(component.app.uid);
2811            }
2812        } else {
2813            mUsageStatsService.notePauseComponent(component.realActivity);
2814            synchronized (stats) {
2815                stats.noteActivityPausedLocked(component.app.uid);
2816            }
2817        }
2818    }
2819
2820    Intent getHomeIntent() {
2821        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
2822        intent.setComponent(mTopComponent);
2823        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
2824            intent.addCategory(Intent.CATEGORY_HOME);
2825        }
2826        return intent;
2827    }
2828
2829    boolean startHomeActivityLocked(int userId) {
2830        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2831                && mTopAction == null) {
2832            // We are running in factory test mode, but unable to find
2833            // the factory test app, so just sit around displaying the
2834            // error message and don't try to start anything.
2835            return false;
2836        }
2837        Intent intent = getHomeIntent();
2838        ActivityInfo aInfo =
2839            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2840        if (aInfo != null) {
2841            intent.setComponent(new ComponentName(
2842                    aInfo.applicationInfo.packageName, aInfo.name));
2843            // Don't do this if the home app is currently being
2844            // instrumented.
2845            aInfo = new ActivityInfo(aInfo);
2846            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2847            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2848                    aInfo.applicationInfo.uid, true);
2849            if (app == null || app.instrumentationClass == null) {
2850                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2851                mStackSupervisor.startHomeActivity(intent, aInfo);
2852            }
2853        }
2854
2855        return true;
2856    }
2857
2858    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2859        ActivityInfo ai = null;
2860        ComponentName comp = intent.getComponent();
2861        try {
2862            if (comp != null) {
2863                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2864            } else {
2865                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2866                        intent,
2867                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2868                            flags, userId);
2869
2870                if (info != null) {
2871                    ai = info.activityInfo;
2872                }
2873            }
2874        } catch (RemoteException e) {
2875            // ignore
2876        }
2877
2878        return ai;
2879    }
2880
2881    /**
2882     * Starts the "new version setup screen" if appropriate.
2883     */
2884    void startSetupActivityLocked() {
2885        // Only do this once per boot.
2886        if (mCheckedForSetup) {
2887            return;
2888        }
2889
2890        // We will show this screen if the current one is a different
2891        // version than the last one shown, and we are not running in
2892        // low-level factory test mode.
2893        final ContentResolver resolver = mContext.getContentResolver();
2894        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
2895                Settings.Global.getInt(resolver,
2896                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
2897            mCheckedForSetup = true;
2898
2899            // See if we should be showing the platform update setup UI.
2900            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2901            List<ResolveInfo> ris = mContext.getPackageManager()
2902                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2903
2904            // We don't allow third party apps to replace this.
2905            ResolveInfo ri = null;
2906            for (int i=0; ris != null && i<ris.size(); i++) {
2907                if ((ris.get(i).activityInfo.applicationInfo.flags
2908                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2909                    ri = ris.get(i);
2910                    break;
2911                }
2912            }
2913
2914            if (ri != null) {
2915                String vers = ri.activityInfo.metaData != null
2916                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2917                        : null;
2918                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2919                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2920                            Intent.METADATA_SETUP_VERSION);
2921                }
2922                String lastVers = Settings.Secure.getString(
2923                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2924                if (vers != null && !vers.equals(lastVers)) {
2925                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2926                    intent.setComponent(new ComponentName(
2927                            ri.activityInfo.packageName, ri.activityInfo.name));
2928                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
2929                            null, null, 0, 0, 0, null, 0, null, false, null, null);
2930                }
2931            }
2932        }
2933    }
2934
2935    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2936        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2937    }
2938
2939    void enforceNotIsolatedCaller(String caller) {
2940        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2941            throw new SecurityException("Isolated process not allowed to call " + caller);
2942        }
2943    }
2944
2945    @Override
2946    public int getFrontActivityScreenCompatMode() {
2947        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2948        synchronized (this) {
2949            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2950        }
2951    }
2952
2953    @Override
2954    public void setFrontActivityScreenCompatMode(int mode) {
2955        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2956                "setFrontActivityScreenCompatMode");
2957        synchronized (this) {
2958            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2959        }
2960    }
2961
2962    @Override
2963    public int getPackageScreenCompatMode(String packageName) {
2964        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2965        synchronized (this) {
2966            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2967        }
2968    }
2969
2970    @Override
2971    public void setPackageScreenCompatMode(String packageName, int mode) {
2972        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2973                "setPackageScreenCompatMode");
2974        synchronized (this) {
2975            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2976        }
2977    }
2978
2979    @Override
2980    public boolean getPackageAskScreenCompat(String packageName) {
2981        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2982        synchronized (this) {
2983            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2984        }
2985    }
2986
2987    @Override
2988    public void setPackageAskScreenCompat(String packageName, boolean ask) {
2989        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2990                "setPackageAskScreenCompat");
2991        synchronized (this) {
2992            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2993        }
2994    }
2995
2996    private void dispatchProcessesChanged() {
2997        int N;
2998        synchronized (this) {
2999            N = mPendingProcessChanges.size();
3000            if (mActiveProcessChanges.length < N) {
3001                mActiveProcessChanges = new ProcessChangeItem[N];
3002            }
3003            mPendingProcessChanges.toArray(mActiveProcessChanges);
3004            mAvailProcessChanges.addAll(mPendingProcessChanges);
3005            mPendingProcessChanges.clear();
3006            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3007        }
3008
3009        int i = mProcessObservers.beginBroadcast();
3010        while (i > 0) {
3011            i--;
3012            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3013            if (observer != null) {
3014                try {
3015                    for (int j=0; j<N; j++) {
3016                        ProcessChangeItem item = mActiveProcessChanges[j];
3017                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3018                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3019                                    + item.pid + " uid=" + item.uid + ": "
3020                                    + item.foregroundActivities);
3021                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3022                                    item.foregroundActivities);
3023                        }
3024                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
3025                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
3026                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
3027                            observer.onImportanceChanged(item.pid, item.uid,
3028                                    item.importance);
3029                        }
3030                    }
3031                } catch (RemoteException e) {
3032                }
3033            }
3034        }
3035        mProcessObservers.finishBroadcast();
3036    }
3037
3038    private void dispatchProcessDied(int pid, int uid) {
3039        int i = mProcessObservers.beginBroadcast();
3040        while (i > 0) {
3041            i--;
3042            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3043            if (observer != null) {
3044                try {
3045                    observer.onProcessDied(pid, uid);
3046                } catch (RemoteException e) {
3047                }
3048            }
3049        }
3050        mProcessObservers.finishBroadcast();
3051    }
3052
3053    final void doPendingActivityLaunchesLocked(boolean doResume) {
3054        final int N = mPendingActivityLaunches.size();
3055        if (N <= 0) {
3056            return;
3057        }
3058        for (int i=0; i<N; i++) {
3059            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3060            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags,
3061                    doResume && i == (N-1), null);
3062        }
3063        mPendingActivityLaunches.clear();
3064    }
3065
3066    @Override
3067    public final int startActivity(IApplicationThread caller, String callingPackage,
3068            Intent intent, String resolvedType, IBinder resultTo,
3069            String resultWho, int requestCode, int startFlags,
3070            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3071        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3072                resultWho, requestCode,
3073                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3074    }
3075
3076    @Override
3077    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3078            Intent intent, String resolvedType, IBinder resultTo,
3079            String resultWho, int requestCode, int startFlags,
3080            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3081        enforceNotIsolatedCaller("startActivity");
3082        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3083                false, true, "startActivity", null);
3084        // TODO: Switch to user app stacks here.
3085        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3086                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3087                null, null, options, userId, null);
3088    }
3089
3090    @Override
3091    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3092            Intent intent, String resolvedType, IBinder resultTo,
3093            String resultWho, int requestCode, int startFlags, String profileFile,
3094            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3095        enforceNotIsolatedCaller("startActivityAndWait");
3096        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3097                false, true, "startActivityAndWait", null);
3098        WaitResult res = new WaitResult();
3099        // TODO: Switch to user app stacks here.
3100        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3101                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3102                res, null, options, UserHandle.getCallingUserId(), null);
3103        return res;
3104    }
3105
3106    @Override
3107    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3108            Intent intent, String resolvedType, IBinder resultTo,
3109            String resultWho, int requestCode, int startFlags, Configuration config,
3110            Bundle options, int userId) {
3111        enforceNotIsolatedCaller("startActivityWithConfig");
3112        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3113                false, true, "startActivityWithConfig", null);
3114        // TODO: Switch to user app stacks here.
3115        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3116                resolvedType, resultTo, resultWho, requestCode, startFlags,
3117                null, null, null, config, options, userId, null);
3118        return ret;
3119    }
3120
3121    @Override
3122    public int startActivityIntentSender(IApplicationThread caller,
3123            IntentSender intent, Intent fillInIntent, String resolvedType,
3124            IBinder resultTo, String resultWho, int requestCode,
3125            int flagsMask, int flagsValues, Bundle options) {
3126        enforceNotIsolatedCaller("startActivityIntentSender");
3127        // Refuse possible leaked file descriptors
3128        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3129            throw new IllegalArgumentException("File descriptors passed in Intent");
3130        }
3131
3132        IIntentSender sender = intent.getTarget();
3133        if (!(sender instanceof PendingIntentRecord)) {
3134            throw new IllegalArgumentException("Bad PendingIntent object");
3135        }
3136
3137        PendingIntentRecord pir = (PendingIntentRecord)sender;
3138
3139        synchronized (this) {
3140            // If this is coming from the currently resumed activity, it is
3141            // effectively saying that app switches are allowed at this point.
3142            final ActivityStack stack = getFocusedStack();
3143            if (stack.mResumedActivity != null &&
3144                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3145                mAppSwitchesAllowedTime = 0;
3146            }
3147        }
3148        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3149                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3150        return ret;
3151    }
3152
3153    @Override
3154    public boolean startNextMatchingActivity(IBinder callingActivity,
3155            Intent intent, Bundle options) {
3156        // Refuse possible leaked file descriptors
3157        if (intent != null && intent.hasFileDescriptors() == true) {
3158            throw new IllegalArgumentException("File descriptors passed in Intent");
3159        }
3160
3161        synchronized (this) {
3162            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3163            if (r == null) {
3164                ActivityOptions.abort(options);
3165                return false;
3166            }
3167            if (r.app == null || r.app.thread == null) {
3168                // The caller is not running...  d'oh!
3169                ActivityOptions.abort(options);
3170                return false;
3171            }
3172            intent = new Intent(intent);
3173            // The caller is not allowed to change the data.
3174            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3175            // And we are resetting to find the next component...
3176            intent.setComponent(null);
3177
3178            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3179
3180            ActivityInfo aInfo = null;
3181            try {
3182                List<ResolveInfo> resolves =
3183                    AppGlobals.getPackageManager().queryIntentActivities(
3184                            intent, r.resolvedType,
3185                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3186                            UserHandle.getCallingUserId());
3187
3188                // Look for the original activity in the list...
3189                final int N = resolves != null ? resolves.size() : 0;
3190                for (int i=0; i<N; i++) {
3191                    ResolveInfo rInfo = resolves.get(i);
3192                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3193                            && rInfo.activityInfo.name.equals(r.info.name)) {
3194                        // We found the current one...  the next matching is
3195                        // after it.
3196                        i++;
3197                        if (i<N) {
3198                            aInfo = resolves.get(i).activityInfo;
3199                        }
3200                        if (debug) {
3201                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3202                                    + "/" + r.info.name);
3203                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3204                                    + "/" + aInfo.name);
3205                        }
3206                        break;
3207                    }
3208                }
3209            } catch (RemoteException e) {
3210            }
3211
3212            if (aInfo == null) {
3213                // Nobody who is next!
3214                ActivityOptions.abort(options);
3215                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3216                return false;
3217            }
3218
3219            intent.setComponent(new ComponentName(
3220                    aInfo.applicationInfo.packageName, aInfo.name));
3221            intent.setFlags(intent.getFlags()&~(
3222                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3223                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3224                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3225                    Intent.FLAG_ACTIVITY_NEW_TASK));
3226
3227            // Okay now we need to start the new activity, replacing the
3228            // currently running activity.  This is a little tricky because
3229            // we want to start the new one as if the current one is finished,
3230            // but not finish the current one first so that there is no flicker.
3231            // And thus...
3232            final boolean wasFinishing = r.finishing;
3233            r.finishing = true;
3234
3235            // Propagate reply information over to the new activity.
3236            final ActivityRecord resultTo = r.resultTo;
3237            final String resultWho = r.resultWho;
3238            final int requestCode = r.requestCode;
3239            r.resultTo = null;
3240            if (resultTo != null) {
3241                resultTo.removeResultsLocked(r, resultWho, requestCode);
3242            }
3243
3244            final long origId = Binder.clearCallingIdentity();
3245            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3246                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
3247                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3248                    options, false, null, null);
3249            Binder.restoreCallingIdentity(origId);
3250
3251            r.finishing = wasFinishing;
3252            if (res != ActivityManager.START_SUCCESS) {
3253                return false;
3254            }
3255            return true;
3256        }
3257    }
3258
3259    final int startActivityInPackage(int uid, String callingPackage,
3260            Intent intent, String resolvedType, IBinder resultTo,
3261            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3262                    IActivityContainer container) {
3263
3264        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3265                false, true, "startActivityInPackage", null);
3266
3267        // TODO: Switch to user app stacks here.
3268        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3269                resultTo, resultWho, requestCode, startFlags,
3270                null, null, null, null, options, userId, container);
3271        return ret;
3272    }
3273
3274    @Override
3275    public final int startActivities(IApplicationThread caller, String callingPackage,
3276            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3277            int userId) {
3278        enforceNotIsolatedCaller("startActivities");
3279        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3280                false, true, "startActivity", null);
3281        // TODO: Switch to user app stacks here.
3282        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3283                resolvedTypes, resultTo, options, userId);
3284        return ret;
3285    }
3286
3287    final int startActivitiesInPackage(int uid, String callingPackage,
3288            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3289            Bundle options, int userId) {
3290
3291        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3292                false, true, "startActivityInPackage", null);
3293        // TODO: Switch to user app stacks here.
3294        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3295                resultTo, options, userId);
3296        return ret;
3297    }
3298
3299    final void addRecentTaskLocked(TaskRecord task) {
3300        int N = mRecentTasks.size();
3301        // Quick case: check if the top-most recent task is the same.
3302        if (N > 0 && mRecentTasks.get(0) == task) {
3303            return;
3304        }
3305        // Remove any existing entries that are the same kind of task.
3306        for (int i=0; i<N; i++) {
3307            TaskRecord tr = mRecentTasks.get(i);
3308            if (task.userId == tr.userId
3309                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
3310                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
3311                tr.disposeThumbnail();
3312                mRecentTasks.remove(i);
3313                i--;
3314                N--;
3315                if (task.intent == null) {
3316                    // If the new recent task we are adding is not fully
3317                    // specified, then replace it with the existing recent task.
3318                    task = tr;
3319                }
3320            }
3321        }
3322        if (N >= MAX_RECENT_TASKS) {
3323            mRecentTasks.remove(N-1).disposeThumbnail();
3324        }
3325        mRecentTasks.add(0, task);
3326    }
3327
3328    @Override
3329    public void reportActivityFullyDrawn(IBinder token) {
3330        synchronized (this) {
3331            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3332            if (r == null) {
3333                return;
3334            }
3335            r.reportFullyDrawnLocked();
3336        }
3337    }
3338
3339    @Override
3340    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3341        synchronized (this) {
3342            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3343            if (r == null) {
3344                return;
3345            }
3346            final long origId = Binder.clearCallingIdentity();
3347            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3348            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3349                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3350            if (config != null) {
3351                r.frozenBeforeDestroy = true;
3352                if (!updateConfigurationLocked(config, r, false, false)) {
3353                    mStackSupervisor.resumeTopActivitiesLocked();
3354                }
3355            }
3356            Binder.restoreCallingIdentity(origId);
3357        }
3358    }
3359
3360    @Override
3361    public int getRequestedOrientation(IBinder token) {
3362        synchronized (this) {
3363            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3364            if (r == null) {
3365                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3366            }
3367            return mWindowManager.getAppOrientation(r.appToken);
3368        }
3369    }
3370
3371    /**
3372     * This is the internal entry point for handling Activity.finish().
3373     *
3374     * @param token The Binder token referencing the Activity we want to finish.
3375     * @param resultCode Result code, if any, from this Activity.
3376     * @param resultData Result data (Intent), if any, from this Activity.
3377     *
3378     * @return Returns true if the activity successfully finished, or false if it is still running.
3379     */
3380    @Override
3381    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
3382        // Refuse possible leaked file descriptors
3383        if (resultData != null && resultData.hasFileDescriptors() == true) {
3384            throw new IllegalArgumentException("File descriptors passed in Intent");
3385        }
3386
3387        synchronized(this) {
3388            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3389            if (r == null) {
3390                return true;
3391            }
3392            if (mController != null) {
3393                // Find the first activity that is not finishing.
3394                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3395                if (next != null) {
3396                    // ask watcher if this is allowed
3397                    boolean resumeOK = true;
3398                    try {
3399                        resumeOK = mController.activityResuming(next.packageName);
3400                    } catch (RemoteException e) {
3401                        mController = null;
3402                        Watchdog.getInstance().setActivityController(null);
3403                    }
3404
3405                    if (!resumeOK) {
3406                        return false;
3407                    }
3408                }
3409            }
3410            final long origId = Binder.clearCallingIdentity();
3411            boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode,
3412                    resultData, "app-request", true);
3413            Binder.restoreCallingIdentity(origId);
3414            return res;
3415        }
3416    }
3417
3418    @Override
3419    public final void finishHeavyWeightApp() {
3420        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3421                != PackageManager.PERMISSION_GRANTED) {
3422            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3423                    + Binder.getCallingPid()
3424                    + ", uid=" + Binder.getCallingUid()
3425                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3426            Slog.w(TAG, msg);
3427            throw new SecurityException(msg);
3428        }
3429
3430        synchronized(this) {
3431            if (mHeavyWeightProcess == null) {
3432                return;
3433            }
3434
3435            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3436                    mHeavyWeightProcess.activities);
3437            for (int i=0; i<activities.size(); i++) {
3438                ActivityRecord r = activities.get(i);
3439                if (!r.finishing) {
3440                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3441                            null, "finish-heavy", true);
3442                }
3443            }
3444
3445            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3446                    mHeavyWeightProcess.userId, 0));
3447            mHeavyWeightProcess = null;
3448        }
3449    }
3450
3451    @Override
3452    public void crashApplication(int uid, int initialPid, String packageName,
3453            String message) {
3454        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3455                != PackageManager.PERMISSION_GRANTED) {
3456            String msg = "Permission Denial: crashApplication() from pid="
3457                    + Binder.getCallingPid()
3458                    + ", uid=" + Binder.getCallingUid()
3459                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3460            Slog.w(TAG, msg);
3461            throw new SecurityException(msg);
3462        }
3463
3464        synchronized(this) {
3465            ProcessRecord proc = null;
3466
3467            // Figure out which process to kill.  We don't trust that initialPid
3468            // still has any relation to current pids, so must scan through the
3469            // list.
3470            synchronized (mPidsSelfLocked) {
3471                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3472                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3473                    if (p.uid != uid) {
3474                        continue;
3475                    }
3476                    if (p.pid == initialPid) {
3477                        proc = p;
3478                        break;
3479                    }
3480                    if (p.pkgList.containsKey(packageName)) {
3481                        proc = p;
3482                    }
3483                }
3484            }
3485
3486            if (proc == null) {
3487                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3488                        + " initialPid=" + initialPid
3489                        + " packageName=" + packageName);
3490                return;
3491            }
3492
3493            if (proc.thread != null) {
3494                if (proc.pid == Process.myPid()) {
3495                    Log.w(TAG, "crashApplication: trying to crash self!");
3496                    return;
3497                }
3498                long ident = Binder.clearCallingIdentity();
3499                try {
3500                    proc.thread.scheduleCrash(message);
3501                } catch (RemoteException e) {
3502                }
3503                Binder.restoreCallingIdentity(ident);
3504            }
3505        }
3506    }
3507
3508    @Override
3509    public final void finishSubActivity(IBinder token, String resultWho,
3510            int requestCode) {
3511        synchronized(this) {
3512            final long origId = Binder.clearCallingIdentity();
3513            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3514            if (r != null) {
3515                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3516            }
3517            Binder.restoreCallingIdentity(origId);
3518        }
3519    }
3520
3521    @Override
3522    public boolean finishActivityAffinity(IBinder token) {
3523        synchronized(this) {
3524            final long origId = Binder.clearCallingIdentity();
3525            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3526            boolean res = false;
3527            if (r != null) {
3528                res = r.task.stack.finishActivityAffinityLocked(r);
3529            }
3530            Binder.restoreCallingIdentity(origId);
3531            return res;
3532        }
3533    }
3534
3535    @Override
3536    public boolean willActivityBeVisible(IBinder token) {
3537        synchronized(this) {
3538            ActivityStack stack = ActivityRecord.getStackLocked(token);
3539            if (stack != null) {
3540                return stack.willActivityBeVisibleLocked(token);
3541            }
3542            return false;
3543        }
3544    }
3545
3546    @Override
3547    public void overridePendingTransition(IBinder token, String packageName,
3548            int enterAnim, int exitAnim) {
3549        synchronized(this) {
3550            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3551            if (self == null) {
3552                return;
3553            }
3554
3555            final long origId = Binder.clearCallingIdentity();
3556
3557            if (self.state == ActivityState.RESUMED
3558                    || self.state == ActivityState.PAUSING) {
3559                mWindowManager.overridePendingAppTransition(packageName,
3560                        enterAnim, exitAnim, null);
3561            }
3562
3563            Binder.restoreCallingIdentity(origId);
3564        }
3565    }
3566
3567    /**
3568     * Main function for removing an existing process from the activity manager
3569     * as a result of that process going away.  Clears out all connections
3570     * to the process.
3571     */
3572    private final void handleAppDiedLocked(ProcessRecord app,
3573            boolean restarting, boolean allowRestart) {
3574        int pid = app.pid;
3575        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3576        if (!restarting) {
3577            removeLruProcessLocked(app);
3578            if (pid > 0) {
3579                ProcessList.remove(pid);
3580            }
3581        }
3582
3583        if (mProfileProc == app) {
3584            clearProfilerLocked();
3585        }
3586
3587        // Remove this application's activities from active lists.
3588        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3589
3590        app.activities.clear();
3591
3592        if (app.instrumentationClass != null) {
3593            Slog.w(TAG, "Crash of app " + app.processName
3594                  + " running instrumentation " + app.instrumentationClass);
3595            Bundle info = new Bundle();
3596            info.putString("shortMsg", "Process crashed.");
3597            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3598        }
3599
3600        if (!restarting) {
3601            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3602                // If there was nothing to resume, and we are not already
3603                // restarting this process, but there is a visible activity that
3604                // is hosted by the process...  then make sure all visible
3605                // activities are running, taking care of restarting this
3606                // process.
3607                if (hasVisibleActivities) {
3608                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3609                }
3610            }
3611        }
3612    }
3613
3614    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3615        IBinder threadBinder = thread.asBinder();
3616        // Find the application record.
3617        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3618            ProcessRecord rec = mLruProcesses.get(i);
3619            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3620                return i;
3621            }
3622        }
3623        return -1;
3624    }
3625
3626    final ProcessRecord getRecordForAppLocked(
3627            IApplicationThread thread) {
3628        if (thread == null) {
3629            return null;
3630        }
3631
3632        int appIndex = getLRURecordIndexForAppLocked(thread);
3633        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3634    }
3635
3636    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3637        // If there are no longer any background processes running,
3638        // and the app that died was not running instrumentation,
3639        // then tell everyone we are now low on memory.
3640        boolean haveBg = false;
3641        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3642            ProcessRecord rec = mLruProcesses.get(i);
3643            if (rec.thread != null
3644                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3645                haveBg = true;
3646                break;
3647            }
3648        }
3649
3650        if (!haveBg) {
3651            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3652            if (doReport) {
3653                long now = SystemClock.uptimeMillis();
3654                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3655                    doReport = false;
3656                } else {
3657                    mLastMemUsageReportTime = now;
3658                }
3659            }
3660            final ArrayList<ProcessMemInfo> memInfos
3661                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3662            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3663            long now = SystemClock.uptimeMillis();
3664            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3665                ProcessRecord rec = mLruProcesses.get(i);
3666                if (rec == dyingProc || rec.thread == null) {
3667                    continue;
3668                }
3669                if (doReport) {
3670                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3671                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3672                }
3673                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3674                    // The low memory report is overriding any current
3675                    // state for a GC request.  Make sure to do
3676                    // heavy/important/visible/foreground processes first.
3677                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3678                        rec.lastRequestedGc = 0;
3679                    } else {
3680                        rec.lastRequestedGc = rec.lastLowMemory;
3681                    }
3682                    rec.reportLowMemory = true;
3683                    rec.lastLowMemory = now;
3684                    mProcessesToGc.remove(rec);
3685                    addProcessToGcListLocked(rec);
3686                }
3687            }
3688            if (doReport) {
3689                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3690                mHandler.sendMessage(msg);
3691            }
3692            scheduleAppGcsLocked();
3693        }
3694    }
3695
3696    final void appDiedLocked(ProcessRecord app, int pid,
3697            IApplicationThread thread) {
3698
3699        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3700        synchronized (stats) {
3701            stats.noteProcessDiedLocked(app.info.uid, pid);
3702        }
3703
3704        // Clean up already done if the process has been re-started.
3705        if (app.pid == pid && app.thread != null &&
3706                app.thread.asBinder() == thread.asBinder()) {
3707            boolean doLowMem = app.instrumentationClass == null;
3708            boolean doOomAdj = doLowMem;
3709            if (!app.killedByAm) {
3710                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3711                        + ") has died.");
3712                mAllowLowerMemLevel = true;
3713            } else {
3714                // Note that we always want to do oom adj to update our state with the
3715                // new number of procs.
3716                mAllowLowerMemLevel = false;
3717                doLowMem = false;
3718            }
3719            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3720            if (DEBUG_CLEANUP) Slog.v(
3721                TAG, "Dying app: " + app + ", pid: " + pid
3722                + ", thread: " + thread.asBinder());
3723            handleAppDiedLocked(app, false, true);
3724
3725            if (doOomAdj) {
3726                updateOomAdjLocked();
3727            }
3728            if (doLowMem) {
3729                doLowMemReportIfNeededLocked(app);
3730            }
3731        } else if (app.pid != pid) {
3732            // A new process has already been started.
3733            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3734                    + ") has died and restarted (pid " + app.pid + ").");
3735            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3736        } else if (DEBUG_PROCESSES) {
3737            Slog.d(TAG, "Received spurious death notification for thread "
3738                    + thread.asBinder());
3739        }
3740    }
3741
3742    /**
3743     * If a stack trace dump file is configured, dump process stack traces.
3744     * @param clearTraces causes the dump file to be erased prior to the new
3745     *    traces being written, if true; when false, the new traces will be
3746     *    appended to any existing file content.
3747     * @param firstPids of dalvik VM processes to dump stack traces for first
3748     * @param lastPids of dalvik VM processes to dump stack traces for last
3749     * @param nativeProcs optional list of native process names to dump stack crawls
3750     * @return file containing stack traces, or null if no dump file is configured
3751     */
3752    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3753            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3754        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3755        if (tracesPath == null || tracesPath.length() == 0) {
3756            return null;
3757        }
3758
3759        File tracesFile = new File(tracesPath);
3760        try {
3761            File tracesDir = tracesFile.getParentFile();
3762            if (!tracesDir.exists()) {
3763                tracesFile.mkdirs();
3764                if (!SELinux.restorecon(tracesDir)) {
3765                    return null;
3766                }
3767            }
3768            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3769
3770            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3771            tracesFile.createNewFile();
3772            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3773        } catch (IOException e) {
3774            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3775            return null;
3776        }
3777
3778        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
3779        return tracesFile;
3780    }
3781
3782    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3783            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3784        // Use a FileObserver to detect when traces finish writing.
3785        // The order of traces is considered important to maintain for legibility.
3786        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3787            @Override
3788            public synchronized void onEvent(int event, String path) { notify(); }
3789        };
3790
3791        try {
3792            observer.startWatching();
3793
3794            // First collect all of the stacks of the most important pids.
3795            if (firstPids != null) {
3796                try {
3797                    int num = firstPids.size();
3798                    for (int i = 0; i < num; i++) {
3799                        synchronized (observer) {
3800                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3801                            observer.wait(200);  // Wait for write-close, give up after 200msec
3802                        }
3803                    }
3804                } catch (InterruptedException e) {
3805                    Log.wtf(TAG, e);
3806                }
3807            }
3808
3809            // Next collect the stacks of the native pids
3810            if (nativeProcs != null) {
3811                int[] pids = Process.getPidsForCommands(nativeProcs);
3812                if (pids != null) {
3813                    for (int pid : pids) {
3814                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3815                    }
3816                }
3817            }
3818
3819            // Lastly, measure CPU usage.
3820            if (processCpuTracker != null) {
3821                processCpuTracker.init();
3822                System.gc();
3823                processCpuTracker.update();
3824                try {
3825                    synchronized (processCpuTracker) {
3826                        processCpuTracker.wait(500); // measure over 1/2 second.
3827                    }
3828                } catch (InterruptedException e) {
3829                }
3830                processCpuTracker.update();
3831
3832                // We'll take the stack crawls of just the top apps using CPU.
3833                final int N = processCpuTracker.countWorkingStats();
3834                int numProcs = 0;
3835                for (int i=0; i<N && numProcs<5; i++) {
3836                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
3837                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3838                        numProcs++;
3839                        try {
3840                            synchronized (observer) {
3841                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3842                                observer.wait(200);  // Wait for write-close, give up after 200msec
3843                            }
3844                        } catch (InterruptedException e) {
3845                            Log.wtf(TAG, e);
3846                        }
3847
3848                    }
3849                }
3850            }
3851        } finally {
3852            observer.stopWatching();
3853        }
3854    }
3855
3856    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3857        if (true || IS_USER_BUILD) {
3858            return;
3859        }
3860        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3861        if (tracesPath == null || tracesPath.length() == 0) {
3862            return;
3863        }
3864
3865        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3866        StrictMode.allowThreadDiskWrites();
3867        try {
3868            final File tracesFile = new File(tracesPath);
3869            final File tracesDir = tracesFile.getParentFile();
3870            final File tracesTmp = new File(tracesDir, "__tmp__");
3871            try {
3872                if (!tracesDir.exists()) {
3873                    tracesFile.mkdirs();
3874                    if (!SELinux.restorecon(tracesDir.getPath())) {
3875                        return;
3876                    }
3877                }
3878                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3879
3880                if (tracesFile.exists()) {
3881                    tracesTmp.delete();
3882                    tracesFile.renameTo(tracesTmp);
3883                }
3884                StringBuilder sb = new StringBuilder();
3885                Time tobj = new Time();
3886                tobj.set(System.currentTimeMillis());
3887                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3888                sb.append(": ");
3889                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3890                sb.append(" since ");
3891                sb.append(msg);
3892                FileOutputStream fos = new FileOutputStream(tracesFile);
3893                fos.write(sb.toString().getBytes());
3894                if (app == null) {
3895                    fos.write("\n*** No application process!".getBytes());
3896                }
3897                fos.close();
3898                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3899            } catch (IOException e) {
3900                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3901                return;
3902            }
3903
3904            if (app != null) {
3905                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3906                firstPids.add(app.pid);
3907                dumpStackTraces(tracesPath, firstPids, null, null, null);
3908            }
3909
3910            File lastTracesFile = null;
3911            File curTracesFile = null;
3912            for (int i=9; i>=0; i--) {
3913                String name = String.format(Locale.US, "slow%02d.txt", i);
3914                curTracesFile = new File(tracesDir, name);
3915                if (curTracesFile.exists()) {
3916                    if (lastTracesFile != null) {
3917                        curTracesFile.renameTo(lastTracesFile);
3918                    } else {
3919                        curTracesFile.delete();
3920                    }
3921                }
3922                lastTracesFile = curTracesFile;
3923            }
3924            tracesFile.renameTo(curTracesFile);
3925            if (tracesTmp.exists()) {
3926                tracesTmp.renameTo(tracesFile);
3927            }
3928        } finally {
3929            StrictMode.setThreadPolicy(oldPolicy);
3930        }
3931    }
3932
3933    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3934            ActivityRecord parent, boolean aboveSystem, final String annotation) {
3935        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3936        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3937
3938        if (mController != null) {
3939            try {
3940                // 0 == continue, -1 = kill process immediately
3941                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3942                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3943            } catch (RemoteException e) {
3944                mController = null;
3945                Watchdog.getInstance().setActivityController(null);
3946            }
3947        }
3948
3949        long anrTime = SystemClock.uptimeMillis();
3950        if (MONITOR_CPU_USAGE) {
3951            updateCpuStatsNow();
3952        }
3953
3954        synchronized (this) {
3955            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3956            if (mShuttingDown) {
3957                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3958                return;
3959            } else if (app.notResponding) {
3960                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3961                return;
3962            } else if (app.crashing) {
3963                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3964                return;
3965            }
3966
3967            // In case we come through here for the same app before completing
3968            // this one, mark as anring now so we will bail out.
3969            app.notResponding = true;
3970
3971            // Log the ANR to the event log.
3972            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
3973                    app.processName, app.info.flags, annotation);
3974
3975            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3976            firstPids.add(app.pid);
3977
3978            int parentPid = app.pid;
3979            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3980            if (parentPid != app.pid) firstPids.add(parentPid);
3981
3982            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3983
3984            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3985                ProcessRecord r = mLruProcesses.get(i);
3986                if (r != null && r.thread != null) {
3987                    int pid = r.pid;
3988                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3989                        if (r.persistent) {
3990                            firstPids.add(pid);
3991                        } else {
3992                            lastPids.put(pid, Boolean.TRUE);
3993                        }
3994                    }
3995                }
3996            }
3997        }
3998
3999        // Log the ANR to the main log.
4000        StringBuilder info = new StringBuilder();
4001        info.setLength(0);
4002        info.append("ANR in ").append(app.processName);
4003        if (activity != null && activity.shortComponentName != null) {
4004            info.append(" (").append(activity.shortComponentName).append(")");
4005        }
4006        info.append("\n");
4007        info.append("PID: ").append(app.pid).append("\n");
4008        if (annotation != null) {
4009            info.append("Reason: ").append(annotation).append("\n");
4010        }
4011        if (parent != null && parent != activity) {
4012            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4013        }
4014
4015        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4016
4017        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4018                NATIVE_STACKS_OF_INTEREST);
4019
4020        String cpuInfo = null;
4021        if (MONITOR_CPU_USAGE) {
4022            updateCpuStatsNow();
4023            synchronized (mProcessCpuThread) {
4024                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4025            }
4026            info.append(processCpuTracker.printCurrentLoad());
4027            info.append(cpuInfo);
4028        }
4029
4030        info.append(processCpuTracker.printCurrentState(anrTime));
4031
4032        Slog.e(TAG, info.toString());
4033        if (tracesFile == null) {
4034            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4035            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4036        }
4037
4038        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4039                cpuInfo, tracesFile, null);
4040
4041        if (mController != null) {
4042            try {
4043                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4044                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4045                if (res != 0) {
4046                    if (res < 0 && app.pid != MY_PID) {
4047                        Process.killProcess(app.pid);
4048                    } else {
4049                        synchronized (this) {
4050                            mServices.scheduleServiceTimeoutLocked(app);
4051                        }
4052                    }
4053                    return;
4054                }
4055            } catch (RemoteException e) {
4056                mController = null;
4057                Watchdog.getInstance().setActivityController(null);
4058            }
4059        }
4060
4061        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4062        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4063                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4064
4065        synchronized (this) {
4066            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4067                killUnneededProcessLocked(app, "background ANR");
4068                return;
4069            }
4070
4071            // Set the app's notResponding state, and look up the errorReportReceiver
4072            makeAppNotRespondingLocked(app,
4073                    activity != null ? activity.shortComponentName : null,
4074                    annotation != null ? "ANR " + annotation : "ANR",
4075                    info.toString());
4076
4077            // Bring up the infamous App Not Responding dialog
4078            Message msg = Message.obtain();
4079            HashMap<String, Object> map = new HashMap<String, Object>();
4080            msg.what = SHOW_NOT_RESPONDING_MSG;
4081            msg.obj = map;
4082            msg.arg1 = aboveSystem ? 1 : 0;
4083            map.put("app", app);
4084            if (activity != null) {
4085                map.put("activity", activity);
4086            }
4087
4088            mHandler.sendMessage(msg);
4089        }
4090    }
4091
4092    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4093        if (!mLaunchWarningShown) {
4094            mLaunchWarningShown = true;
4095            mHandler.post(new Runnable() {
4096                @Override
4097                public void run() {
4098                    synchronized (ActivityManagerService.this) {
4099                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4100                        d.show();
4101                        mHandler.postDelayed(new Runnable() {
4102                            @Override
4103                            public void run() {
4104                                synchronized (ActivityManagerService.this) {
4105                                    d.dismiss();
4106                                    mLaunchWarningShown = false;
4107                                }
4108                            }
4109                        }, 4000);
4110                    }
4111                }
4112            });
4113        }
4114    }
4115
4116    @Override
4117    public boolean clearApplicationUserData(final String packageName,
4118            final IPackageDataObserver observer, int userId) {
4119        enforceNotIsolatedCaller("clearApplicationUserData");
4120        int uid = Binder.getCallingUid();
4121        int pid = Binder.getCallingPid();
4122        userId = handleIncomingUser(pid, uid,
4123                userId, false, true, "clearApplicationUserData", null);
4124        long callingId = Binder.clearCallingIdentity();
4125        try {
4126            IPackageManager pm = AppGlobals.getPackageManager();
4127            int pkgUid = -1;
4128            synchronized(this) {
4129                try {
4130                    pkgUid = pm.getPackageUid(packageName, userId);
4131                } catch (RemoteException e) {
4132                }
4133                if (pkgUid == -1) {
4134                    Slog.w(TAG, "Invalid packageName: " + packageName);
4135                    if (observer != null) {
4136                        try {
4137                            observer.onRemoveCompleted(packageName, false);
4138                        } catch (RemoteException e) {
4139                            Slog.i(TAG, "Observer no longer exists.");
4140                        }
4141                    }
4142                    return false;
4143                }
4144                if (uid == pkgUid || checkComponentPermission(
4145                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4146                        pid, uid, -1, true)
4147                        == PackageManager.PERMISSION_GRANTED) {
4148                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4149                } else {
4150                    throw new SecurityException("PID " + pid + " does not have permission "
4151                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4152                                    + " of package " + packageName);
4153                }
4154            }
4155
4156            try {
4157                // Clear application user data
4158                pm.clearApplicationUserData(packageName, observer, userId);
4159
4160                // Remove all permissions granted from/to this package
4161                removeUriPermissionsForPackageLocked(packageName, userId, true);
4162
4163                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4164                        Uri.fromParts("package", packageName, null));
4165                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4166                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4167                        null, null, 0, null, null, null, false, false, userId);
4168            } catch (RemoteException e) {
4169            }
4170        } finally {
4171            Binder.restoreCallingIdentity(callingId);
4172        }
4173        return true;
4174    }
4175
4176    @Override
4177    public void killBackgroundProcesses(final String packageName, int userId) {
4178        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4179                != PackageManager.PERMISSION_GRANTED &&
4180                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4181                        != PackageManager.PERMISSION_GRANTED) {
4182            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4183                    + Binder.getCallingPid()
4184                    + ", uid=" + Binder.getCallingUid()
4185                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4186            Slog.w(TAG, msg);
4187            throw new SecurityException(msg);
4188        }
4189
4190        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4191                userId, true, true, "killBackgroundProcesses", null);
4192        long callingId = Binder.clearCallingIdentity();
4193        try {
4194            IPackageManager pm = AppGlobals.getPackageManager();
4195            synchronized(this) {
4196                int appId = -1;
4197                try {
4198                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4199                } catch (RemoteException e) {
4200                }
4201                if (appId == -1) {
4202                    Slog.w(TAG, "Invalid packageName: " + packageName);
4203                    return;
4204                }
4205                killPackageProcessesLocked(packageName, appId, userId,
4206                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4207            }
4208        } finally {
4209            Binder.restoreCallingIdentity(callingId);
4210        }
4211    }
4212
4213    @Override
4214    public void killAllBackgroundProcesses() {
4215        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4216                != PackageManager.PERMISSION_GRANTED) {
4217            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4218                    + Binder.getCallingPid()
4219                    + ", uid=" + Binder.getCallingUid()
4220                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4221            Slog.w(TAG, msg);
4222            throw new SecurityException(msg);
4223        }
4224
4225        long callingId = Binder.clearCallingIdentity();
4226        try {
4227            synchronized(this) {
4228                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4229                final int NP = mProcessNames.getMap().size();
4230                for (int ip=0; ip<NP; ip++) {
4231                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4232                    final int NA = apps.size();
4233                    for (int ia=0; ia<NA; ia++) {
4234                        ProcessRecord app = apps.valueAt(ia);
4235                        if (app.persistent) {
4236                            // we don't kill persistent processes
4237                            continue;
4238                        }
4239                        if (app.removed) {
4240                            procs.add(app);
4241                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4242                            app.removed = true;
4243                            procs.add(app);
4244                        }
4245                    }
4246                }
4247
4248                int N = procs.size();
4249                for (int i=0; i<N; i++) {
4250                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4251                }
4252                mAllowLowerMemLevel = true;
4253                updateOomAdjLocked();
4254                doLowMemReportIfNeededLocked(null);
4255            }
4256        } finally {
4257            Binder.restoreCallingIdentity(callingId);
4258        }
4259    }
4260
4261    @Override
4262    public void forceStopPackage(final String packageName, int userId) {
4263        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4264                != PackageManager.PERMISSION_GRANTED) {
4265            String msg = "Permission Denial: forceStopPackage() from pid="
4266                    + Binder.getCallingPid()
4267                    + ", uid=" + Binder.getCallingUid()
4268                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4269            Slog.w(TAG, msg);
4270            throw new SecurityException(msg);
4271        }
4272        final int callingPid = Binder.getCallingPid();
4273        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4274                userId, true, true, "forceStopPackage", null);
4275        long callingId = Binder.clearCallingIdentity();
4276        try {
4277            IPackageManager pm = AppGlobals.getPackageManager();
4278            synchronized(this) {
4279                int[] users = userId == UserHandle.USER_ALL
4280                        ? getUsersLocked() : new int[] { userId };
4281                for (int user : users) {
4282                    int pkgUid = -1;
4283                    try {
4284                        pkgUid = pm.getPackageUid(packageName, user);
4285                    } catch (RemoteException e) {
4286                    }
4287                    if (pkgUid == -1) {
4288                        Slog.w(TAG, "Invalid packageName: " + packageName);
4289                        continue;
4290                    }
4291                    try {
4292                        pm.setPackageStoppedState(packageName, true, user);
4293                    } catch (RemoteException e) {
4294                    } catch (IllegalArgumentException e) {
4295                        Slog.w(TAG, "Failed trying to unstop package "
4296                                + packageName + ": " + e);
4297                    }
4298                    if (isUserRunningLocked(user, false)) {
4299                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4300                    }
4301                }
4302            }
4303        } finally {
4304            Binder.restoreCallingIdentity(callingId);
4305        }
4306    }
4307
4308    /*
4309     * The pkg name and app id have to be specified.
4310     */
4311    @Override
4312    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4313        if (pkg == null) {
4314            return;
4315        }
4316        // Make sure the uid is valid.
4317        if (appid < 0) {
4318            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4319            return;
4320        }
4321        int callerUid = Binder.getCallingUid();
4322        // Only the system server can kill an application
4323        if (callerUid == Process.SYSTEM_UID) {
4324            // Post an aysnc message to kill the application
4325            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4326            msg.arg1 = appid;
4327            msg.arg2 = 0;
4328            Bundle bundle = new Bundle();
4329            bundle.putString("pkg", pkg);
4330            bundle.putString("reason", reason);
4331            msg.obj = bundle;
4332            mHandler.sendMessage(msg);
4333        } else {
4334            throw new SecurityException(callerUid + " cannot kill pkg: " +
4335                    pkg);
4336        }
4337    }
4338
4339    @Override
4340    public void closeSystemDialogs(String reason) {
4341        enforceNotIsolatedCaller("closeSystemDialogs");
4342
4343        final int pid = Binder.getCallingPid();
4344        final int uid = Binder.getCallingUid();
4345        final long origId = Binder.clearCallingIdentity();
4346        try {
4347            synchronized (this) {
4348                // Only allow this from foreground processes, so that background
4349                // applications can't abuse it to prevent system UI from being shown.
4350                if (uid >= Process.FIRST_APPLICATION_UID) {
4351                    ProcessRecord proc;
4352                    synchronized (mPidsSelfLocked) {
4353                        proc = mPidsSelfLocked.get(pid);
4354                    }
4355                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4356                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4357                                + " from background process " + proc);
4358                        return;
4359                    }
4360                }
4361                closeSystemDialogsLocked(reason);
4362            }
4363        } finally {
4364            Binder.restoreCallingIdentity(origId);
4365        }
4366    }
4367
4368    void closeSystemDialogsLocked(String reason) {
4369        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4370        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4371                | Intent.FLAG_RECEIVER_FOREGROUND);
4372        if (reason != null) {
4373            intent.putExtra("reason", reason);
4374        }
4375        mWindowManager.closeSystemDialogs(reason);
4376
4377        mStackSupervisor.closeSystemDialogsLocked();
4378
4379        broadcastIntentLocked(null, null, intent, null,
4380                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4381                Process.SYSTEM_UID, UserHandle.USER_ALL);
4382    }
4383
4384    @Override
4385    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4386        enforceNotIsolatedCaller("getProcessMemoryInfo");
4387        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4388        for (int i=pids.length-1; i>=0; i--) {
4389            ProcessRecord proc;
4390            int oomAdj;
4391            synchronized (this) {
4392                synchronized (mPidsSelfLocked) {
4393                    proc = mPidsSelfLocked.get(pids[i]);
4394                    oomAdj = proc != null ? proc.setAdj : 0;
4395                }
4396            }
4397            infos[i] = new Debug.MemoryInfo();
4398            Debug.getMemoryInfo(pids[i], infos[i]);
4399            if (proc != null) {
4400                synchronized (this) {
4401                    if (proc.thread != null && proc.setAdj == oomAdj) {
4402                        // Record this for posterity if the process has been stable.
4403                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4404                                infos[i].getTotalUss(), false, proc.pkgList);
4405                    }
4406                }
4407            }
4408        }
4409        return infos;
4410    }
4411
4412    @Override
4413    public long[] getProcessPss(int[] pids) {
4414        enforceNotIsolatedCaller("getProcessPss");
4415        long[] pss = new long[pids.length];
4416        for (int i=pids.length-1; i>=0; i--) {
4417            ProcessRecord proc;
4418            int oomAdj;
4419            synchronized (this) {
4420                synchronized (mPidsSelfLocked) {
4421                    proc = mPidsSelfLocked.get(pids[i]);
4422                    oomAdj = proc != null ? proc.setAdj : 0;
4423                }
4424            }
4425            long[] tmpUss = new long[1];
4426            pss[i] = Debug.getPss(pids[i], tmpUss);
4427            if (proc != null) {
4428                synchronized (this) {
4429                    if (proc.thread != null && proc.setAdj == oomAdj) {
4430                        // Record this for posterity if the process has been stable.
4431                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4432                    }
4433                }
4434            }
4435        }
4436        return pss;
4437    }
4438
4439    @Override
4440    public void killApplicationProcess(String processName, int uid) {
4441        if (processName == null) {
4442            return;
4443        }
4444
4445        int callerUid = Binder.getCallingUid();
4446        // Only the system server can kill an application
4447        if (callerUid == Process.SYSTEM_UID) {
4448            synchronized (this) {
4449                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4450                if (app != null && app.thread != null) {
4451                    try {
4452                        app.thread.scheduleSuicide();
4453                    } catch (RemoteException e) {
4454                        // If the other end already died, then our work here is done.
4455                    }
4456                } else {
4457                    Slog.w(TAG, "Process/uid not found attempting kill of "
4458                            + processName + " / " + uid);
4459                }
4460            }
4461        } else {
4462            throw new SecurityException(callerUid + " cannot kill app process: " +
4463                    processName);
4464        }
4465    }
4466
4467    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4468        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4469                false, true, false, false, UserHandle.getUserId(uid), reason);
4470        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4471                Uri.fromParts("package", packageName, null));
4472        if (!mProcessesReady) {
4473            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4474                    | Intent.FLAG_RECEIVER_FOREGROUND);
4475        }
4476        intent.putExtra(Intent.EXTRA_UID, uid);
4477        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4478        broadcastIntentLocked(null, null, intent,
4479                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4480                false, false,
4481                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4482    }
4483
4484    private void forceStopUserLocked(int userId, String reason) {
4485        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4486        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4487        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4488                | Intent.FLAG_RECEIVER_FOREGROUND);
4489        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4490        broadcastIntentLocked(null, null, intent,
4491                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4492                false, false,
4493                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4494    }
4495
4496    private final boolean killPackageProcessesLocked(String packageName, int appId,
4497            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4498            boolean doit, boolean evenPersistent, String reason) {
4499        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4500
4501        // Remove all processes this package may have touched: all with the
4502        // same UID (except for the system or root user), and all whose name
4503        // matches the package name.
4504        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4505        final int NP = mProcessNames.getMap().size();
4506        for (int ip=0; ip<NP; ip++) {
4507            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4508            final int NA = apps.size();
4509            for (int ia=0; ia<NA; ia++) {
4510                ProcessRecord app = apps.valueAt(ia);
4511                if (app.persistent && !evenPersistent) {
4512                    // we don't kill persistent processes
4513                    continue;
4514                }
4515                if (app.removed) {
4516                    if (doit) {
4517                        procs.add(app);
4518                    }
4519                    continue;
4520                }
4521
4522                // Skip process if it doesn't meet our oom adj requirement.
4523                if (app.setAdj < minOomAdj) {
4524                    continue;
4525                }
4526
4527                // If no package is specified, we call all processes under the
4528                // give user id.
4529                if (packageName == null) {
4530                    if (app.userId != userId) {
4531                        continue;
4532                    }
4533                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4534                        continue;
4535                    }
4536                // Package has been specified, we want to hit all processes
4537                // that match it.  We need to qualify this by the processes
4538                // that are running under the specified app and user ID.
4539                } else {
4540                    if (UserHandle.getAppId(app.uid) != appId) {
4541                        continue;
4542                    }
4543                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4544                        continue;
4545                    }
4546                    if (!app.pkgList.containsKey(packageName)) {
4547                        continue;
4548                    }
4549                }
4550
4551                // Process has passed all conditions, kill it!
4552                if (!doit) {
4553                    return true;
4554                }
4555                app.removed = true;
4556                procs.add(app);
4557            }
4558        }
4559
4560        int N = procs.size();
4561        for (int i=0; i<N; i++) {
4562            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4563        }
4564        updateOomAdjLocked();
4565        return N > 0;
4566    }
4567
4568    private final boolean forceStopPackageLocked(String name, int appId,
4569            boolean callerWillRestart, boolean purgeCache, boolean doit,
4570            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4571        int i;
4572        int N;
4573
4574        if (userId == UserHandle.USER_ALL && name == null) {
4575            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4576        }
4577
4578        if (appId < 0 && name != null) {
4579            try {
4580                appId = UserHandle.getAppId(
4581                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4582            } catch (RemoteException e) {
4583            }
4584        }
4585
4586        if (doit) {
4587            if (name != null) {
4588                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4589                        + " user=" + userId + ": " + reason);
4590            } else {
4591                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4592            }
4593
4594            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4595            for (int ip=pmap.size()-1; ip>=0; ip--) {
4596                SparseArray<Long> ba = pmap.valueAt(ip);
4597                for (i=ba.size()-1; i>=0; i--) {
4598                    boolean remove = false;
4599                    final int entUid = ba.keyAt(i);
4600                    if (name != null) {
4601                        if (userId == UserHandle.USER_ALL) {
4602                            if (UserHandle.getAppId(entUid) == appId) {
4603                                remove = true;
4604                            }
4605                        } else {
4606                            if (entUid == UserHandle.getUid(userId, appId)) {
4607                                remove = true;
4608                            }
4609                        }
4610                    } else if (UserHandle.getUserId(entUid) == userId) {
4611                        remove = true;
4612                    }
4613                    if (remove) {
4614                        ba.removeAt(i);
4615                    }
4616                }
4617                if (ba.size() == 0) {
4618                    pmap.removeAt(ip);
4619                }
4620            }
4621        }
4622
4623        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4624                -100, callerWillRestart, true, doit, evenPersistent,
4625                name == null ? ("stop user " + userId) : ("stop " + name));
4626
4627        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4628            if (!doit) {
4629                return true;
4630            }
4631            didSomething = true;
4632        }
4633
4634        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4635            if (!doit) {
4636                return true;
4637            }
4638            didSomething = true;
4639        }
4640
4641        if (name == null) {
4642            // Remove all sticky broadcasts from this user.
4643            mStickyBroadcasts.remove(userId);
4644        }
4645
4646        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4647        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4648                userId, providers)) {
4649            if (!doit) {
4650                return true;
4651            }
4652            didSomething = true;
4653        }
4654        N = providers.size();
4655        for (i=0; i<N; i++) {
4656            removeDyingProviderLocked(null, providers.get(i), true);
4657        }
4658
4659        // Remove transient permissions granted from/to this package/user
4660        removeUriPermissionsForPackageLocked(name, userId, false);
4661
4662        if (name == null || uninstalling) {
4663            // Remove pending intents.  For now we only do this when force
4664            // stopping users, because we have some problems when doing this
4665            // for packages -- app widgets are not currently cleaned up for
4666            // such packages, so they can be left with bad pending intents.
4667            if (mIntentSenderRecords.size() > 0) {
4668                Iterator<WeakReference<PendingIntentRecord>> it
4669                        = mIntentSenderRecords.values().iterator();
4670                while (it.hasNext()) {
4671                    WeakReference<PendingIntentRecord> wpir = it.next();
4672                    if (wpir == null) {
4673                        it.remove();
4674                        continue;
4675                    }
4676                    PendingIntentRecord pir = wpir.get();
4677                    if (pir == null) {
4678                        it.remove();
4679                        continue;
4680                    }
4681                    if (name == null) {
4682                        // Stopping user, remove all objects for the user.
4683                        if (pir.key.userId != userId) {
4684                            // Not the same user, skip it.
4685                            continue;
4686                        }
4687                    } else {
4688                        if (UserHandle.getAppId(pir.uid) != appId) {
4689                            // Different app id, skip it.
4690                            continue;
4691                        }
4692                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4693                            // Different user, skip it.
4694                            continue;
4695                        }
4696                        if (!pir.key.packageName.equals(name)) {
4697                            // Different package, skip it.
4698                            continue;
4699                        }
4700                    }
4701                    if (!doit) {
4702                        return true;
4703                    }
4704                    didSomething = true;
4705                    it.remove();
4706                    pir.canceled = true;
4707                    if (pir.key.activity != null) {
4708                        pir.key.activity.pendingResults.remove(pir.ref);
4709                    }
4710                }
4711            }
4712        }
4713
4714        if (doit) {
4715            if (purgeCache && name != null) {
4716                AttributeCache ac = AttributeCache.instance();
4717                if (ac != null) {
4718                    ac.removePackage(name);
4719                }
4720            }
4721            if (mBooted) {
4722                mStackSupervisor.resumeTopActivitiesLocked();
4723                mStackSupervisor.scheduleIdleLocked();
4724            }
4725        }
4726
4727        return didSomething;
4728    }
4729
4730    private final boolean removeProcessLocked(ProcessRecord app,
4731            boolean callerWillRestart, boolean allowRestart, String reason) {
4732        final String name = app.processName;
4733        final int uid = app.uid;
4734        if (DEBUG_PROCESSES) Slog.d(
4735            TAG, "Force removing proc " + app.toShortString() + " (" + name
4736            + "/" + uid + ")");
4737
4738        mProcessNames.remove(name, uid);
4739        mIsolatedProcesses.remove(app.uid);
4740        if (mHeavyWeightProcess == app) {
4741            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4742                    mHeavyWeightProcess.userId, 0));
4743            mHeavyWeightProcess = null;
4744        }
4745        boolean needRestart = false;
4746        if (app.pid > 0 && app.pid != MY_PID) {
4747            int pid = app.pid;
4748            synchronized (mPidsSelfLocked) {
4749                mPidsSelfLocked.remove(pid);
4750                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4751            }
4752            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
4753                    app.processName, app.info.uid);
4754            if (app.isolated) {
4755                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
4756            }
4757            killUnneededProcessLocked(app, reason);
4758            handleAppDiedLocked(app, true, allowRestart);
4759            removeLruProcessLocked(app);
4760
4761            if (app.persistent && !app.isolated) {
4762                if (!callerWillRestart) {
4763                    addAppLocked(app.info, false);
4764                } else {
4765                    needRestart = true;
4766                }
4767            }
4768        } else {
4769            mRemovedProcesses.add(app);
4770        }
4771
4772        return needRestart;
4773    }
4774
4775    private final void processStartTimedOutLocked(ProcessRecord app) {
4776        final int pid = app.pid;
4777        boolean gone = false;
4778        synchronized (mPidsSelfLocked) {
4779            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4780            if (knownApp != null && knownApp.thread == null) {
4781                mPidsSelfLocked.remove(pid);
4782                gone = true;
4783            }
4784        }
4785
4786        if (gone) {
4787            Slog.w(TAG, "Process " + app + " failed to attach");
4788            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
4789                    pid, app.uid, app.processName);
4790            mProcessNames.remove(app.processName, app.uid);
4791            mIsolatedProcesses.remove(app.uid);
4792            if (mHeavyWeightProcess == app) {
4793                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4794                        mHeavyWeightProcess.userId, 0));
4795                mHeavyWeightProcess = null;
4796            }
4797            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
4798                    app.processName, app.info.uid);
4799            if (app.isolated) {
4800                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
4801            }
4802            // Take care of any launching providers waiting for this process.
4803            checkAppInLaunchingProvidersLocked(app, true);
4804            // Take care of any services that are waiting for the process.
4805            mServices.processStartTimedOutLocked(app);
4806            killUnneededProcessLocked(app, "start timeout");
4807            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4808                Slog.w(TAG, "Unattached app died before backup, skipping");
4809                try {
4810                    IBackupManager bm = IBackupManager.Stub.asInterface(
4811                            ServiceManager.getService(Context.BACKUP_SERVICE));
4812                    bm.agentDisconnected(app.info.packageName);
4813                } catch (RemoteException e) {
4814                    // Can't happen; the backup manager is local
4815                }
4816            }
4817            if (isPendingBroadcastProcessLocked(pid)) {
4818                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4819                skipPendingBroadcastLocked(pid);
4820            }
4821        } else {
4822            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4823        }
4824    }
4825
4826    private final boolean attachApplicationLocked(IApplicationThread thread,
4827            int pid) {
4828
4829        // Find the application record that is being attached...  either via
4830        // the pid if we are running in multiple processes, or just pull the
4831        // next app record if we are emulating process with anonymous threads.
4832        ProcessRecord app;
4833        if (pid != MY_PID && pid >= 0) {
4834            synchronized (mPidsSelfLocked) {
4835                app = mPidsSelfLocked.get(pid);
4836            }
4837        } else {
4838            app = null;
4839        }
4840
4841        if (app == null) {
4842            Slog.w(TAG, "No pending application record for pid " + pid
4843                    + " (IApplicationThread " + thread + "); dropping process");
4844            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4845            if (pid > 0 && pid != MY_PID) {
4846                Process.killProcessQuiet(pid);
4847            } else {
4848                try {
4849                    thread.scheduleExit();
4850                } catch (Exception e) {
4851                    // Ignore exceptions.
4852                }
4853            }
4854            return false;
4855        }
4856
4857        // If this application record is still attached to a previous
4858        // process, clean it up now.
4859        if (app.thread != null) {
4860            handleAppDiedLocked(app, true, true);
4861        }
4862
4863        // Tell the process all about itself.
4864
4865        if (localLOGV) Slog.v(
4866                TAG, "Binding process pid " + pid + " to record " + app);
4867
4868        final String processName = app.processName;
4869        try {
4870            AppDeathRecipient adr = new AppDeathRecipient(
4871                    app, pid, thread);
4872            thread.asBinder().linkToDeath(adr, 0);
4873            app.deathRecipient = adr;
4874        } catch (RemoteException e) {
4875            app.resetPackageList(mProcessStats);
4876            startProcessLocked(app, "link fail", processName);
4877            return false;
4878        }
4879
4880        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
4881
4882        app.makeActive(thread, mProcessStats);
4883        app.curAdj = app.setAdj = -100;
4884        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
4885        app.forcingToForeground = null;
4886        updateProcessForegroundLocked(app, false, false);
4887        app.hasShownUi = false;
4888        app.debugging = false;
4889        app.cached = false;
4890
4891        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4892
4893        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4894        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4895
4896        if (!normalMode) {
4897            Slog.i(TAG, "Launching preboot mode app: " + app);
4898        }
4899
4900        if (localLOGV) Slog.v(
4901            TAG, "New app record " + app
4902            + " thread=" + thread.asBinder() + " pid=" + pid);
4903        try {
4904            int testMode = IApplicationThread.DEBUG_OFF;
4905            if (mDebugApp != null && mDebugApp.equals(processName)) {
4906                testMode = mWaitForDebugger
4907                    ? IApplicationThread.DEBUG_WAIT
4908                    : IApplicationThread.DEBUG_ON;
4909                app.debugging = true;
4910                if (mDebugTransient) {
4911                    mDebugApp = mOrigDebugApp;
4912                    mWaitForDebugger = mOrigWaitForDebugger;
4913                }
4914            }
4915            String profileFile = app.instrumentationProfileFile;
4916            ParcelFileDescriptor profileFd = null;
4917            boolean profileAutoStop = false;
4918            if (mProfileApp != null && mProfileApp.equals(processName)) {
4919                mProfileProc = app;
4920                profileFile = mProfileFile;
4921                profileFd = mProfileFd;
4922                profileAutoStop = mAutoStopProfiler;
4923            }
4924            boolean enableOpenGlTrace = false;
4925            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4926                enableOpenGlTrace = true;
4927                mOpenGlTraceApp = null;
4928            }
4929
4930            // If the app is being launched for restore or full backup, set it up specially
4931            boolean isRestrictedBackupMode = false;
4932            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4933                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4934                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4935                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4936            }
4937
4938            ensurePackageDexOpt(app.instrumentationInfo != null
4939                    ? app.instrumentationInfo.packageName
4940                    : app.info.packageName);
4941            if (app.instrumentationClass != null) {
4942                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4943            }
4944            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4945                    + processName + " with config " + mConfiguration);
4946            ApplicationInfo appInfo = app.instrumentationInfo != null
4947                    ? app.instrumentationInfo : app.info;
4948            app.compat = compatibilityInfoForPackageLocked(appInfo);
4949            if (profileFd != null) {
4950                profileFd = profileFd.dup();
4951            }
4952            thread.bindApplication(processName, appInfo, providers,
4953                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4954                    app.instrumentationArguments, app.instrumentationWatcher,
4955                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
4956                    isRestrictedBackupMode || !normalMode, app.persistent,
4957                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4958                    mCoreSettingsObserver.getCoreSettingsLocked());
4959            updateLruProcessLocked(app, false, null);
4960            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4961        } catch (Exception e) {
4962            // todo: Yikes!  What should we do?  For now we will try to
4963            // start another process, but that could easily get us in
4964            // an infinite loop of restarting processes...
4965            Slog.w(TAG, "Exception thrown during bind!", e);
4966
4967            app.resetPackageList(mProcessStats);
4968            app.unlinkDeathRecipient();
4969            startProcessLocked(app, "bind fail", processName);
4970            return false;
4971        }
4972
4973        // Remove this record from the list of starting applications.
4974        mPersistentStartingProcesses.remove(app);
4975        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4976                "Attach application locked removing on hold: " + app);
4977        mProcessesOnHold.remove(app);
4978
4979        boolean badApp = false;
4980        boolean didSomething = false;
4981
4982        // See if the top visible activity is waiting to run in this process...
4983        if (normalMode) {
4984            try {
4985                if (mStackSupervisor.attachApplicationLocked(app)) {
4986                    didSomething = true;
4987                }
4988            } catch (Exception e) {
4989                badApp = true;
4990            }
4991        }
4992
4993        // Find any services that should be running in this process...
4994        if (!badApp) {
4995            try {
4996                didSomething |= mServices.attachApplicationLocked(app, processName);
4997            } catch (Exception e) {
4998                badApp = true;
4999            }
5000        }
5001
5002        // Check if a next-broadcast receiver is in this process...
5003        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5004            try {
5005                didSomething |= sendPendingBroadcastsLocked(app);
5006            } catch (Exception e) {
5007                // If the app died trying to launch the receiver we declare it 'bad'
5008                badApp = true;
5009            }
5010        }
5011
5012        // Check whether the next backup agent is in this process...
5013        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5014            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5015            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5016            try {
5017                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5018                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5019                        mBackupTarget.backupMode);
5020            } catch (Exception e) {
5021                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5022                e.printStackTrace();
5023            }
5024        }
5025
5026        if (badApp) {
5027            // todo: Also need to kill application to deal with all
5028            // kinds of exceptions.
5029            handleAppDiedLocked(app, false, true);
5030            return false;
5031        }
5032
5033        if (!didSomething) {
5034            updateOomAdjLocked();
5035        }
5036
5037        return true;
5038    }
5039
5040    @Override
5041    public final void attachApplication(IApplicationThread thread) {
5042        synchronized (this) {
5043            int callingPid = Binder.getCallingPid();
5044            final long origId = Binder.clearCallingIdentity();
5045            attachApplicationLocked(thread, callingPid);
5046            Binder.restoreCallingIdentity(origId);
5047        }
5048    }
5049
5050    @Override
5051    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5052        final long origId = Binder.clearCallingIdentity();
5053        synchronized (this) {
5054            ActivityStack stack = ActivityRecord.getStackLocked(token);
5055            if (stack != null) {
5056                ActivityRecord r =
5057                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5058                if (stopProfiling) {
5059                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5060                        try {
5061                            mProfileFd.close();
5062                        } catch (IOException e) {
5063                        }
5064                        clearProfilerLocked();
5065                    }
5066                }
5067            }
5068        }
5069        Binder.restoreCallingIdentity(origId);
5070    }
5071
5072    void enableScreenAfterBoot() {
5073        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5074                SystemClock.uptimeMillis());
5075        mWindowManager.enableScreenAfterBoot();
5076
5077        synchronized (this) {
5078            updateEventDispatchingLocked();
5079        }
5080    }
5081
5082    @Override
5083    public void showBootMessage(final CharSequence msg, final boolean always) {
5084        enforceNotIsolatedCaller("showBootMessage");
5085        mWindowManager.showBootMessage(msg, always);
5086    }
5087
5088    @Override
5089    public void dismissKeyguardOnNextActivity() {
5090        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5091        final long token = Binder.clearCallingIdentity();
5092        try {
5093            synchronized (this) {
5094                if (DEBUG_LOCKSCREEN) logLockScreen("");
5095                if (mLockScreenShown) {
5096                    mLockScreenShown = false;
5097                    comeOutOfSleepIfNeededLocked();
5098                }
5099                mStackSupervisor.setDismissKeyguard(true);
5100            }
5101        } finally {
5102            Binder.restoreCallingIdentity(token);
5103        }
5104    }
5105
5106    final void finishBooting() {
5107        IntentFilter pkgFilter = new IntentFilter();
5108        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
5109        pkgFilter.addDataScheme("package");
5110        mContext.registerReceiver(new BroadcastReceiver() {
5111            @Override
5112            public void onReceive(Context context, Intent intent) {
5113                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
5114                if (pkgs != null) {
5115                    for (String pkg : pkgs) {
5116                        synchronized (ActivityManagerService.this) {
5117                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
5118                                    "finished booting")) {
5119                                setResultCode(Activity.RESULT_OK);
5120                                return;
5121                            }
5122                        }
5123                    }
5124                }
5125            }
5126        }, pkgFilter);
5127
5128        synchronized (this) {
5129            // Ensure that any processes we had put on hold are now started
5130            // up.
5131            final int NP = mProcessesOnHold.size();
5132            if (NP > 0) {
5133                ArrayList<ProcessRecord> procs =
5134                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5135                for (int ip=0; ip<NP; ip++) {
5136                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5137                            + procs.get(ip));
5138                    startProcessLocked(procs.get(ip), "on-hold", null);
5139                }
5140            }
5141
5142            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5143                // Start looking for apps that are abusing wake locks.
5144                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5145                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5146                // Tell anyone interested that we are done booting!
5147                SystemProperties.set("sys.boot_completed", "1");
5148                SystemProperties.set("dev.bootcomplete", "1");
5149                for (int i=0; i<mStartedUsers.size(); i++) {
5150                    UserStartedState uss = mStartedUsers.valueAt(i);
5151                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5152                        uss.mState = UserStartedState.STATE_RUNNING;
5153                        final int userId = mStartedUsers.keyAt(i);
5154                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5155                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5156                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5157                        broadcastIntentLocked(null, null, intent, null,
5158                                new IIntentReceiver.Stub() {
5159                                    @Override
5160                                    public void performReceive(Intent intent, int resultCode,
5161                                            String data, Bundle extras, boolean ordered,
5162                                            boolean sticky, int sendingUser) {
5163                                        synchronized (ActivityManagerService.this) {
5164                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5165                                                    true, false);
5166                                        }
5167                                    }
5168                                },
5169                                0, null, null,
5170                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5171                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5172                                userId);
5173                    }
5174                }
5175                scheduleStartRelatedUsersLocked();
5176            }
5177        }
5178    }
5179
5180    final void ensureBootCompleted() {
5181        boolean booting;
5182        boolean enableScreen;
5183        synchronized (this) {
5184            booting = mBooting;
5185            mBooting = false;
5186            enableScreen = !mBooted;
5187            mBooted = true;
5188        }
5189
5190        if (booting) {
5191            finishBooting();
5192        }
5193
5194        if (enableScreen) {
5195            enableScreenAfterBoot();
5196        }
5197    }
5198
5199    @Override
5200    public final void activityResumed(IBinder token) {
5201        final long origId = Binder.clearCallingIdentity();
5202        synchronized(this) {
5203            ActivityStack stack = ActivityRecord.getStackLocked(token);
5204            if (stack != null) {
5205                ActivityRecord.activityResumedLocked(token);
5206            }
5207        }
5208        Binder.restoreCallingIdentity(origId);
5209    }
5210
5211    @Override
5212    public final void activityPaused(IBinder token) {
5213        final long origId = Binder.clearCallingIdentity();
5214        synchronized(this) {
5215            ActivityStack stack = ActivityRecord.getStackLocked(token);
5216            if (stack != null) {
5217                stack.activityPausedLocked(token, false);
5218            }
5219        }
5220        Binder.restoreCallingIdentity(origId);
5221    }
5222
5223    @Override
5224    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
5225            CharSequence description) {
5226        if (localLOGV) Slog.v(
5227            TAG, "Activity stopped: token=" + token);
5228
5229        // Refuse possible leaked file descriptors
5230        if (icicle != null && icicle.hasFileDescriptors()) {
5231            throw new IllegalArgumentException("File descriptors passed in Bundle");
5232        }
5233
5234        ActivityRecord r = null;
5235
5236        final long origId = Binder.clearCallingIdentity();
5237
5238        synchronized (this) {
5239            r = ActivityRecord.isInStackLocked(token);
5240            if (r != null) {
5241                r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description);
5242            }
5243        }
5244
5245        if (r != null) {
5246            sendPendingThumbnail(r, null, null, null, false);
5247        }
5248
5249        trimApplications();
5250
5251        Binder.restoreCallingIdentity(origId);
5252    }
5253
5254    @Override
5255    public final void activityDestroyed(IBinder token) {
5256        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5257        synchronized (this) {
5258            ActivityStack stack = ActivityRecord.getStackLocked(token);
5259            if (stack != null) {
5260                stack.activityDestroyedLocked(token);
5261            }
5262        }
5263    }
5264
5265    @Override
5266    public String getCallingPackage(IBinder token) {
5267        synchronized (this) {
5268            ActivityRecord r = getCallingRecordLocked(token);
5269            return r != null ? r.info.packageName : null;
5270        }
5271    }
5272
5273    @Override
5274    public ComponentName getCallingActivity(IBinder token) {
5275        synchronized (this) {
5276            ActivityRecord r = getCallingRecordLocked(token);
5277            return r != null ? r.intent.getComponent() : null;
5278        }
5279    }
5280
5281    private ActivityRecord getCallingRecordLocked(IBinder token) {
5282        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5283        if (r == null) {
5284            return null;
5285        }
5286        return r.resultTo;
5287    }
5288
5289    @Override
5290    public ComponentName getActivityClassForToken(IBinder token) {
5291        synchronized(this) {
5292            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5293            if (r == null) {
5294                return null;
5295            }
5296            return r.intent.getComponent();
5297        }
5298    }
5299
5300    @Override
5301    public String getPackageForToken(IBinder token) {
5302        synchronized(this) {
5303            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5304            if (r == null) {
5305                return null;
5306            }
5307            return r.packageName;
5308        }
5309    }
5310
5311    @Override
5312    public IIntentSender getIntentSender(int type,
5313            String packageName, IBinder token, String resultWho,
5314            int requestCode, Intent[] intents, String[] resolvedTypes,
5315            int flags, Bundle options, int userId) {
5316        enforceNotIsolatedCaller("getIntentSender");
5317        // Refuse possible leaked file descriptors
5318        if (intents != null) {
5319            if (intents.length < 1) {
5320                throw new IllegalArgumentException("Intents array length must be >= 1");
5321            }
5322            for (int i=0; i<intents.length; i++) {
5323                Intent intent = intents[i];
5324                if (intent != null) {
5325                    if (intent.hasFileDescriptors()) {
5326                        throw new IllegalArgumentException("File descriptors passed in Intent");
5327                    }
5328                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5329                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5330                        throw new IllegalArgumentException(
5331                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5332                    }
5333                    intents[i] = new Intent(intent);
5334                }
5335            }
5336            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5337                throw new IllegalArgumentException(
5338                        "Intent array length does not match resolvedTypes length");
5339            }
5340        }
5341        if (options != null) {
5342            if (options.hasFileDescriptors()) {
5343                throw new IllegalArgumentException("File descriptors passed in options");
5344            }
5345        }
5346
5347        synchronized(this) {
5348            int callingUid = Binder.getCallingUid();
5349            int origUserId = userId;
5350            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5351                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5352                    "getIntentSender", null);
5353            if (origUserId == UserHandle.USER_CURRENT) {
5354                // We don't want to evaluate this until the pending intent is
5355                // actually executed.  However, we do want to always do the
5356                // security checking for it above.
5357                userId = UserHandle.USER_CURRENT;
5358            }
5359            try {
5360                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5361                    int uid = AppGlobals.getPackageManager()
5362                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5363                    if (!UserHandle.isSameApp(callingUid, uid)) {
5364                        String msg = "Permission Denial: getIntentSender() from pid="
5365                            + Binder.getCallingPid()
5366                            + ", uid=" + Binder.getCallingUid()
5367                            + ", (need uid=" + uid + ")"
5368                            + " is not allowed to send as package " + packageName;
5369                        Slog.w(TAG, msg);
5370                        throw new SecurityException(msg);
5371                    }
5372                }
5373
5374                return getIntentSenderLocked(type, packageName, callingUid, userId,
5375                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5376
5377            } catch (RemoteException e) {
5378                throw new SecurityException(e);
5379            }
5380        }
5381    }
5382
5383    IIntentSender getIntentSenderLocked(int type, String packageName,
5384            int callingUid, int userId, IBinder token, String resultWho,
5385            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5386            Bundle options) {
5387        if (DEBUG_MU)
5388            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5389        ActivityRecord activity = null;
5390        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5391            activity = ActivityRecord.isInStackLocked(token);
5392            if (activity == null) {
5393                return null;
5394            }
5395            if (activity.finishing) {
5396                return null;
5397            }
5398        }
5399
5400        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5401        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5402        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5403        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5404                |PendingIntent.FLAG_UPDATE_CURRENT);
5405
5406        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5407                type, packageName, activity, resultWho,
5408                requestCode, intents, resolvedTypes, flags, options, userId);
5409        WeakReference<PendingIntentRecord> ref;
5410        ref = mIntentSenderRecords.get(key);
5411        PendingIntentRecord rec = ref != null ? ref.get() : null;
5412        if (rec != null) {
5413            if (!cancelCurrent) {
5414                if (updateCurrent) {
5415                    if (rec.key.requestIntent != null) {
5416                        rec.key.requestIntent.replaceExtras(intents != null ?
5417                                intents[intents.length - 1] : null);
5418                    }
5419                    if (intents != null) {
5420                        intents[intents.length-1] = rec.key.requestIntent;
5421                        rec.key.allIntents = intents;
5422                        rec.key.allResolvedTypes = resolvedTypes;
5423                    } else {
5424                        rec.key.allIntents = null;
5425                        rec.key.allResolvedTypes = null;
5426                    }
5427                }
5428                return rec;
5429            }
5430            rec.canceled = true;
5431            mIntentSenderRecords.remove(key);
5432        }
5433        if (noCreate) {
5434            return rec;
5435        }
5436        rec = new PendingIntentRecord(this, key, callingUid);
5437        mIntentSenderRecords.put(key, rec.ref);
5438        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5439            if (activity.pendingResults == null) {
5440                activity.pendingResults
5441                        = new HashSet<WeakReference<PendingIntentRecord>>();
5442            }
5443            activity.pendingResults.add(rec.ref);
5444        }
5445        return rec;
5446    }
5447
5448    @Override
5449    public void cancelIntentSender(IIntentSender sender) {
5450        if (!(sender instanceof PendingIntentRecord)) {
5451            return;
5452        }
5453        synchronized(this) {
5454            PendingIntentRecord rec = (PendingIntentRecord)sender;
5455            try {
5456                int uid = AppGlobals.getPackageManager()
5457                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5458                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5459                    String msg = "Permission Denial: cancelIntentSender() from pid="
5460                        + Binder.getCallingPid()
5461                        + ", uid=" + Binder.getCallingUid()
5462                        + " is not allowed to cancel packges "
5463                        + rec.key.packageName;
5464                    Slog.w(TAG, msg);
5465                    throw new SecurityException(msg);
5466                }
5467            } catch (RemoteException e) {
5468                throw new SecurityException(e);
5469            }
5470            cancelIntentSenderLocked(rec, true);
5471        }
5472    }
5473
5474    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5475        rec.canceled = true;
5476        mIntentSenderRecords.remove(rec.key);
5477        if (cleanActivity && rec.key.activity != null) {
5478            rec.key.activity.pendingResults.remove(rec.ref);
5479        }
5480    }
5481
5482    @Override
5483    public String getPackageForIntentSender(IIntentSender pendingResult) {
5484        if (!(pendingResult instanceof PendingIntentRecord)) {
5485            return null;
5486        }
5487        try {
5488            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5489            return res.key.packageName;
5490        } catch (ClassCastException e) {
5491        }
5492        return null;
5493    }
5494
5495    @Override
5496    public int getUidForIntentSender(IIntentSender sender) {
5497        if (sender instanceof PendingIntentRecord) {
5498            try {
5499                PendingIntentRecord res = (PendingIntentRecord)sender;
5500                return res.uid;
5501            } catch (ClassCastException e) {
5502            }
5503        }
5504        return -1;
5505    }
5506
5507    @Override
5508    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5509        if (!(pendingResult instanceof PendingIntentRecord)) {
5510            return false;
5511        }
5512        try {
5513            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5514            if (res.key.allIntents == null) {
5515                return false;
5516            }
5517            for (int i=0; i<res.key.allIntents.length; i++) {
5518                Intent intent = res.key.allIntents[i];
5519                if (intent.getPackage() != null && intent.getComponent() != null) {
5520                    return false;
5521                }
5522            }
5523            return true;
5524        } catch (ClassCastException e) {
5525        }
5526        return false;
5527    }
5528
5529    @Override
5530    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5531        if (!(pendingResult instanceof PendingIntentRecord)) {
5532            return false;
5533        }
5534        try {
5535            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5536            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5537                return true;
5538            }
5539            return false;
5540        } catch (ClassCastException e) {
5541        }
5542        return false;
5543    }
5544
5545    @Override
5546    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5547        if (!(pendingResult instanceof PendingIntentRecord)) {
5548            return null;
5549        }
5550        try {
5551            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5552            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5553        } catch (ClassCastException e) {
5554        }
5555        return null;
5556    }
5557
5558    @Override
5559    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5560        if (!(pendingResult instanceof PendingIntentRecord)) {
5561            return null;
5562        }
5563        try {
5564            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5565            Intent intent = res.key.requestIntent;
5566            if (intent != null) {
5567                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5568                        || res.lastTagPrefix.equals(prefix))) {
5569                    return res.lastTag;
5570                }
5571                res.lastTagPrefix = prefix;
5572                StringBuilder sb = new StringBuilder(128);
5573                if (prefix != null) {
5574                    sb.append(prefix);
5575                }
5576                if (intent.getAction() != null) {
5577                    sb.append(intent.getAction());
5578                } else if (intent.getComponent() != null) {
5579                    intent.getComponent().appendShortString(sb);
5580                } else {
5581                    sb.append("?");
5582                }
5583                return res.lastTag = sb.toString();
5584            }
5585        } catch (ClassCastException e) {
5586        }
5587        return null;
5588    }
5589
5590    @Override
5591    public void setProcessLimit(int max) {
5592        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5593                "setProcessLimit()");
5594        synchronized (this) {
5595            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5596            mProcessLimitOverride = max;
5597        }
5598        trimApplications();
5599    }
5600
5601    @Override
5602    public int getProcessLimit() {
5603        synchronized (this) {
5604            return mProcessLimitOverride;
5605        }
5606    }
5607
5608    void foregroundTokenDied(ForegroundToken token) {
5609        synchronized (ActivityManagerService.this) {
5610            synchronized (mPidsSelfLocked) {
5611                ForegroundToken cur
5612                    = mForegroundProcesses.get(token.pid);
5613                if (cur != token) {
5614                    return;
5615                }
5616                mForegroundProcesses.remove(token.pid);
5617                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5618                if (pr == null) {
5619                    return;
5620                }
5621                pr.forcingToForeground = null;
5622                updateProcessForegroundLocked(pr, false, false);
5623            }
5624            updateOomAdjLocked();
5625        }
5626    }
5627
5628    @Override
5629    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5630        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5631                "setProcessForeground()");
5632        synchronized(this) {
5633            boolean changed = false;
5634
5635            synchronized (mPidsSelfLocked) {
5636                ProcessRecord pr = mPidsSelfLocked.get(pid);
5637                if (pr == null && isForeground) {
5638                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5639                    return;
5640                }
5641                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5642                if (oldToken != null) {
5643                    oldToken.token.unlinkToDeath(oldToken, 0);
5644                    mForegroundProcesses.remove(pid);
5645                    if (pr != null) {
5646                        pr.forcingToForeground = null;
5647                    }
5648                    changed = true;
5649                }
5650                if (isForeground && token != null) {
5651                    ForegroundToken newToken = new ForegroundToken() {
5652                        @Override
5653                        public void binderDied() {
5654                            foregroundTokenDied(this);
5655                        }
5656                    };
5657                    newToken.pid = pid;
5658                    newToken.token = token;
5659                    try {
5660                        token.linkToDeath(newToken, 0);
5661                        mForegroundProcesses.put(pid, newToken);
5662                        pr.forcingToForeground = token;
5663                        changed = true;
5664                    } catch (RemoteException e) {
5665                        // If the process died while doing this, we will later
5666                        // do the cleanup with the process death link.
5667                    }
5668                }
5669            }
5670
5671            if (changed) {
5672                updateOomAdjLocked();
5673            }
5674        }
5675    }
5676
5677    // =========================================================
5678    // PERMISSIONS
5679    // =========================================================
5680
5681    static class PermissionController extends IPermissionController.Stub {
5682        ActivityManagerService mActivityManagerService;
5683        PermissionController(ActivityManagerService activityManagerService) {
5684            mActivityManagerService = activityManagerService;
5685        }
5686
5687        @Override
5688        public boolean checkPermission(String permission, int pid, int uid) {
5689            return mActivityManagerService.checkPermission(permission, pid,
5690                    uid) == PackageManager.PERMISSION_GRANTED;
5691        }
5692    }
5693
5694    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5695        @Override
5696        public int checkComponentPermission(String permission, int pid, int uid,
5697                int owningUid, boolean exported) {
5698            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5699                    owningUid, exported);
5700        }
5701
5702        @Override
5703        public Object getAMSLock() {
5704            return ActivityManagerService.this;
5705        }
5706    }
5707
5708    /**
5709     * This can be called with or without the global lock held.
5710     */
5711    int checkComponentPermission(String permission, int pid, int uid,
5712            int owningUid, boolean exported) {
5713        // We might be performing an operation on behalf of an indirect binder
5714        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5715        // client identity accordingly before proceeding.
5716        Identity tlsIdentity = sCallerIdentity.get();
5717        if (tlsIdentity != null) {
5718            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5719                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5720            uid = tlsIdentity.uid;
5721            pid = tlsIdentity.pid;
5722        }
5723
5724        if (pid == MY_PID) {
5725            return PackageManager.PERMISSION_GRANTED;
5726        }
5727
5728        return ActivityManager.checkComponentPermission(permission, uid,
5729                owningUid, exported);
5730    }
5731
5732    /**
5733     * As the only public entry point for permissions checking, this method
5734     * can enforce the semantic that requesting a check on a null global
5735     * permission is automatically denied.  (Internally a null permission
5736     * string is used when calling {@link #checkComponentPermission} in cases
5737     * when only uid-based security is needed.)
5738     *
5739     * This can be called with or without the global lock held.
5740     */
5741    @Override
5742    public int checkPermission(String permission, int pid, int uid) {
5743        if (permission == null) {
5744            return PackageManager.PERMISSION_DENIED;
5745        }
5746        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5747    }
5748
5749    /**
5750     * Binder IPC calls go through the public entry point.
5751     * This can be called with or without the global lock held.
5752     */
5753    int checkCallingPermission(String permission) {
5754        return checkPermission(permission,
5755                Binder.getCallingPid(),
5756                UserHandle.getAppId(Binder.getCallingUid()));
5757    }
5758
5759    /**
5760     * This can be called with or without the global lock held.
5761     */
5762    void enforceCallingPermission(String permission, String func) {
5763        if (checkCallingPermission(permission)
5764                == PackageManager.PERMISSION_GRANTED) {
5765            return;
5766        }
5767
5768        String msg = "Permission Denial: " + func + " from pid="
5769                + Binder.getCallingPid()
5770                + ", uid=" + Binder.getCallingUid()
5771                + " requires " + permission;
5772        Slog.w(TAG, msg);
5773        throw new SecurityException(msg);
5774    }
5775
5776    /**
5777     * Determine if UID is holding permissions required to access {@link Uri} in
5778     * the given {@link ProviderInfo}. Final permission checking is always done
5779     * in {@link ContentProvider}.
5780     */
5781    private final boolean checkHoldingPermissionsLocked(
5782            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
5783        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5784                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
5785
5786        if (pi.applicationInfo.uid == uid) {
5787            return true;
5788        } else if (!pi.exported) {
5789            return false;
5790        }
5791
5792        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
5793        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
5794        try {
5795            // check if target holds top-level <provider> permissions
5796            if (!readMet && pi.readPermission != null
5797                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
5798                readMet = true;
5799            }
5800            if (!writeMet && pi.writePermission != null
5801                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
5802                writeMet = true;
5803            }
5804
5805            // track if unprotected read/write is allowed; any denied
5806            // <path-permission> below removes this ability
5807            boolean allowDefaultRead = pi.readPermission == null;
5808            boolean allowDefaultWrite = pi.writePermission == null;
5809
5810            // check if target holds any <path-permission> that match uri
5811            final PathPermission[] pps = pi.pathPermissions;
5812            if (pps != null) {
5813                final String path = uri.getPath();
5814                int i = pps.length;
5815                while (i > 0 && (!readMet || !writeMet)) {
5816                    i--;
5817                    PathPermission pp = pps[i];
5818                    if (pp.match(path)) {
5819                        if (!readMet) {
5820                            final String pprperm = pp.getReadPermission();
5821                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
5822                                    + pprperm + " for " + pp.getPath()
5823                                    + ": match=" + pp.match(path)
5824                                    + " check=" + pm.checkUidPermission(pprperm, uid));
5825                            if (pprperm != null) {
5826                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
5827                                    readMet = true;
5828                                } else {
5829                                    allowDefaultRead = false;
5830                                }
5831                            }
5832                        }
5833                        if (!writeMet) {
5834                            final String ppwperm = pp.getWritePermission();
5835                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
5836                                    + ppwperm + " for " + pp.getPath()
5837                                    + ": match=" + pp.match(path)
5838                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
5839                            if (ppwperm != null) {
5840                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
5841                                    writeMet = true;
5842                                } else {
5843                                    allowDefaultWrite = false;
5844                                }
5845                            }
5846                        }
5847                    }
5848                }
5849            }
5850
5851            // grant unprotected <provider> read/write, if not blocked by
5852            // <path-permission> above
5853            if (allowDefaultRead) readMet = true;
5854            if (allowDefaultWrite) writeMet = true;
5855
5856        } catch (RemoteException e) {
5857            return false;
5858        }
5859
5860        return readMet && writeMet;
5861    }
5862
5863    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
5864        ProviderInfo pi = null;
5865        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
5866        if (cpr != null) {
5867            pi = cpr.info;
5868        } else {
5869            try {
5870                pi = AppGlobals.getPackageManager().resolveContentProvider(
5871                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
5872            } catch (RemoteException ex) {
5873            }
5874        }
5875        return pi;
5876    }
5877
5878    private UriPermission findUriPermissionLocked(int targetUid, Uri uri) {
5879        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5880        if (targetUris != null) {
5881            return targetUris.get(uri);
5882        } else {
5883            return null;
5884        }
5885    }
5886
5887    private UriPermission findOrCreateUriPermissionLocked(
5888            String sourcePkg, String targetPkg, int targetUid, Uri uri) {
5889        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5890        if (targetUris == null) {
5891            targetUris = Maps.newArrayMap();
5892            mGrantedUriPermissions.put(targetUid, targetUris);
5893        }
5894
5895        UriPermission perm = targetUris.get(uri);
5896        if (perm == null) {
5897            perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri);
5898            targetUris.put(uri, perm);
5899        }
5900
5901        return perm;
5902    }
5903
5904    private final boolean checkUriPermissionLocked(
5905            Uri uri, int uid, int modeFlags, int minStrength) {
5906        // Root gets to do everything.
5907        if (uid == 0) {
5908            return true;
5909        }
5910        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5911        if (perms == null) return false;
5912        UriPermission perm = perms.get(uri);
5913        if (perm == null) return false;
5914        return perm.getStrength(modeFlags) >= minStrength;
5915    }
5916
5917    @Override
5918    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
5919        enforceNotIsolatedCaller("checkUriPermission");
5920
5921        // Another redirected-binder-call permissions check as in
5922        // {@link checkComponentPermission}.
5923        Identity tlsIdentity = sCallerIdentity.get();
5924        if (tlsIdentity != null) {
5925            uid = tlsIdentity.uid;
5926            pid = tlsIdentity.pid;
5927        }
5928
5929        // Our own process gets to do everything.
5930        if (pid == MY_PID) {
5931            return PackageManager.PERMISSION_GRANTED;
5932        }
5933        synchronized(this) {
5934            return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED)
5935                    ? PackageManager.PERMISSION_GRANTED
5936                    : PackageManager.PERMISSION_DENIED;
5937        }
5938    }
5939
5940    /**
5941     * Check if the targetPkg can be granted permission to access uri by
5942     * the callingUid using the given modeFlags.  Throws a security exception
5943     * if callingUid is not allowed to do this.  Returns the uid of the target
5944     * if the URI permission grant should be performed; returns -1 if it is not
5945     * needed (for example targetPkg already has permission to access the URI).
5946     * If you already know the uid of the target, you can supply it in
5947     * lastTargetUid else set that to -1.
5948     */
5949    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5950            Uri uri, int modeFlags, int lastTargetUid) {
5951        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
5952        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5953                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5954        if (modeFlags == 0) {
5955            return -1;
5956        }
5957
5958        if (targetPkg != null) {
5959            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5960                    "Checking grant " + targetPkg + " permission to " + uri);
5961        }
5962
5963        final IPackageManager pm = AppGlobals.getPackageManager();
5964
5965        // If this is not a content: uri, we can't do anything with it.
5966        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
5967            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5968                    "Can't grant URI permission for non-content URI: " + uri);
5969            return -1;
5970        }
5971
5972        final String authority = uri.getAuthority();
5973        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
5974        if (pi == null) {
5975            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
5976            return -1;
5977        }
5978
5979        int targetUid = lastTargetUid;
5980        if (targetUid < 0 && targetPkg != null) {
5981            try {
5982                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
5983                if (targetUid < 0) {
5984                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5985                            "Can't grant URI permission no uid for: " + targetPkg);
5986                    return -1;
5987                }
5988            } catch (RemoteException ex) {
5989                return -1;
5990            }
5991        }
5992
5993        if (targetUid >= 0) {
5994            // First...  does the target actually need this permission?
5995            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
5996                // No need to grant the target this permission.
5997                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5998                        "Target " + targetPkg + " already has full permission to " + uri);
5999                return -1;
6000            }
6001        } else {
6002            // First...  there is no target package, so can anyone access it?
6003            boolean allowed = pi.exported;
6004            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6005                if (pi.readPermission != null) {
6006                    allowed = false;
6007                }
6008            }
6009            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6010                if (pi.writePermission != null) {
6011                    allowed = false;
6012                }
6013            }
6014            if (allowed) {
6015                return -1;
6016            }
6017        }
6018
6019        // Second...  is the provider allowing granting of URI permissions?
6020        if (!pi.grantUriPermissions) {
6021            throw new SecurityException("Provider " + pi.packageName
6022                    + "/" + pi.name
6023                    + " does not allow granting of Uri permissions (uri "
6024                    + uri + ")");
6025        }
6026        if (pi.uriPermissionPatterns != null) {
6027            final int N = pi.uriPermissionPatterns.length;
6028            boolean allowed = false;
6029            for (int i=0; i<N; i++) {
6030                if (pi.uriPermissionPatterns[i] != null
6031                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
6032                    allowed = true;
6033                    break;
6034                }
6035            }
6036            if (!allowed) {
6037                throw new SecurityException("Provider " + pi.packageName
6038                        + "/" + pi.name
6039                        + " does not allow granting of permission to path of Uri "
6040                        + uri);
6041            }
6042        }
6043
6044        // Third...  does the caller itself have permission to access
6045        // this uri?
6046        if (callingUid != Process.myUid()) {
6047            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6048                // Require they hold a strong enough Uri permission
6049                final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6050                        : UriPermission.STRENGTH_OWNED;
6051                if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) {
6052                    throw new SecurityException("Uid " + callingUid
6053                            + " does not have permission to uri " + uri);
6054                }
6055            }
6056        }
6057
6058        return targetUid;
6059    }
6060
6061    @Override
6062    public int checkGrantUriPermission(int callingUid, String targetPkg,
6063            Uri uri, int modeFlags) {
6064        enforceNotIsolatedCaller("checkGrantUriPermission");
6065        synchronized(this) {
6066            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6067        }
6068    }
6069
6070    void grantUriPermissionUncheckedLocked(
6071            int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
6072        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6073        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6074                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6075        if (modeFlags == 0) {
6076            return;
6077        }
6078
6079        // So here we are: the caller has the assumed permission
6080        // to the uri, and the target doesn't.  Let's now give this to
6081        // the target.
6082
6083        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6084                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
6085
6086        final String authority = uri.getAuthority();
6087        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid));
6088        if (pi == null) {
6089            Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString());
6090            return;
6091        }
6092
6093        final UriPermission perm = findOrCreateUriPermissionLocked(
6094                pi.packageName, targetPkg, targetUid, uri);
6095        perm.grantModes(modeFlags, persistable, owner);
6096    }
6097
6098    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
6099            int modeFlags, UriPermissionOwner owner) {
6100        if (targetPkg == null) {
6101            throw new NullPointerException("targetPkg");
6102        }
6103
6104        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6105        if (targetUid < 0) {
6106            return;
6107        }
6108
6109        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
6110    }
6111
6112    static class NeededUriGrants extends ArrayList<Uri> {
6113        final String targetPkg;
6114        final int targetUid;
6115        final int flags;
6116
6117        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6118            this.targetPkg = targetPkg;
6119            this.targetUid = targetUid;
6120            this.flags = flags;
6121        }
6122    }
6123
6124    /**
6125     * Like checkGrantUriPermissionLocked, but takes an Intent.
6126     */
6127    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6128            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6129        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6130                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6131                + " clip=" + (intent != null ? intent.getClipData() : null)
6132                + " from " + intent + "; flags=0x"
6133                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6134
6135        if (targetPkg == null) {
6136            throw new NullPointerException("targetPkg");
6137        }
6138
6139        if (intent == null) {
6140            return null;
6141        }
6142        Uri data = intent.getData();
6143        ClipData clip = intent.getClipData();
6144        if (data == null && clip == null) {
6145            return null;
6146        }
6147
6148        if (data != null) {
6149            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
6150                mode, needed != null ? needed.targetUid : -1);
6151            if (targetUid > 0) {
6152                if (needed == null) {
6153                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6154                }
6155                needed.add(data);
6156            }
6157        }
6158        if (clip != null) {
6159            for (int i=0; i<clip.getItemCount(); i++) {
6160                Uri uri = clip.getItemAt(i).getUri();
6161                if (uri != null) {
6162                    int targetUid = -1;
6163                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
6164                            mode, needed != null ? needed.targetUid : -1);
6165                    if (targetUid > 0) {
6166                        if (needed == null) {
6167                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6168                        }
6169                        needed.add(uri);
6170                    }
6171                } else {
6172                    Intent clipIntent = clip.getItemAt(i).getIntent();
6173                    if (clipIntent != null) {
6174                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6175                                callingUid, targetPkg, clipIntent, mode, needed);
6176                        if (newNeeded != null) {
6177                            needed = newNeeded;
6178                        }
6179                    }
6180                }
6181            }
6182        }
6183
6184        return needed;
6185    }
6186
6187    /**
6188     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6189     */
6190    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6191            UriPermissionOwner owner) {
6192        if (needed != null) {
6193            for (int i=0; i<needed.size(); i++) {
6194                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6195                        needed.get(i), needed.flags, owner);
6196            }
6197        }
6198    }
6199
6200    void grantUriPermissionFromIntentLocked(int callingUid,
6201            String targetPkg, Intent intent, UriPermissionOwner owner) {
6202        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6203                intent, intent != null ? intent.getFlags() : 0, null);
6204        if (needed == null) {
6205            return;
6206        }
6207
6208        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6209    }
6210
6211    @Override
6212    public void grantUriPermission(IApplicationThread caller, String targetPkg,
6213            Uri uri, int modeFlags) {
6214        enforceNotIsolatedCaller("grantUriPermission");
6215        synchronized(this) {
6216            final ProcessRecord r = getRecordForAppLocked(caller);
6217            if (r == null) {
6218                throw new SecurityException("Unable to find app for caller "
6219                        + caller
6220                        + " when granting permission to uri " + uri);
6221            }
6222            if (targetPkg == null) {
6223                throw new IllegalArgumentException("null target");
6224            }
6225            if (uri == null) {
6226                throw new IllegalArgumentException("null uri");
6227            }
6228
6229            // Persistable only supported through Intents
6230            Preconditions.checkFlagsArgument(modeFlags,
6231                    Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6232
6233            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
6234                    null);
6235        }
6236    }
6237
6238    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6239        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
6240                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
6241            ArrayMap<Uri, UriPermission> perms
6242                    = mGrantedUriPermissions.get(perm.targetUid);
6243            if (perms != null) {
6244                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6245                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6246                perms.remove(perm.uri);
6247                if (perms.size() == 0) {
6248                    mGrantedUriPermissions.remove(perm.targetUid);
6249                }
6250            }
6251        }
6252    }
6253
6254    private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) {
6255        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri);
6256
6257        final IPackageManager pm = AppGlobals.getPackageManager();
6258        final String authority = uri.getAuthority();
6259        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6260        if (pi == null) {
6261            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
6262            return;
6263        }
6264
6265        // Does the caller have this permission on the URI?
6266        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6267            // Right now, if you are not the original owner of the permission,
6268            // you are not allowed to revoke it.
6269            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6270                throw new SecurityException("Uid " + callingUid
6271                        + " does not have permission to uri " + uri);
6272            //}
6273        }
6274
6275        boolean persistChanged = false;
6276
6277        // Go through all of the permissions and remove any that match.
6278        final List<String> SEGMENTS = uri.getPathSegments();
6279        if (SEGMENTS != null) {
6280            final int NS = SEGMENTS.size();
6281            int N = mGrantedUriPermissions.size();
6282            for (int i=0; i<N; i++) {
6283                ArrayMap<Uri, UriPermission> perms
6284                        = mGrantedUriPermissions.valueAt(i);
6285                Iterator<UriPermission> it = perms.values().iterator();
6286            toploop:
6287                while (it.hasNext()) {
6288                    UriPermission perm = it.next();
6289                    Uri targetUri = perm.uri;
6290                    if (!authority.equals(targetUri.getAuthority())) {
6291                        continue;
6292                    }
6293                    List<String> targetSegments = targetUri.getPathSegments();
6294                    if (targetSegments == null) {
6295                        continue;
6296                    }
6297                    if (targetSegments.size() < NS) {
6298                        continue;
6299                    }
6300                    for (int j=0; j<NS; j++) {
6301                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
6302                            continue toploop;
6303                        }
6304                    }
6305                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6306                            "Revoking " + perm.targetUid + " permission to " + perm.uri);
6307                    persistChanged |= perm.clearModes(modeFlags, true);
6308                    if (perm.modeFlags == 0) {
6309                        it.remove();
6310                    }
6311                }
6312                if (perms.size() == 0) {
6313                    mGrantedUriPermissions.remove(
6314                            mGrantedUriPermissions.keyAt(i));
6315                    N--;
6316                    i--;
6317                }
6318            }
6319        }
6320
6321        if (persistChanged) {
6322            schedulePersistUriGrants();
6323        }
6324    }
6325
6326    @Override
6327    public void revokeUriPermission(IApplicationThread caller, Uri uri,
6328            int modeFlags) {
6329        enforceNotIsolatedCaller("revokeUriPermission");
6330        synchronized(this) {
6331            final ProcessRecord r = getRecordForAppLocked(caller);
6332            if (r == null) {
6333                throw new SecurityException("Unable to find app for caller "
6334                        + caller
6335                        + " when revoking permission to uri " + uri);
6336            }
6337            if (uri == null) {
6338                Slog.w(TAG, "revokeUriPermission: null uri");
6339                return;
6340            }
6341
6342            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6343                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6344            if (modeFlags == 0) {
6345                return;
6346            }
6347
6348            final IPackageManager pm = AppGlobals.getPackageManager();
6349            final String authority = uri.getAuthority();
6350            final ProviderInfo pi = getProviderInfoLocked(authority, r.userId);
6351            if (pi == null) {
6352                Slog.w(TAG, "No content provider found for permission revoke: "
6353                        + uri.toSafeString());
6354                return;
6355            }
6356
6357            revokeUriPermissionLocked(r.uid, uri, modeFlags);
6358        }
6359    }
6360
6361    /**
6362     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6363     * given package.
6364     *
6365     * @param packageName Package name to match, or {@code null} to apply to all
6366     *            packages.
6367     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6368     *            to all users.
6369     * @param persistable If persistable grants should be removed.
6370     */
6371    private void removeUriPermissionsForPackageLocked(
6372            String packageName, int userHandle, boolean persistable) {
6373        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6374            throw new IllegalArgumentException("Must narrow by either package or user");
6375        }
6376
6377        boolean persistChanged = false;
6378
6379        final int size = mGrantedUriPermissions.size();
6380        for (int i = 0; i < size; i++) {
6381            // Only inspect grants matching user
6382            if (userHandle == UserHandle.USER_ALL
6383                    || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) {
6384                final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i)
6385                        .values().iterator();
6386                while (it.hasNext()) {
6387                    final UriPermission perm = it.next();
6388
6389                    // Only inspect grants matching package
6390                    if (packageName == null || perm.sourcePkg.equals(packageName)
6391                            || perm.targetPkg.equals(packageName)) {
6392                        persistChanged |= perm.clearModes(~0, persistable);
6393
6394                        // Only remove when no modes remain; any persisted grants
6395                        // will keep this alive.
6396                        if (perm.modeFlags == 0) {
6397                            it.remove();
6398                        }
6399                    }
6400                }
6401            }
6402        }
6403
6404        if (persistChanged) {
6405            schedulePersistUriGrants();
6406        }
6407    }
6408
6409    @Override
6410    public IBinder newUriPermissionOwner(String name) {
6411        enforceNotIsolatedCaller("newUriPermissionOwner");
6412        synchronized(this) {
6413            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6414            return owner.getExternalTokenLocked();
6415        }
6416    }
6417
6418    @Override
6419    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
6420            Uri uri, int modeFlags) {
6421        synchronized(this) {
6422            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6423            if (owner == null) {
6424                throw new IllegalArgumentException("Unknown owner: " + token);
6425            }
6426            if (fromUid != Binder.getCallingUid()) {
6427                if (Binder.getCallingUid() != Process.myUid()) {
6428                    // Only system code can grant URI permissions on behalf
6429                    // of other users.
6430                    throw new SecurityException("nice try");
6431                }
6432            }
6433            if (targetPkg == null) {
6434                throw new IllegalArgumentException("null target");
6435            }
6436            if (uri == null) {
6437                throw new IllegalArgumentException("null uri");
6438            }
6439
6440            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
6441        }
6442    }
6443
6444    @Override
6445    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
6446        synchronized(this) {
6447            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6448            if (owner == null) {
6449                throw new IllegalArgumentException("Unknown owner: " + token);
6450            }
6451
6452            if (uri == null) {
6453                owner.removeUriPermissionsLocked(mode);
6454            } else {
6455                owner.removeUriPermissionLocked(uri, mode);
6456            }
6457        }
6458    }
6459
6460    private void schedulePersistUriGrants() {
6461        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6462            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6463                    10 * DateUtils.SECOND_IN_MILLIS);
6464        }
6465    }
6466
6467    private void writeGrantedUriPermissions() {
6468        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6469
6470        // Snapshot permissions so we can persist without lock
6471        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6472        synchronized (this) {
6473            final int size = mGrantedUriPermissions.size();
6474            for (int i = 0 ; i < size; i++) {
6475                for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) {
6476                    if (perm.persistedModeFlags != 0) {
6477                        persist.add(perm.snapshot());
6478                    }
6479                }
6480            }
6481        }
6482
6483        FileOutputStream fos = null;
6484        try {
6485            fos = mGrantFile.startWrite();
6486
6487            XmlSerializer out = new FastXmlSerializer();
6488            out.setOutput(fos, "utf-8");
6489            out.startDocument(null, true);
6490            out.startTag(null, TAG_URI_GRANTS);
6491            for (UriPermission.Snapshot perm : persist) {
6492                out.startTag(null, TAG_URI_GRANT);
6493                writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle);
6494                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6495                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6496                out.attribute(null, ATTR_URI, String.valueOf(perm.uri));
6497                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6498                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6499                out.endTag(null, TAG_URI_GRANT);
6500            }
6501            out.endTag(null, TAG_URI_GRANTS);
6502            out.endDocument();
6503
6504            mGrantFile.finishWrite(fos);
6505        } catch (IOException e) {
6506            if (fos != null) {
6507                mGrantFile.failWrite(fos);
6508            }
6509        }
6510    }
6511
6512    private void readGrantedUriPermissionsLocked() {
6513        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6514
6515        final long now = System.currentTimeMillis();
6516
6517        FileInputStream fis = null;
6518        try {
6519            fis = mGrantFile.openRead();
6520            final XmlPullParser in = Xml.newPullParser();
6521            in.setInput(fis, null);
6522
6523            int type;
6524            while ((type = in.next()) != END_DOCUMENT) {
6525                final String tag = in.getName();
6526                if (type == START_TAG) {
6527                    if (TAG_URI_GRANT.equals(tag)) {
6528                        final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE);
6529                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6530                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6531                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6532                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6533                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6534
6535                        // Sanity check that provider still belongs to source package
6536                        final ProviderInfo pi = getProviderInfoLocked(
6537                                uri.getAuthority(), userHandle);
6538                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6539                            int targetUid = -1;
6540                            try {
6541                                targetUid = AppGlobals.getPackageManager()
6542                                        .getPackageUid(targetPkg, userHandle);
6543                            } catch (RemoteException e) {
6544                            }
6545                            if (targetUid != -1) {
6546                                final UriPermission perm = findOrCreateUriPermissionLocked(
6547                                        sourcePkg, targetPkg, targetUid, uri);
6548                                perm.initPersistedModes(modeFlags, createdTime);
6549                            }
6550                        } else {
6551                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6552                                    + " but instead found " + pi);
6553                        }
6554                    }
6555                }
6556            }
6557        } catch (FileNotFoundException e) {
6558            // Missing grants is okay
6559        } catch (IOException e) {
6560            Log.wtf(TAG, "Failed reading Uri grants", e);
6561        } catch (XmlPullParserException e) {
6562            Log.wtf(TAG, "Failed reading Uri grants", e);
6563        } finally {
6564            IoUtils.closeQuietly(fis);
6565        }
6566    }
6567
6568    @Override
6569    public void takePersistableUriPermission(Uri uri, int modeFlags) {
6570        enforceNotIsolatedCaller("takePersistableUriPermission");
6571
6572        Preconditions.checkFlagsArgument(modeFlags,
6573                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6574
6575        synchronized (this) {
6576            final int callingUid = Binder.getCallingUid();
6577            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6578            if (perm == null) {
6579                throw new SecurityException("No permission grant found for UID " + callingUid
6580                        + " and Uri " + uri.toSafeString());
6581            }
6582
6583            boolean persistChanged = perm.takePersistableModes(modeFlags);
6584            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6585
6586            if (persistChanged) {
6587                schedulePersistUriGrants();
6588            }
6589        }
6590    }
6591
6592    @Override
6593    public void releasePersistableUriPermission(Uri uri, int modeFlags) {
6594        enforceNotIsolatedCaller("releasePersistableUriPermission");
6595
6596        Preconditions.checkFlagsArgument(modeFlags,
6597                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6598
6599        synchronized (this) {
6600            final int callingUid = Binder.getCallingUid();
6601
6602            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6603            if (perm == null) {
6604                Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri "
6605                        + uri.toSafeString());
6606                return;
6607            }
6608
6609            final boolean persistChanged = perm.releasePersistableModes(modeFlags);
6610            removeUriPermissionIfNeededLocked(perm);
6611            if (persistChanged) {
6612                schedulePersistUriGrants();
6613            }
6614        }
6615    }
6616
6617    /**
6618     * Prune any older {@link UriPermission} for the given UID until outstanding
6619     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6620     *
6621     * @return if any mutations occured that require persisting.
6622     */
6623    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6624        final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6625        if (perms == null) return false;
6626        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6627
6628        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6629        for (UriPermission perm : perms.values()) {
6630            if (perm.persistedModeFlags != 0) {
6631                persisted.add(perm);
6632            }
6633        }
6634
6635        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6636        if (trimCount <= 0) return false;
6637
6638        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6639        for (int i = 0; i < trimCount; i++) {
6640            final UriPermission perm = persisted.get(i);
6641
6642            if (DEBUG_URI_PERMISSION) {
6643                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6644            }
6645
6646            perm.releasePersistableModes(~0);
6647            removeUriPermissionIfNeededLocked(perm);
6648        }
6649
6650        return true;
6651    }
6652
6653    @Override
6654    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6655            String packageName, boolean incoming) {
6656        enforceNotIsolatedCaller("getPersistedUriPermissions");
6657        Preconditions.checkNotNull(packageName, "packageName");
6658
6659        final int callingUid = Binder.getCallingUid();
6660        final IPackageManager pm = AppGlobals.getPackageManager();
6661        try {
6662            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6663            if (packageUid != callingUid) {
6664                throw new SecurityException(
6665                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6666            }
6667        } catch (RemoteException e) {
6668            throw new SecurityException("Failed to verify package name ownership");
6669        }
6670
6671        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6672        synchronized (this) {
6673            if (incoming) {
6674                final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6675                if (perms == null) {
6676                    Slog.w(TAG, "No permission grants found for " + packageName);
6677                } else {
6678                    final int size = perms.size();
6679                    for (int i = 0; i < size; i++) {
6680                        final UriPermission perm = perms.valueAt(i);
6681                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6682                            result.add(perm.buildPersistedPublicApiObject());
6683                        }
6684                    }
6685                }
6686            } else {
6687                final int size = mGrantedUriPermissions.size();
6688                for (int i = 0; i < size; i++) {
6689                    final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6690                    final int permsSize = perms.size();
6691                    for (int j = 0; j < permsSize; j++) {
6692                        final UriPermission perm = perms.valueAt(j);
6693                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6694                            result.add(perm.buildPersistedPublicApiObject());
6695                        }
6696                    }
6697                }
6698            }
6699        }
6700        return new ParceledListSlice<android.content.UriPermission>(result);
6701    }
6702
6703    @Override
6704    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6705        synchronized (this) {
6706            ProcessRecord app =
6707                who != null ? getRecordForAppLocked(who) : null;
6708            if (app == null) return;
6709
6710            Message msg = Message.obtain();
6711            msg.what = WAIT_FOR_DEBUGGER_MSG;
6712            msg.obj = app;
6713            msg.arg1 = waiting ? 1 : 0;
6714            mHandler.sendMessage(msg);
6715        }
6716    }
6717
6718    @Override
6719    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
6720        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
6721        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
6722        outInfo.availMem = Process.getFreeMemory();
6723        outInfo.totalMem = Process.getTotalMemory();
6724        outInfo.threshold = homeAppMem;
6725        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
6726        outInfo.hiddenAppThreshold = cachedAppMem;
6727        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
6728                ProcessList.SERVICE_ADJ);
6729        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
6730                ProcessList.VISIBLE_APP_ADJ);
6731        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
6732                ProcessList.FOREGROUND_APP_ADJ);
6733    }
6734
6735    // =========================================================
6736    // TASK MANAGEMENT
6737    // =========================================================
6738
6739    @Override
6740    public List<RunningTaskInfo> getTasks(int maxNum, int flags,
6741                         IThumbnailReceiver receiver) {
6742        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
6743
6744        PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver);
6745        ActivityRecord topRecord = null;
6746
6747        synchronized(this) {
6748            if (localLOGV) Slog.v(
6749                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
6750                + ", receiver=" + receiver);
6751
6752            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
6753                    != PackageManager.PERMISSION_GRANTED) {
6754                if (receiver != null) {
6755                    // If the caller wants to wait for pending thumbnails,
6756                    // it ain't gonna get them.
6757                    try {
6758                        receiver.finished();
6759                    } catch (RemoteException ex) {
6760                    }
6761                }
6762                String msg = "Permission Denial: getTasks() from pid="
6763                        + Binder.getCallingPid()
6764                        + ", uid=" + Binder.getCallingUid()
6765                        + " requires " + android.Manifest.permission.GET_TASKS;
6766                Slog.w(TAG, msg);
6767                throw new SecurityException(msg);
6768            }
6769
6770            // TODO: Improve with MRU list from all ActivityStacks.
6771            topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list);
6772
6773            if (!pending.pendingRecords.isEmpty()) {
6774                mPendingThumbnails.add(pending);
6775            }
6776        }
6777
6778        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
6779
6780        if (topRecord != null) {
6781            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
6782            try {
6783                IApplicationThread topThumbnail = topRecord.app.thread;
6784                topThumbnail.requestThumbnail(topRecord.appToken);
6785            } catch (Exception e) {
6786                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
6787                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
6788            }
6789        }
6790
6791        if (pending == null && receiver != null) {
6792            // In this case all thumbnails were available and the client
6793            // is being asked to be told when the remaining ones come in...
6794            // which is unusually, since the top-most currently running
6795            // activity should never have a canned thumbnail!  Oh well.
6796            try {
6797                receiver.finished();
6798            } catch (RemoteException ex) {
6799            }
6800        }
6801
6802        return list;
6803    }
6804
6805    TaskRecord getMostRecentTask() {
6806        return mRecentTasks.get(0);
6807    }
6808
6809    @Override
6810    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
6811            int flags, int userId) {
6812        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6813                false, true, "getRecentTasks", null);
6814
6815        synchronized (this) {
6816            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
6817                    "getRecentTasks()");
6818            final boolean detailed = checkCallingPermission(
6819                    android.Manifest.permission.GET_DETAILED_TASKS)
6820                    == PackageManager.PERMISSION_GRANTED;
6821
6822            IPackageManager pm = AppGlobals.getPackageManager();
6823
6824            final int N = mRecentTasks.size();
6825            ArrayList<ActivityManager.RecentTaskInfo> res
6826                    = new ArrayList<ActivityManager.RecentTaskInfo>(
6827                            maxNum < N ? maxNum : N);
6828            for (int i=0; i<N && maxNum > 0; i++) {
6829                TaskRecord tr = mRecentTasks.get(i);
6830                // Only add calling user's recent tasks
6831                if (tr.userId != userId) continue;
6832                // Return the entry if desired by the caller.  We always return
6833                // the first entry, because callers always expect this to be the
6834                // foreground app.  We may filter others if the caller has
6835                // not supplied RECENT_WITH_EXCLUDED and there is some reason
6836                // we should exclude the entry.
6837
6838                if (i == 0
6839                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
6840                        || (tr.intent == null)
6841                        || ((tr.intent.getFlags()
6842                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
6843                    ActivityManager.RecentTaskInfo rti
6844                            = new ActivityManager.RecentTaskInfo();
6845                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
6846                    rti.persistentId = tr.taskId;
6847                    rti.baseIntent = new Intent(
6848                            tr.intent != null ? tr.intent : tr.affinityIntent);
6849                    if (!detailed) {
6850                        rti.baseIntent.replaceExtras((Bundle)null);
6851                    }
6852                    rti.origActivity = tr.origActivity;
6853                    rti.description = tr.lastDescription;
6854                    rti.stackId = tr.stack.mStackId;
6855
6856                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
6857                        // Check whether this activity is currently available.
6858                        try {
6859                            if (rti.origActivity != null) {
6860                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
6861                                        == null) {
6862                                    continue;
6863                                }
6864                            } else if (rti.baseIntent != null) {
6865                                if (pm.queryIntentActivities(rti.baseIntent,
6866                                        null, 0, userId) == null) {
6867                                    continue;
6868                                }
6869                            }
6870                        } catch (RemoteException e) {
6871                            // Will never happen.
6872                        }
6873                    }
6874
6875                    res.add(rti);
6876                    maxNum--;
6877                }
6878            }
6879            return res;
6880        }
6881    }
6882
6883    private TaskRecord recentTaskForIdLocked(int id) {
6884        final int N = mRecentTasks.size();
6885            for (int i=0; i<N; i++) {
6886                TaskRecord tr = mRecentTasks.get(i);
6887                if (tr.taskId == id) {
6888                    return tr;
6889                }
6890            }
6891            return null;
6892    }
6893
6894    @Override
6895    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
6896        synchronized (this) {
6897            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6898                    "getTaskThumbnails()");
6899            TaskRecord tr = recentTaskForIdLocked(id);
6900            if (tr != null) {
6901                return tr.getTaskThumbnailsLocked();
6902            }
6903        }
6904        return null;
6905    }
6906
6907    @Override
6908    public Bitmap getTaskTopThumbnail(int id) {
6909        synchronized (this) {
6910            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6911                    "getTaskTopThumbnail()");
6912            TaskRecord tr = recentTaskForIdLocked(id);
6913            if (tr != null) {
6914                return tr.getTaskTopThumbnailLocked();
6915            }
6916        }
6917        return null;
6918    }
6919
6920    @Override
6921    public boolean removeSubTask(int taskId, int subTaskIndex) {
6922        synchronized (this) {
6923            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6924                    "removeSubTask()");
6925            long ident = Binder.clearCallingIdentity();
6926            try {
6927                TaskRecord tr = recentTaskForIdLocked(taskId);
6928                if (tr != null) {
6929                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
6930                }
6931                return false;
6932            } finally {
6933                Binder.restoreCallingIdentity(ident);
6934            }
6935        }
6936    }
6937
6938    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
6939        if (!pr.killedByAm) {
6940            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
6941            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
6942                    pr.processName, pr.setAdj, reason);
6943            pr.killedByAm = true;
6944            Process.killProcessQuiet(pr.pid);
6945        }
6946    }
6947
6948    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
6949        tr.disposeThumbnail();
6950        mRecentTasks.remove(tr);
6951        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
6952        Intent baseIntent = new Intent(
6953                tr.intent != null ? tr.intent : tr.affinityIntent);
6954        ComponentName component = baseIntent.getComponent();
6955        if (component == null) {
6956            Slog.w(TAG, "Now component for base intent of task: " + tr);
6957            return;
6958        }
6959
6960        // Find any running services associated with this app.
6961        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
6962
6963        if (killProcesses) {
6964            // Find any running processes associated with this app.
6965            final String pkg = component.getPackageName();
6966            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
6967            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
6968            for (int i=0; i<pmap.size(); i++) {
6969                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
6970                for (int j=0; j<uids.size(); j++) {
6971                    ProcessRecord proc = uids.valueAt(j);
6972                    if (proc.userId != tr.userId) {
6973                        continue;
6974                    }
6975                    if (!proc.pkgList.containsKey(pkg)) {
6976                        continue;
6977                    }
6978                    procs.add(proc);
6979                }
6980            }
6981
6982            // Kill the running processes.
6983            for (int i=0; i<procs.size(); i++) {
6984                ProcessRecord pr = procs.get(i);
6985                if (pr == mHomeProcess) {
6986                    // Don't kill the home process along with tasks from the same package.
6987                    continue;
6988                }
6989                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
6990                    killUnneededProcessLocked(pr, "remove task");
6991                } else {
6992                    pr.waitingToKill = "remove task";
6993                }
6994            }
6995        }
6996    }
6997
6998    @Override
6999    public boolean removeTask(int taskId, int flags) {
7000        synchronized (this) {
7001            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7002                    "removeTask()");
7003            long ident = Binder.clearCallingIdentity();
7004            try {
7005                TaskRecord tr = recentTaskForIdLocked(taskId);
7006                if (tr != null) {
7007                    ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false);
7008                    if (r != null) {
7009                        cleanUpRemovedTaskLocked(tr, flags);
7010                        return true;
7011                    }
7012                    if (tr.mActivities.size() == 0) {
7013                        // Caller is just removing a recent task that is
7014                        // not actively running.  That is easy!
7015                        cleanUpRemovedTaskLocked(tr, flags);
7016                        return true;
7017                    }
7018                    Slog.w(TAG, "removeTask: task " + taskId
7019                            + " does not have activities to remove, "
7020                            + " but numActivities=" + tr.numActivities
7021                            + ": " + tr);
7022                }
7023            } finally {
7024                Binder.restoreCallingIdentity(ident);
7025            }
7026        }
7027        return false;
7028    }
7029
7030    /**
7031     * TODO: Add mController hook
7032     */
7033    @Override
7034    public void moveTaskToFront(int task, int flags, Bundle options) {
7035        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7036                "moveTaskToFront()");
7037
7038        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving task=" + task);
7039        synchronized(this) {
7040            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7041                    Binder.getCallingUid(), "Task to front")) {
7042                ActivityOptions.abort(options);
7043                return;
7044            }
7045            final long origId = Binder.clearCallingIdentity();
7046            try {
7047                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7048            } finally {
7049                Binder.restoreCallingIdentity(origId);
7050            }
7051            ActivityOptions.abort(options);
7052        }
7053    }
7054
7055    @Override
7056    public void moveTaskToBack(int taskId) {
7057        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7058                "moveTaskToBack()");
7059
7060        synchronized(this) {
7061            TaskRecord tr = recentTaskForIdLocked(taskId);
7062            if (tr != null) {
7063                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7064                ActivityStack stack = tr.stack;
7065                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7066                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7067                            Binder.getCallingUid(), "Task to back")) {
7068                        return;
7069                    }
7070                }
7071                final long origId = Binder.clearCallingIdentity();
7072                try {
7073                    stack.moveTaskToBackLocked(taskId, null);
7074                } finally {
7075                    Binder.restoreCallingIdentity(origId);
7076                }
7077            }
7078        }
7079    }
7080
7081    /**
7082     * Moves an activity, and all of the other activities within the same task, to the bottom
7083     * of the history stack.  The activity's order within the task is unchanged.
7084     *
7085     * @param token A reference to the activity we wish to move
7086     * @param nonRoot If false then this only works if the activity is the root
7087     *                of a task; if true it will work for any activity in a task.
7088     * @return Returns true if the move completed, false if not.
7089     */
7090    @Override
7091    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7092        enforceNotIsolatedCaller("moveActivityTaskToBack");
7093        synchronized(this) {
7094            final long origId = Binder.clearCallingIdentity();
7095            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7096            if (taskId >= 0) {
7097                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7098            }
7099            Binder.restoreCallingIdentity(origId);
7100        }
7101        return false;
7102    }
7103
7104    @Override
7105    public void moveTaskBackwards(int task) {
7106        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7107                "moveTaskBackwards()");
7108
7109        synchronized(this) {
7110            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7111                    Binder.getCallingUid(), "Task backwards")) {
7112                return;
7113            }
7114            final long origId = Binder.clearCallingIdentity();
7115            moveTaskBackwardsLocked(task);
7116            Binder.restoreCallingIdentity(origId);
7117        }
7118    }
7119
7120    private final void moveTaskBackwardsLocked(int task) {
7121        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7122    }
7123
7124    @Override
7125    public IBinder getHomeActivityToken() throws RemoteException {
7126        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7127                "getHomeActivityToken()");
7128        synchronized (this) {
7129            return mStackSupervisor.getHomeActivityToken();
7130        }
7131    }
7132
7133    @Override
7134    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7135            IActivityContainerCallback callback) throws RemoteException {
7136        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7137                "createActivityContainer()");
7138        synchronized (this) {
7139            if (parentActivityToken == null) {
7140                throw new IllegalArgumentException("parent token must not be null");
7141            }
7142            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7143            if (r == null) {
7144                return null;
7145            }
7146            return mStackSupervisor.createActivityContainer(r, callback);
7147        }
7148    }
7149
7150    @Override
7151    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7152        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7153                "deleteActivityContainer()");
7154        synchronized (this) {
7155            mStackSupervisor.deleteActivityContainer(container);
7156        }
7157    }
7158
7159    @Override
7160    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7161            throws RemoteException {
7162        synchronized (this) {
7163            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7164            if (stack != null) {
7165                return stack.mActivityContainer;
7166            }
7167            return null;
7168        }
7169    }
7170
7171    @Override
7172    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7173        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7174                "moveTaskToStack()");
7175        if (stackId == HOME_STACK_ID) {
7176            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7177                    new RuntimeException("here").fillInStackTrace());
7178        }
7179        synchronized (this) {
7180            long ident = Binder.clearCallingIdentity();
7181            try {
7182                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7183                        + stackId + " toTop=" + toTop);
7184                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7185            } finally {
7186                Binder.restoreCallingIdentity(ident);
7187            }
7188        }
7189    }
7190
7191    @Override
7192    public void resizeStack(int stackBoxId, Rect bounds) {
7193        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7194                "resizeStackBox()");
7195        long ident = Binder.clearCallingIdentity();
7196        try {
7197            mWindowManager.resizeStack(stackBoxId, bounds);
7198        } finally {
7199            Binder.restoreCallingIdentity(ident);
7200        }
7201    }
7202
7203    @Override
7204    public List<StackInfo> getAllStackInfos() {
7205        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7206                "getAllStackInfos()");
7207        long ident = Binder.clearCallingIdentity();
7208        try {
7209            synchronized (this) {
7210                return mStackSupervisor.getAllStackInfosLocked();
7211            }
7212        } finally {
7213            Binder.restoreCallingIdentity(ident);
7214        }
7215    }
7216
7217    @Override
7218    public StackInfo getStackInfo(int stackId) {
7219        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7220                "getStackInfo()");
7221        long ident = Binder.clearCallingIdentity();
7222        try {
7223            synchronized (this) {
7224                return mStackSupervisor.getStackInfoLocked(stackId);
7225            }
7226        } finally {
7227            Binder.restoreCallingIdentity(ident);
7228        }
7229    }
7230
7231    @Override
7232    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7233        synchronized(this) {
7234            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7235        }
7236    }
7237
7238    // =========================================================
7239    // THUMBNAILS
7240    // =========================================================
7241
7242    public void reportThumbnail(IBinder token,
7243            Bitmap thumbnail, CharSequence description) {
7244        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
7245        final long origId = Binder.clearCallingIdentity();
7246        sendPendingThumbnail(null, token, thumbnail, description, true);
7247        Binder.restoreCallingIdentity(origId);
7248    }
7249
7250    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
7251            Bitmap thumbnail, CharSequence description, boolean always) {
7252        TaskRecord task;
7253        ArrayList<PendingThumbnailsRecord> receivers = null;
7254
7255        //System.out.println("Send pending thumbnail: " + r);
7256
7257        synchronized(this) {
7258            if (r == null) {
7259                r = ActivityRecord.isInStackLocked(token);
7260                if (r == null) {
7261                    return;
7262                }
7263            }
7264            if (thumbnail == null && r.thumbHolder != null) {
7265                thumbnail = r.thumbHolder.lastThumbnail;
7266                description = r.thumbHolder.lastDescription;
7267            }
7268            if (thumbnail == null && !always) {
7269                // If there is no thumbnail, and this entry is not actually
7270                // going away, then abort for now and pick up the next
7271                // thumbnail we get.
7272                return;
7273            }
7274            task = r.task;
7275
7276            int N = mPendingThumbnails.size();
7277            int i=0;
7278            while (i<N) {
7279                PendingThumbnailsRecord pr = mPendingThumbnails.get(i);
7280                //System.out.println("Looking in " + pr.pendingRecords);
7281                if (pr.pendingRecords.remove(r)) {
7282                    if (receivers == null) {
7283                        receivers = new ArrayList<PendingThumbnailsRecord>();
7284                    }
7285                    receivers.add(pr);
7286                    if (pr.pendingRecords.size() == 0) {
7287                        pr.finished = true;
7288                        mPendingThumbnails.remove(i);
7289                        N--;
7290                        continue;
7291                    }
7292                }
7293                i++;
7294            }
7295        }
7296
7297        if (receivers != null) {
7298            final int N = receivers.size();
7299            for (int i=0; i<N; i++) {
7300                try {
7301                    PendingThumbnailsRecord pr = receivers.get(i);
7302                    pr.receiver.newThumbnail(
7303                        task != null ? task.taskId : -1, thumbnail, description);
7304                    if (pr.finished) {
7305                        pr.receiver.finished();
7306                    }
7307                } catch (Exception e) {
7308                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
7309                }
7310            }
7311        }
7312    }
7313
7314    // =========================================================
7315    // CONTENT PROVIDERS
7316    // =========================================================
7317
7318    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7319        List<ProviderInfo> providers = null;
7320        try {
7321            providers = AppGlobals.getPackageManager().
7322                queryContentProviders(app.processName, app.uid,
7323                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7324        } catch (RemoteException ex) {
7325        }
7326        if (DEBUG_MU)
7327            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7328        int userId = app.userId;
7329        if (providers != null) {
7330            int N = providers.size();
7331            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7332            for (int i=0; i<N; i++) {
7333                ProviderInfo cpi =
7334                    (ProviderInfo)providers.get(i);
7335                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7336                        cpi.name, cpi.flags);
7337                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7338                    // This is a singleton provider, but a user besides the
7339                    // default user is asking to initialize a process it runs
7340                    // in...  well, no, it doesn't actually run in this process,
7341                    // it runs in the process of the default user.  Get rid of it.
7342                    providers.remove(i);
7343                    N--;
7344                    i--;
7345                    continue;
7346                }
7347
7348                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7349                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7350                if (cpr == null) {
7351                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7352                    mProviderMap.putProviderByClass(comp, cpr);
7353                }
7354                if (DEBUG_MU)
7355                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7356                app.pubProviders.put(cpi.name, cpr);
7357                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7358                    // Don't add this if it is a platform component that is marked
7359                    // to run in multiple processes, because this is actually
7360                    // part of the framework so doesn't make sense to track as a
7361                    // separate apk in the process.
7362                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7363                }
7364                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7365            }
7366        }
7367        return providers;
7368    }
7369
7370    /**
7371     * Check if {@link ProcessRecord} has a possible chance at accessing the
7372     * given {@link ProviderInfo}. Final permission checking is always done
7373     * in {@link ContentProvider}.
7374     */
7375    private final String checkContentProviderPermissionLocked(
7376            ProviderInfo cpi, ProcessRecord r) {
7377        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7378        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7379        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7380                cpi.applicationInfo.uid, cpi.exported)
7381                == PackageManager.PERMISSION_GRANTED) {
7382            return null;
7383        }
7384        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7385                cpi.applicationInfo.uid, cpi.exported)
7386                == PackageManager.PERMISSION_GRANTED) {
7387            return null;
7388        }
7389
7390        PathPermission[] pps = cpi.pathPermissions;
7391        if (pps != null) {
7392            int i = pps.length;
7393            while (i > 0) {
7394                i--;
7395                PathPermission pp = pps[i];
7396                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7397                        cpi.applicationInfo.uid, cpi.exported)
7398                        == PackageManager.PERMISSION_GRANTED) {
7399                    return null;
7400                }
7401                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7402                        cpi.applicationInfo.uid, cpi.exported)
7403                        == PackageManager.PERMISSION_GRANTED) {
7404                    return null;
7405                }
7406            }
7407        }
7408
7409        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7410        if (perms != null) {
7411            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
7412                if (uri.getKey().getAuthority().equals(cpi.authority)) {
7413                    return null;
7414                }
7415            }
7416        }
7417
7418        String msg;
7419        if (!cpi.exported) {
7420            msg = "Permission Denial: opening provider " + cpi.name
7421                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7422                    + ", uid=" + callingUid + ") that is not exported from uid "
7423                    + cpi.applicationInfo.uid;
7424        } else {
7425            msg = "Permission Denial: opening provider " + cpi.name
7426                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7427                    + ", uid=" + callingUid + ") requires "
7428                    + cpi.readPermission + " or " + cpi.writePermission;
7429        }
7430        Slog.w(TAG, msg);
7431        return msg;
7432    }
7433
7434    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7435            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7436        if (r != null) {
7437            for (int i=0; i<r.conProviders.size(); i++) {
7438                ContentProviderConnection conn = r.conProviders.get(i);
7439                if (conn.provider == cpr) {
7440                    if (DEBUG_PROVIDER) Slog.v(TAG,
7441                            "Adding provider requested by "
7442                            + r.processName + " from process "
7443                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7444                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7445                    if (stable) {
7446                        conn.stableCount++;
7447                        conn.numStableIncs++;
7448                    } else {
7449                        conn.unstableCount++;
7450                        conn.numUnstableIncs++;
7451                    }
7452                    return conn;
7453                }
7454            }
7455            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7456            if (stable) {
7457                conn.stableCount = 1;
7458                conn.numStableIncs = 1;
7459            } else {
7460                conn.unstableCount = 1;
7461                conn.numUnstableIncs = 1;
7462            }
7463            cpr.connections.add(conn);
7464            r.conProviders.add(conn);
7465            return conn;
7466        }
7467        cpr.addExternalProcessHandleLocked(externalProcessToken);
7468        return null;
7469    }
7470
7471    boolean decProviderCountLocked(ContentProviderConnection conn,
7472            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7473        if (conn != null) {
7474            cpr = conn.provider;
7475            if (DEBUG_PROVIDER) Slog.v(TAG,
7476                    "Removing provider requested by "
7477                    + conn.client.processName + " from process "
7478                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7479                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7480            if (stable) {
7481                conn.stableCount--;
7482            } else {
7483                conn.unstableCount--;
7484            }
7485            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7486                cpr.connections.remove(conn);
7487                conn.client.conProviders.remove(conn);
7488                return true;
7489            }
7490            return false;
7491        }
7492        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7493        return false;
7494    }
7495
7496    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7497            String name, IBinder token, boolean stable, int userId) {
7498        ContentProviderRecord cpr;
7499        ContentProviderConnection conn = null;
7500        ProviderInfo cpi = null;
7501
7502        synchronized(this) {
7503            ProcessRecord r = null;
7504            if (caller != null) {
7505                r = getRecordForAppLocked(caller);
7506                if (r == null) {
7507                    throw new SecurityException(
7508                            "Unable to find app for caller " + caller
7509                          + " (pid=" + Binder.getCallingPid()
7510                          + ") when getting content provider " + name);
7511                }
7512            }
7513
7514            // First check if this content provider has been published...
7515            cpr = mProviderMap.getProviderByName(name, userId);
7516            boolean providerRunning = cpr != null;
7517            if (providerRunning) {
7518                cpi = cpr.info;
7519                String msg;
7520                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7521                    throw new SecurityException(msg);
7522                }
7523
7524                if (r != null && cpr.canRunHere(r)) {
7525                    // This provider has been published or is in the process
7526                    // of being published...  but it is also allowed to run
7527                    // in the caller's process, so don't make a connection
7528                    // and just let the caller instantiate its own instance.
7529                    ContentProviderHolder holder = cpr.newHolder(null);
7530                    // don't give caller the provider object, it needs
7531                    // to make its own.
7532                    holder.provider = null;
7533                    return holder;
7534                }
7535
7536                final long origId = Binder.clearCallingIdentity();
7537
7538                // In this case the provider instance already exists, so we can
7539                // return it right away.
7540                conn = incProviderCountLocked(r, cpr, token, stable);
7541                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7542                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7543                        // If this is a perceptible app accessing the provider,
7544                        // make sure to count it as being accessed and thus
7545                        // back up on the LRU list.  This is good because
7546                        // content providers are often expensive to start.
7547                        updateLruProcessLocked(cpr.proc, false, null);
7548                    }
7549                }
7550
7551                if (cpr.proc != null) {
7552                    if (false) {
7553                        if (cpr.name.flattenToShortString().equals(
7554                                "com.android.providers.calendar/.CalendarProvider2")) {
7555                            Slog.v(TAG, "****************** KILLING "
7556                                + cpr.name.flattenToShortString());
7557                            Process.killProcess(cpr.proc.pid);
7558                        }
7559                    }
7560                    boolean success = updateOomAdjLocked(cpr.proc);
7561                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7562                    // NOTE: there is still a race here where a signal could be
7563                    // pending on the process even though we managed to update its
7564                    // adj level.  Not sure what to do about this, but at least
7565                    // the race is now smaller.
7566                    if (!success) {
7567                        // Uh oh...  it looks like the provider's process
7568                        // has been killed on us.  We need to wait for a new
7569                        // process to be started, and make sure its death
7570                        // doesn't kill our process.
7571                        Slog.i(TAG,
7572                                "Existing provider " + cpr.name.flattenToShortString()
7573                                + " is crashing; detaching " + r);
7574                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7575                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7576                        if (!lastRef) {
7577                            // This wasn't the last ref our process had on
7578                            // the provider...  we have now been killed, bail.
7579                            return null;
7580                        }
7581                        providerRunning = false;
7582                        conn = null;
7583                    }
7584                }
7585
7586                Binder.restoreCallingIdentity(origId);
7587            }
7588
7589            boolean singleton;
7590            if (!providerRunning) {
7591                try {
7592                    cpi = AppGlobals.getPackageManager().
7593                        resolveContentProvider(name,
7594                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7595                } catch (RemoteException ex) {
7596                }
7597                if (cpi == null) {
7598                    return null;
7599                }
7600                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7601                        cpi.name, cpi.flags);
7602                if (singleton) {
7603                    userId = 0;
7604                }
7605                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7606
7607                String msg;
7608                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7609                    throw new SecurityException(msg);
7610                }
7611
7612                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
7613                        && !cpi.processName.equals("system")) {
7614                    // If this content provider does not run in the system
7615                    // process, and the system is not yet ready to run other
7616                    // processes, then fail fast instead of hanging.
7617                    throw new IllegalArgumentException(
7618                            "Attempt to launch content provider before system ready");
7619                }
7620
7621                // Make sure that the user who owns this provider is started.  If not,
7622                // we don't want to allow it to run.
7623                if (mStartedUsers.get(userId) == null) {
7624                    Slog.w(TAG, "Unable to launch app "
7625                            + cpi.applicationInfo.packageName + "/"
7626                            + cpi.applicationInfo.uid + " for provider "
7627                            + name + ": user " + userId + " is stopped");
7628                    return null;
7629                }
7630
7631                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7632                cpr = mProviderMap.getProviderByClass(comp, userId);
7633                final boolean firstClass = cpr == null;
7634                if (firstClass) {
7635                    try {
7636                        ApplicationInfo ai =
7637                            AppGlobals.getPackageManager().
7638                                getApplicationInfo(
7639                                        cpi.applicationInfo.packageName,
7640                                        STOCK_PM_FLAGS, userId);
7641                        if (ai == null) {
7642                            Slog.w(TAG, "No package info for content provider "
7643                                    + cpi.name);
7644                            return null;
7645                        }
7646                        ai = getAppInfoForUser(ai, userId);
7647                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
7648                    } catch (RemoteException ex) {
7649                        // pm is in same process, this will never happen.
7650                    }
7651                }
7652
7653                if (r != null && cpr.canRunHere(r)) {
7654                    // If this is a multiprocess provider, then just return its
7655                    // info and allow the caller to instantiate it.  Only do
7656                    // this if the provider is the same user as the caller's
7657                    // process, or can run as root (so can be in any process).
7658                    return cpr.newHolder(null);
7659                }
7660
7661                if (DEBUG_PROVIDER) {
7662                    RuntimeException e = new RuntimeException("here");
7663                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
7664                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
7665                }
7666
7667                // This is single process, and our app is now connecting to it.
7668                // See if we are already in the process of launching this
7669                // provider.
7670                final int N = mLaunchingProviders.size();
7671                int i;
7672                for (i=0; i<N; i++) {
7673                    if (mLaunchingProviders.get(i) == cpr) {
7674                        break;
7675                    }
7676                }
7677
7678                // If the provider is not already being launched, then get it
7679                // started.
7680                if (i >= N) {
7681                    final long origId = Binder.clearCallingIdentity();
7682
7683                    try {
7684                        // Content provider is now in use, its package can't be stopped.
7685                        try {
7686                            AppGlobals.getPackageManager().setPackageStoppedState(
7687                                    cpr.appInfo.packageName, false, userId);
7688                        } catch (RemoteException e) {
7689                        } catch (IllegalArgumentException e) {
7690                            Slog.w(TAG, "Failed trying to unstop package "
7691                                    + cpr.appInfo.packageName + ": " + e);
7692                        }
7693
7694                        // Use existing process if already started
7695                        ProcessRecord proc = getProcessRecordLocked(
7696                                cpi.processName, cpr.appInfo.uid, false);
7697                        if (proc != null && proc.thread != null) {
7698                            if (DEBUG_PROVIDER) {
7699                                Slog.d(TAG, "Installing in existing process " + proc);
7700                            }
7701                            proc.pubProviders.put(cpi.name, cpr);
7702                            try {
7703                                proc.thread.scheduleInstallProvider(cpi);
7704                            } catch (RemoteException e) {
7705                            }
7706                        } else {
7707                            proc = startProcessLocked(cpi.processName,
7708                                    cpr.appInfo, false, 0, "content provider",
7709                                    new ComponentName(cpi.applicationInfo.packageName,
7710                                            cpi.name), false, false, false);
7711                            if (proc == null) {
7712                                Slog.w(TAG, "Unable to launch app "
7713                                        + cpi.applicationInfo.packageName + "/"
7714                                        + cpi.applicationInfo.uid + " for provider "
7715                                        + name + ": process is bad");
7716                                return null;
7717                            }
7718                        }
7719                        cpr.launchingApp = proc;
7720                        mLaunchingProviders.add(cpr);
7721                    } finally {
7722                        Binder.restoreCallingIdentity(origId);
7723                    }
7724                }
7725
7726                // Make sure the provider is published (the same provider class
7727                // may be published under multiple names).
7728                if (firstClass) {
7729                    mProviderMap.putProviderByClass(comp, cpr);
7730                }
7731
7732                mProviderMap.putProviderByName(name, cpr);
7733                conn = incProviderCountLocked(r, cpr, token, stable);
7734                if (conn != null) {
7735                    conn.waiting = true;
7736                }
7737            }
7738        }
7739
7740        // Wait for the provider to be published...
7741        synchronized (cpr) {
7742            while (cpr.provider == null) {
7743                if (cpr.launchingApp == null) {
7744                    Slog.w(TAG, "Unable to launch app "
7745                            + cpi.applicationInfo.packageName + "/"
7746                            + cpi.applicationInfo.uid + " for provider "
7747                            + name + ": launching app became null");
7748                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
7749                            UserHandle.getUserId(cpi.applicationInfo.uid),
7750                            cpi.applicationInfo.packageName,
7751                            cpi.applicationInfo.uid, name);
7752                    return null;
7753                }
7754                try {
7755                    if (DEBUG_MU) {
7756                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
7757                                + cpr.launchingApp);
7758                    }
7759                    if (conn != null) {
7760                        conn.waiting = true;
7761                    }
7762                    cpr.wait();
7763                } catch (InterruptedException ex) {
7764                } finally {
7765                    if (conn != null) {
7766                        conn.waiting = false;
7767                    }
7768                }
7769            }
7770        }
7771        return cpr != null ? cpr.newHolder(conn) : null;
7772    }
7773
7774    public final ContentProviderHolder getContentProvider(
7775            IApplicationThread caller, String name, int userId, boolean stable) {
7776        enforceNotIsolatedCaller("getContentProvider");
7777        if (caller == null) {
7778            String msg = "null IApplicationThread when getting content provider "
7779                    + name;
7780            Slog.w(TAG, msg);
7781            throw new SecurityException(msg);
7782        }
7783
7784        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7785                false, true, "getContentProvider", null);
7786        return getContentProviderImpl(caller, name, null, stable, userId);
7787    }
7788
7789    public ContentProviderHolder getContentProviderExternal(
7790            String name, int userId, IBinder token) {
7791        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7792            "Do not have permission in call getContentProviderExternal()");
7793        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7794                false, true, "getContentProvider", null);
7795        return getContentProviderExternalUnchecked(name, token, userId);
7796    }
7797
7798    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
7799            IBinder token, int userId) {
7800        return getContentProviderImpl(null, name, token, true, userId);
7801    }
7802
7803    /**
7804     * Drop a content provider from a ProcessRecord's bookkeeping
7805     */
7806    public void removeContentProvider(IBinder connection, boolean stable) {
7807        enforceNotIsolatedCaller("removeContentProvider");
7808        long ident = Binder.clearCallingIdentity();
7809        try {
7810            synchronized (this) {
7811                ContentProviderConnection conn;
7812                try {
7813                    conn = (ContentProviderConnection)connection;
7814                } catch (ClassCastException e) {
7815                    String msg ="removeContentProvider: " + connection
7816                            + " not a ContentProviderConnection";
7817                    Slog.w(TAG, msg);
7818                    throw new IllegalArgumentException(msg);
7819                }
7820                if (conn == null) {
7821                    throw new NullPointerException("connection is null");
7822                }
7823                if (decProviderCountLocked(conn, null, null, stable)) {
7824                    updateOomAdjLocked();
7825                }
7826            }
7827        } finally {
7828            Binder.restoreCallingIdentity(ident);
7829        }
7830    }
7831
7832    public void removeContentProviderExternal(String name, IBinder token) {
7833        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7834            "Do not have permission in call removeContentProviderExternal()");
7835        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
7836    }
7837
7838    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
7839        synchronized (this) {
7840            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
7841            if(cpr == null) {
7842                //remove from mProvidersByClass
7843                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
7844                return;
7845            }
7846
7847            //update content provider record entry info
7848            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
7849            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
7850            if (localCpr.hasExternalProcessHandles()) {
7851                if (localCpr.removeExternalProcessHandleLocked(token)) {
7852                    updateOomAdjLocked();
7853                } else {
7854                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
7855                            + " with no external reference for token: "
7856                            + token + ".");
7857                }
7858            } else {
7859                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
7860                        + " with no external references.");
7861            }
7862        }
7863    }
7864
7865    public final void publishContentProviders(IApplicationThread caller,
7866            List<ContentProviderHolder> providers) {
7867        if (providers == null) {
7868            return;
7869        }
7870
7871        enforceNotIsolatedCaller("publishContentProviders");
7872        synchronized (this) {
7873            final ProcessRecord r = getRecordForAppLocked(caller);
7874            if (DEBUG_MU)
7875                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
7876            if (r == null) {
7877                throw new SecurityException(
7878                        "Unable to find app for caller " + caller
7879                      + " (pid=" + Binder.getCallingPid()
7880                      + ") when publishing content providers");
7881            }
7882
7883            final long origId = Binder.clearCallingIdentity();
7884
7885            final int N = providers.size();
7886            for (int i=0; i<N; i++) {
7887                ContentProviderHolder src = providers.get(i);
7888                if (src == null || src.info == null || src.provider == null) {
7889                    continue;
7890                }
7891                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
7892                if (DEBUG_MU)
7893                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
7894                if (dst != null) {
7895                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
7896                    mProviderMap.putProviderByClass(comp, dst);
7897                    String names[] = dst.info.authority.split(";");
7898                    for (int j = 0; j < names.length; j++) {
7899                        mProviderMap.putProviderByName(names[j], dst);
7900                    }
7901
7902                    int NL = mLaunchingProviders.size();
7903                    int j;
7904                    for (j=0; j<NL; j++) {
7905                        if (mLaunchingProviders.get(j) == dst) {
7906                            mLaunchingProviders.remove(j);
7907                            j--;
7908                            NL--;
7909                        }
7910                    }
7911                    synchronized (dst) {
7912                        dst.provider = src.provider;
7913                        dst.proc = r;
7914                        dst.notifyAll();
7915                    }
7916                    updateOomAdjLocked(r);
7917                }
7918            }
7919
7920            Binder.restoreCallingIdentity(origId);
7921        }
7922    }
7923
7924    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
7925        ContentProviderConnection conn;
7926        try {
7927            conn = (ContentProviderConnection)connection;
7928        } catch (ClassCastException e) {
7929            String msg ="refContentProvider: " + connection
7930                    + " not a ContentProviderConnection";
7931            Slog.w(TAG, msg);
7932            throw new IllegalArgumentException(msg);
7933        }
7934        if (conn == null) {
7935            throw new NullPointerException("connection is null");
7936        }
7937
7938        synchronized (this) {
7939            if (stable > 0) {
7940                conn.numStableIncs += stable;
7941            }
7942            stable = conn.stableCount + stable;
7943            if (stable < 0) {
7944                throw new IllegalStateException("stableCount < 0: " + stable);
7945            }
7946
7947            if (unstable > 0) {
7948                conn.numUnstableIncs += unstable;
7949            }
7950            unstable = conn.unstableCount + unstable;
7951            if (unstable < 0) {
7952                throw new IllegalStateException("unstableCount < 0: " + unstable);
7953            }
7954
7955            if ((stable+unstable) <= 0) {
7956                throw new IllegalStateException("ref counts can't go to zero here: stable="
7957                        + stable + " unstable=" + unstable);
7958            }
7959            conn.stableCount = stable;
7960            conn.unstableCount = unstable;
7961            return !conn.dead;
7962        }
7963    }
7964
7965    public void unstableProviderDied(IBinder connection) {
7966        ContentProviderConnection conn;
7967        try {
7968            conn = (ContentProviderConnection)connection;
7969        } catch (ClassCastException e) {
7970            String msg ="refContentProvider: " + connection
7971                    + " not a ContentProviderConnection";
7972            Slog.w(TAG, msg);
7973            throw new IllegalArgumentException(msg);
7974        }
7975        if (conn == null) {
7976            throw new NullPointerException("connection is null");
7977        }
7978
7979        // Safely retrieve the content provider associated with the connection.
7980        IContentProvider provider;
7981        synchronized (this) {
7982            provider = conn.provider.provider;
7983        }
7984
7985        if (provider == null) {
7986            // Um, yeah, we're way ahead of you.
7987            return;
7988        }
7989
7990        // Make sure the caller is being honest with us.
7991        if (provider.asBinder().pingBinder()) {
7992            // Er, no, still looks good to us.
7993            synchronized (this) {
7994                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
7995                        + " says " + conn + " died, but we don't agree");
7996                return;
7997            }
7998        }
7999
8000        // Well look at that!  It's dead!
8001        synchronized (this) {
8002            if (conn.provider.provider != provider) {
8003                // But something changed...  good enough.
8004                return;
8005            }
8006
8007            ProcessRecord proc = conn.provider.proc;
8008            if (proc == null || proc.thread == null) {
8009                // Seems like the process is already cleaned up.
8010                return;
8011            }
8012
8013            // As far as we're concerned, this is just like receiving a
8014            // death notification...  just a bit prematurely.
8015            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8016                    + ") early provider death");
8017            final long ident = Binder.clearCallingIdentity();
8018            try {
8019                appDiedLocked(proc, proc.pid, proc.thread);
8020            } finally {
8021                Binder.restoreCallingIdentity(ident);
8022            }
8023        }
8024    }
8025
8026    @Override
8027    public void appNotRespondingViaProvider(IBinder connection) {
8028        enforceCallingPermission(
8029                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8030
8031        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8032        if (conn == null) {
8033            Slog.w(TAG, "ContentProviderConnection is null");
8034            return;
8035        }
8036
8037        final ProcessRecord host = conn.provider.proc;
8038        if (host == null) {
8039            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8040            return;
8041        }
8042
8043        final long token = Binder.clearCallingIdentity();
8044        try {
8045            appNotResponding(host, null, null, false, "ContentProvider not responding");
8046        } finally {
8047            Binder.restoreCallingIdentity(token);
8048        }
8049    }
8050
8051    public final void installSystemProviders() {
8052        List<ProviderInfo> providers;
8053        synchronized (this) {
8054            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8055            providers = generateApplicationProvidersLocked(app);
8056            if (providers != null) {
8057                for (int i=providers.size()-1; i>=0; i--) {
8058                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8059                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8060                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8061                                + ": not system .apk");
8062                        providers.remove(i);
8063                    }
8064                }
8065            }
8066        }
8067        if (providers != null) {
8068            mSystemThread.installSystemProviders(providers);
8069        }
8070
8071        mCoreSettingsObserver = new CoreSettingsObserver(this);
8072
8073        mUsageStatsService.monitorPackages();
8074    }
8075
8076    /**
8077     * Allows app to retrieve the MIME type of a URI without having permission
8078     * to access its content provider.
8079     *
8080     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8081     *
8082     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8083     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8084     */
8085    public String getProviderMimeType(Uri uri, int userId) {
8086        enforceNotIsolatedCaller("getProviderMimeType");
8087        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8088                userId, false, true, "getProviderMimeType", null);
8089        final String name = uri.getAuthority();
8090        final long ident = Binder.clearCallingIdentity();
8091        ContentProviderHolder holder = null;
8092
8093        try {
8094            holder = getContentProviderExternalUnchecked(name, null, userId);
8095            if (holder != null) {
8096                return holder.provider.getType(uri);
8097            }
8098        } catch (RemoteException e) {
8099            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8100            return null;
8101        } finally {
8102            if (holder != null) {
8103                removeContentProviderExternalUnchecked(name, null, userId);
8104            }
8105            Binder.restoreCallingIdentity(ident);
8106        }
8107
8108        return null;
8109    }
8110
8111    // =========================================================
8112    // GLOBAL MANAGEMENT
8113    // =========================================================
8114
8115    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8116            boolean isolated) {
8117        String proc = customProcess != null ? customProcess : info.processName;
8118        BatteryStatsImpl.Uid.Proc ps = null;
8119        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8120        int uid = info.uid;
8121        if (isolated) {
8122            int userId = UserHandle.getUserId(uid);
8123            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8124            while (true) {
8125                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8126                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8127                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8128                }
8129                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8130                mNextIsolatedProcessUid++;
8131                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8132                    // No process for this uid, use it.
8133                    break;
8134                }
8135                stepsLeft--;
8136                if (stepsLeft <= 0) {
8137                    return null;
8138                }
8139            }
8140        }
8141        return new ProcessRecord(stats, info, proc, uid);
8142    }
8143
8144    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8145        ProcessRecord app;
8146        if (!isolated) {
8147            app = getProcessRecordLocked(info.processName, info.uid, true);
8148        } else {
8149            app = null;
8150        }
8151
8152        if (app == null) {
8153            app = newProcessRecordLocked(info, null, isolated);
8154            mProcessNames.put(info.processName, app.uid, app);
8155            if (isolated) {
8156                mIsolatedProcesses.put(app.uid, app);
8157            }
8158            updateLruProcessLocked(app, false, null);
8159            updateOomAdjLocked();
8160        }
8161
8162        // This package really, really can not be stopped.
8163        try {
8164            AppGlobals.getPackageManager().setPackageStoppedState(
8165                    info.packageName, false, UserHandle.getUserId(app.uid));
8166        } catch (RemoteException e) {
8167        } catch (IllegalArgumentException e) {
8168            Slog.w(TAG, "Failed trying to unstop package "
8169                    + info.packageName + ": " + e);
8170        }
8171
8172        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8173                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8174            app.persistent = true;
8175            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8176        }
8177        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8178            mPersistentStartingProcesses.add(app);
8179            startProcessLocked(app, "added application", app.processName);
8180        }
8181
8182        return app;
8183    }
8184
8185    public void unhandledBack() {
8186        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8187                "unhandledBack()");
8188
8189        synchronized(this) {
8190            final long origId = Binder.clearCallingIdentity();
8191            try {
8192                getFocusedStack().unhandledBackLocked();
8193            } finally {
8194                Binder.restoreCallingIdentity(origId);
8195            }
8196        }
8197    }
8198
8199    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8200        enforceNotIsolatedCaller("openContentUri");
8201        final int userId = UserHandle.getCallingUserId();
8202        String name = uri.getAuthority();
8203        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8204        ParcelFileDescriptor pfd = null;
8205        if (cph != null) {
8206            // We record the binder invoker's uid in thread-local storage before
8207            // going to the content provider to open the file.  Later, in the code
8208            // that handles all permissions checks, we look for this uid and use
8209            // that rather than the Activity Manager's own uid.  The effect is that
8210            // we do the check against the caller's permissions even though it looks
8211            // to the content provider like the Activity Manager itself is making
8212            // the request.
8213            sCallerIdentity.set(new Identity(
8214                    Binder.getCallingPid(), Binder.getCallingUid()));
8215            try {
8216                pfd = cph.provider.openFile(null, uri, "r", null);
8217            } catch (FileNotFoundException e) {
8218                // do nothing; pfd will be returned null
8219            } finally {
8220                // Ensure that whatever happens, we clean up the identity state
8221                sCallerIdentity.remove();
8222            }
8223
8224            // We've got the fd now, so we're done with the provider.
8225            removeContentProviderExternalUnchecked(name, null, userId);
8226        } else {
8227            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8228        }
8229        return pfd;
8230    }
8231
8232    // Actually is sleeping or shutting down or whatever else in the future
8233    // is an inactive state.
8234    public boolean isSleepingOrShuttingDown() {
8235        return mSleeping || mShuttingDown;
8236    }
8237
8238    public void goingToSleep() {
8239        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8240                != PackageManager.PERMISSION_GRANTED) {
8241            throw new SecurityException("Requires permission "
8242                    + android.Manifest.permission.DEVICE_POWER);
8243        }
8244
8245        synchronized(this) {
8246            mWentToSleep = true;
8247            updateEventDispatchingLocked();
8248
8249            if (!mSleeping) {
8250                mSleeping = true;
8251                mStackSupervisor.goingToSleepLocked();
8252
8253                // Initialize the wake times of all processes.
8254                checkExcessivePowerUsageLocked(false);
8255                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8256                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8257                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8258            }
8259        }
8260    }
8261
8262    @Override
8263    public boolean shutdown(int timeout) {
8264        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8265                != PackageManager.PERMISSION_GRANTED) {
8266            throw new SecurityException("Requires permission "
8267                    + android.Manifest.permission.SHUTDOWN);
8268        }
8269
8270        boolean timedout = false;
8271
8272        synchronized(this) {
8273            mShuttingDown = true;
8274            updateEventDispatchingLocked();
8275            timedout = mStackSupervisor.shutdownLocked(timeout);
8276        }
8277
8278        mAppOpsService.shutdown();
8279        mUsageStatsService.shutdown();
8280        mBatteryStatsService.shutdown();
8281        synchronized (this) {
8282            mProcessStats.shutdownLocked();
8283        }
8284
8285        return timedout;
8286    }
8287
8288    public final void activitySlept(IBinder token) {
8289        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8290
8291        final long origId = Binder.clearCallingIdentity();
8292
8293        synchronized (this) {
8294            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8295            if (r != null) {
8296                mStackSupervisor.activitySleptLocked(r);
8297            }
8298        }
8299
8300        Binder.restoreCallingIdentity(origId);
8301    }
8302
8303    void logLockScreen(String msg) {
8304        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8305                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8306                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8307                mStackSupervisor.mDismissKeyguardOnNextActivity);
8308    }
8309
8310    private void comeOutOfSleepIfNeededLocked() {
8311        if (!mWentToSleep && !mLockScreenShown) {
8312            if (mSleeping) {
8313                mSleeping = false;
8314                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8315            }
8316        }
8317    }
8318
8319    public void wakingUp() {
8320        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8321                != PackageManager.PERMISSION_GRANTED) {
8322            throw new SecurityException("Requires permission "
8323                    + android.Manifest.permission.DEVICE_POWER);
8324        }
8325
8326        synchronized(this) {
8327            mWentToSleep = false;
8328            updateEventDispatchingLocked();
8329            comeOutOfSleepIfNeededLocked();
8330        }
8331    }
8332
8333    private void updateEventDispatchingLocked() {
8334        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8335    }
8336
8337    public void setLockScreenShown(boolean shown) {
8338        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8339                != PackageManager.PERMISSION_GRANTED) {
8340            throw new SecurityException("Requires permission "
8341                    + android.Manifest.permission.DEVICE_POWER);
8342        }
8343
8344        synchronized(this) {
8345            long ident = Binder.clearCallingIdentity();
8346            try {
8347                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8348                mLockScreenShown = shown;
8349                comeOutOfSleepIfNeededLocked();
8350            } finally {
8351                Binder.restoreCallingIdentity(ident);
8352            }
8353        }
8354    }
8355
8356    public void stopAppSwitches() {
8357        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8358                != PackageManager.PERMISSION_GRANTED) {
8359            throw new SecurityException("Requires permission "
8360                    + android.Manifest.permission.STOP_APP_SWITCHES);
8361        }
8362
8363        synchronized(this) {
8364            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8365                    + APP_SWITCH_DELAY_TIME;
8366            mDidAppSwitch = false;
8367            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8368            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8369            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8370        }
8371    }
8372
8373    public void resumeAppSwitches() {
8374        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8375                != PackageManager.PERMISSION_GRANTED) {
8376            throw new SecurityException("Requires permission "
8377                    + android.Manifest.permission.STOP_APP_SWITCHES);
8378        }
8379
8380        synchronized(this) {
8381            // Note that we don't execute any pending app switches... we will
8382            // let those wait until either the timeout, or the next start
8383            // activity request.
8384            mAppSwitchesAllowedTime = 0;
8385        }
8386    }
8387
8388    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8389            String name) {
8390        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8391            return true;
8392        }
8393
8394        final int perm = checkComponentPermission(
8395                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8396                callingUid, -1, true);
8397        if (perm == PackageManager.PERMISSION_GRANTED) {
8398            return true;
8399        }
8400
8401        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8402        return false;
8403    }
8404
8405    public void setDebugApp(String packageName, boolean waitForDebugger,
8406            boolean persistent) {
8407        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8408                "setDebugApp()");
8409
8410        long ident = Binder.clearCallingIdentity();
8411        try {
8412            // Note that this is not really thread safe if there are multiple
8413            // callers into it at the same time, but that's not a situation we
8414            // care about.
8415            if (persistent) {
8416                final ContentResolver resolver = mContext.getContentResolver();
8417                Settings.Global.putString(
8418                    resolver, Settings.Global.DEBUG_APP,
8419                    packageName);
8420                Settings.Global.putInt(
8421                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8422                    waitForDebugger ? 1 : 0);
8423            }
8424
8425            synchronized (this) {
8426                if (!persistent) {
8427                    mOrigDebugApp = mDebugApp;
8428                    mOrigWaitForDebugger = mWaitForDebugger;
8429                }
8430                mDebugApp = packageName;
8431                mWaitForDebugger = waitForDebugger;
8432                mDebugTransient = !persistent;
8433                if (packageName != null) {
8434                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8435                            false, UserHandle.USER_ALL, "set debug app");
8436                }
8437            }
8438        } finally {
8439            Binder.restoreCallingIdentity(ident);
8440        }
8441    }
8442
8443    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8444        synchronized (this) {
8445            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8446            if (!isDebuggable) {
8447                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8448                    throw new SecurityException("Process not debuggable: " + app.packageName);
8449                }
8450            }
8451
8452            mOpenGlTraceApp = processName;
8453        }
8454    }
8455
8456    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8457            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8458        synchronized (this) {
8459            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8460            if (!isDebuggable) {
8461                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8462                    throw new SecurityException("Process not debuggable: " + app.packageName);
8463                }
8464            }
8465            mProfileApp = processName;
8466            mProfileFile = profileFile;
8467            if (mProfileFd != null) {
8468                try {
8469                    mProfileFd.close();
8470                } catch (IOException e) {
8471                }
8472                mProfileFd = null;
8473            }
8474            mProfileFd = profileFd;
8475            mProfileType = 0;
8476            mAutoStopProfiler = autoStopProfiler;
8477        }
8478    }
8479
8480    @Override
8481    public void setAlwaysFinish(boolean enabled) {
8482        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8483                "setAlwaysFinish()");
8484
8485        Settings.Global.putInt(
8486                mContext.getContentResolver(),
8487                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8488
8489        synchronized (this) {
8490            mAlwaysFinishActivities = enabled;
8491        }
8492    }
8493
8494    @Override
8495    public void setActivityController(IActivityController controller) {
8496        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8497                "setActivityController()");
8498        synchronized (this) {
8499            mController = controller;
8500            Watchdog.getInstance().setActivityController(controller);
8501        }
8502    }
8503
8504    @Override
8505    public void setUserIsMonkey(boolean userIsMonkey) {
8506        synchronized (this) {
8507            synchronized (mPidsSelfLocked) {
8508                final int callingPid = Binder.getCallingPid();
8509                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8510                if (precessRecord == null) {
8511                    throw new SecurityException("Unknown process: " + callingPid);
8512                }
8513                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8514                    throw new SecurityException("Only an instrumentation process "
8515                            + "with a UiAutomation can call setUserIsMonkey");
8516                }
8517            }
8518            mUserIsMonkey = userIsMonkey;
8519        }
8520    }
8521
8522    @Override
8523    public boolean isUserAMonkey() {
8524        synchronized (this) {
8525            // If there is a controller also implies the user is a monkey.
8526            return (mUserIsMonkey || mController != null);
8527        }
8528    }
8529
8530    public void requestBugReport() {
8531        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8532        SystemProperties.set("ctl.start", "bugreport");
8533    }
8534
8535    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8536        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8537    }
8538
8539    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8540        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8541            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8542        }
8543        return KEY_DISPATCHING_TIMEOUT;
8544    }
8545
8546    @Override
8547    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8548        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8549                != PackageManager.PERMISSION_GRANTED) {
8550            throw new SecurityException("Requires permission "
8551                    + android.Manifest.permission.FILTER_EVENTS);
8552        }
8553        ProcessRecord proc;
8554        long timeout;
8555        synchronized (this) {
8556            synchronized (mPidsSelfLocked) {
8557                proc = mPidsSelfLocked.get(pid);
8558            }
8559            timeout = getInputDispatchingTimeoutLocked(proc);
8560        }
8561
8562        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8563            return -1;
8564        }
8565
8566        return timeout;
8567    }
8568
8569    /**
8570     * Handle input dispatching timeouts.
8571     * Returns whether input dispatching should be aborted or not.
8572     */
8573    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8574            final ActivityRecord activity, final ActivityRecord parent,
8575            final boolean aboveSystem, String reason) {
8576        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8577                != PackageManager.PERMISSION_GRANTED) {
8578            throw new SecurityException("Requires permission "
8579                    + android.Manifest.permission.FILTER_EVENTS);
8580        }
8581
8582        final String annotation;
8583        if (reason == null) {
8584            annotation = "Input dispatching timed out";
8585        } else {
8586            annotation = "Input dispatching timed out (" + reason + ")";
8587        }
8588
8589        if (proc != null) {
8590            synchronized (this) {
8591                if (proc.debugging) {
8592                    return false;
8593                }
8594
8595                if (mDidDexOpt) {
8596                    // Give more time since we were dexopting.
8597                    mDidDexOpt = false;
8598                    return false;
8599                }
8600
8601                if (proc.instrumentationClass != null) {
8602                    Bundle info = new Bundle();
8603                    info.putString("shortMsg", "keyDispatchingTimedOut");
8604                    info.putString("longMsg", annotation);
8605                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8606                    return true;
8607                }
8608            }
8609            mHandler.post(new Runnable() {
8610                @Override
8611                public void run() {
8612                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
8613                }
8614            });
8615        }
8616
8617        return true;
8618    }
8619
8620    public Bundle getAssistContextExtras(int requestType) {
8621        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
8622                "getAssistContextExtras()");
8623        PendingAssistExtras pae;
8624        Bundle extras = new Bundle();
8625        synchronized (this) {
8626            ActivityRecord activity = getFocusedStack().mResumedActivity;
8627            if (activity == null) {
8628                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
8629                return null;
8630            }
8631            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
8632            if (activity.app == null || activity.app.thread == null) {
8633                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
8634                return extras;
8635            }
8636            if (activity.app.pid == Binder.getCallingPid()) {
8637                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
8638                return extras;
8639            }
8640            pae = new PendingAssistExtras(activity);
8641            try {
8642                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
8643                        requestType);
8644                mPendingAssistExtras.add(pae);
8645                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
8646            } catch (RemoteException e) {
8647                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
8648                return extras;
8649            }
8650        }
8651        synchronized (pae) {
8652            while (!pae.haveResult) {
8653                try {
8654                    pae.wait();
8655                } catch (InterruptedException e) {
8656                }
8657            }
8658            if (pae.result != null) {
8659                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
8660            }
8661        }
8662        synchronized (this) {
8663            mPendingAssistExtras.remove(pae);
8664            mHandler.removeCallbacks(pae);
8665        }
8666        return extras;
8667    }
8668
8669    public void reportAssistContextExtras(IBinder token, Bundle extras) {
8670        PendingAssistExtras pae = (PendingAssistExtras)token;
8671        synchronized (pae) {
8672            pae.result = extras;
8673            pae.haveResult = true;
8674            pae.notifyAll();
8675        }
8676    }
8677
8678    public void registerProcessObserver(IProcessObserver observer) {
8679        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8680                "registerProcessObserver()");
8681        synchronized (this) {
8682            mProcessObservers.register(observer);
8683        }
8684    }
8685
8686    @Override
8687    public void unregisterProcessObserver(IProcessObserver observer) {
8688        synchronized (this) {
8689            mProcessObservers.unregister(observer);
8690        }
8691    }
8692
8693    @Override
8694    public boolean convertFromTranslucent(IBinder token) {
8695        final long origId = Binder.clearCallingIdentity();
8696        try {
8697            synchronized (this) {
8698                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8699                if (r == null) {
8700                    return false;
8701                }
8702                if (r.changeWindowTranslucency(true)) {
8703                    mWindowManager.setAppFullscreen(token, true);
8704                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8705                    return true;
8706                }
8707                return false;
8708            }
8709        } finally {
8710            Binder.restoreCallingIdentity(origId);
8711        }
8712    }
8713
8714    @Override
8715    public boolean convertToTranslucent(IBinder token) {
8716        final long origId = Binder.clearCallingIdentity();
8717        try {
8718            synchronized (this) {
8719                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8720                if (r == null) {
8721                    return false;
8722                }
8723                if (r.changeWindowTranslucency(false)) {
8724                    r.task.stack.convertToTranslucent(r);
8725                    mWindowManager.setAppFullscreen(token, false);
8726                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8727                    return true;
8728                }
8729                return false;
8730            }
8731        } finally {
8732            Binder.restoreCallingIdentity(origId);
8733        }
8734    }
8735
8736    @Override
8737    public void setImmersive(IBinder token, boolean immersive) {
8738        synchronized(this) {
8739            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8740            if (r == null) {
8741                throw new IllegalArgumentException();
8742            }
8743            r.immersive = immersive;
8744
8745            // update associated state if we're frontmost
8746            if (r == mFocusedActivity) {
8747                if (DEBUG_IMMERSIVE) {
8748                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
8749                }
8750                applyUpdateLockStateLocked(r);
8751            }
8752        }
8753    }
8754
8755    @Override
8756    public boolean isImmersive(IBinder token) {
8757        synchronized (this) {
8758            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8759            if (r == null) {
8760                throw new IllegalArgumentException();
8761            }
8762            return r.immersive;
8763        }
8764    }
8765
8766    public boolean isTopActivityImmersive() {
8767        enforceNotIsolatedCaller("startActivity");
8768        synchronized (this) {
8769            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
8770            return (r != null) ? r.immersive : false;
8771        }
8772    }
8773
8774    public final void enterSafeMode() {
8775        synchronized(this) {
8776            // It only makes sense to do this before the system is ready
8777            // and started launching other packages.
8778            if (!mSystemReady) {
8779                try {
8780                    AppGlobals.getPackageManager().enterSafeMode();
8781                } catch (RemoteException e) {
8782                }
8783            }
8784        }
8785    }
8786
8787    public final void showSafeModeOverlay() {
8788        View v = LayoutInflater.from(mContext).inflate(
8789                com.android.internal.R.layout.safe_mode, null);
8790        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
8791        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
8792        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
8793        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
8794        lp.gravity = Gravity.BOTTOM | Gravity.START;
8795        lp.format = v.getBackground().getOpacity();
8796        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
8797                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
8798        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
8799        ((WindowManager)mContext.getSystemService(
8800                Context.WINDOW_SERVICE)).addView(v, lp);
8801    }
8802
8803    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
8804        if (!(sender instanceof PendingIntentRecord)) {
8805            return;
8806        }
8807        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8808        synchronized (stats) {
8809            if (mBatteryStatsService.isOnBattery()) {
8810                mBatteryStatsService.enforceCallingPermission();
8811                PendingIntentRecord rec = (PendingIntentRecord)sender;
8812                int MY_UID = Binder.getCallingUid();
8813                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
8814                BatteryStatsImpl.Uid.Pkg pkg =
8815                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
8816                            sourcePkg != null ? sourcePkg : rec.key.packageName);
8817                pkg.incWakeupsLocked();
8818            }
8819        }
8820    }
8821
8822    public boolean killPids(int[] pids, String pReason, boolean secure) {
8823        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8824            throw new SecurityException("killPids only available to the system");
8825        }
8826        String reason = (pReason == null) ? "Unknown" : pReason;
8827        // XXX Note: don't acquire main activity lock here, because the window
8828        // manager calls in with its locks held.
8829
8830        boolean killed = false;
8831        synchronized (mPidsSelfLocked) {
8832            int[] types = new int[pids.length];
8833            int worstType = 0;
8834            for (int i=0; i<pids.length; i++) {
8835                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8836                if (proc != null) {
8837                    int type = proc.setAdj;
8838                    types[i] = type;
8839                    if (type > worstType) {
8840                        worstType = type;
8841                    }
8842                }
8843            }
8844
8845            // If the worst oom_adj is somewhere in the cached proc LRU range,
8846            // then constrain it so we will kill all cached procs.
8847            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
8848                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
8849                worstType = ProcessList.CACHED_APP_MIN_ADJ;
8850            }
8851
8852            // If this is not a secure call, don't let it kill processes that
8853            // are important.
8854            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
8855                worstType = ProcessList.SERVICE_ADJ;
8856            }
8857
8858            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
8859            for (int i=0; i<pids.length; i++) {
8860                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8861                if (proc == null) {
8862                    continue;
8863                }
8864                int adj = proc.setAdj;
8865                if (adj >= worstType && !proc.killedByAm) {
8866                    killUnneededProcessLocked(proc, reason);
8867                    killed = true;
8868                }
8869            }
8870        }
8871        return killed;
8872    }
8873
8874    @Override
8875    public void killUid(int uid, String reason) {
8876        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8877            throw new SecurityException("killUid only available to the system");
8878        }
8879        synchronized (this) {
8880            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
8881                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
8882                    reason != null ? reason : "kill uid");
8883        }
8884    }
8885
8886    @Override
8887    public boolean killProcessesBelowForeground(String reason) {
8888        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8889            throw new SecurityException("killProcessesBelowForeground() only available to system");
8890        }
8891
8892        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
8893    }
8894
8895    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
8896        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8897            throw new SecurityException("killProcessesBelowAdj() only available to system");
8898        }
8899
8900        boolean killed = false;
8901        synchronized (mPidsSelfLocked) {
8902            final int size = mPidsSelfLocked.size();
8903            for (int i = 0; i < size; i++) {
8904                final int pid = mPidsSelfLocked.keyAt(i);
8905                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
8906                if (proc == null) continue;
8907
8908                final int adj = proc.setAdj;
8909                if (adj > belowAdj && !proc.killedByAm) {
8910                    killUnneededProcessLocked(proc, reason);
8911                    killed = true;
8912                }
8913            }
8914        }
8915        return killed;
8916    }
8917
8918    @Override
8919    public void hang(final IBinder who, boolean allowRestart) {
8920        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8921                != PackageManager.PERMISSION_GRANTED) {
8922            throw new SecurityException("Requires permission "
8923                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8924        }
8925
8926        final IBinder.DeathRecipient death = new DeathRecipient() {
8927            @Override
8928            public void binderDied() {
8929                synchronized (this) {
8930                    notifyAll();
8931                }
8932            }
8933        };
8934
8935        try {
8936            who.linkToDeath(death, 0);
8937        } catch (RemoteException e) {
8938            Slog.w(TAG, "hang: given caller IBinder is already dead.");
8939            return;
8940        }
8941
8942        synchronized (this) {
8943            Watchdog.getInstance().setAllowRestart(allowRestart);
8944            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
8945            synchronized (death) {
8946                while (who.isBinderAlive()) {
8947                    try {
8948                        death.wait();
8949                    } catch (InterruptedException e) {
8950                    }
8951                }
8952            }
8953            Watchdog.getInstance().setAllowRestart(true);
8954        }
8955    }
8956
8957    @Override
8958    public void restart() {
8959        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8960                != PackageManager.PERMISSION_GRANTED) {
8961            throw new SecurityException("Requires permission "
8962                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8963        }
8964
8965        Log.i(TAG, "Sending shutdown broadcast...");
8966
8967        BroadcastReceiver br = new BroadcastReceiver() {
8968            @Override public void onReceive(Context context, Intent intent) {
8969                // Now the broadcast is done, finish up the low-level shutdown.
8970                Log.i(TAG, "Shutting down activity manager...");
8971                shutdown(10000);
8972                Log.i(TAG, "Shutdown complete, restarting!");
8973                Process.killProcess(Process.myPid());
8974                System.exit(10);
8975            }
8976        };
8977
8978        // First send the high-level shut down broadcast.
8979        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
8980        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
8981        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
8982        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
8983        mContext.sendOrderedBroadcastAsUser(intent,
8984                UserHandle.ALL, null, br, mHandler, 0, null, null);
8985        */
8986        br.onReceive(mContext, intent);
8987    }
8988
8989    private long getLowRamTimeSinceIdle(long now) {
8990        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
8991    }
8992
8993    @Override
8994    public void performIdleMaintenance() {
8995        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8996                != PackageManager.PERMISSION_GRANTED) {
8997            throw new SecurityException("Requires permission "
8998                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8999        }
9000
9001        synchronized (this) {
9002            final long now = SystemClock.uptimeMillis();
9003            final long timeSinceLastIdle = now - mLastIdleTime;
9004            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9005            mLastIdleTime = now;
9006            mLowRamTimeSinceLastIdle = 0;
9007            if (mLowRamStartTime != 0) {
9008                mLowRamStartTime = now;
9009            }
9010
9011            StringBuilder sb = new StringBuilder(128);
9012            sb.append("Idle maintenance over ");
9013            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9014            sb.append(" low RAM for ");
9015            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9016            Slog.i(TAG, sb.toString());
9017
9018            // If at least 1/3 of our time since the last idle period has been spent
9019            // with RAM low, then we want to kill processes.
9020            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9021
9022            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9023                ProcessRecord proc = mLruProcesses.get(i);
9024                if (proc.notCachedSinceIdle) {
9025                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9026                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9027                        if (doKilling && proc.initialIdlePss != 0
9028                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9029                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9030                                    + " from " + proc.initialIdlePss + ")");
9031                        }
9032                    }
9033                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9034                    proc.notCachedSinceIdle = true;
9035                    proc.initialIdlePss = 0;
9036                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9037                            mSleeping, now);
9038                }
9039            }
9040
9041            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9042            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9043        }
9044    }
9045
9046    public final void startRunning(String pkg, String cls, String action,
9047            String data) {
9048        synchronized(this) {
9049            if (mStartRunning) {
9050                return;
9051            }
9052            mStartRunning = true;
9053            mTopComponent = pkg != null && cls != null
9054                    ? new ComponentName(pkg, cls) : null;
9055            mTopAction = action != null ? action : Intent.ACTION_MAIN;
9056            mTopData = data;
9057            if (!mSystemReady) {
9058                return;
9059            }
9060        }
9061
9062        systemReady(null);
9063    }
9064
9065    private void retrieveSettings() {
9066        final ContentResolver resolver = mContext.getContentResolver();
9067        String debugApp = Settings.Global.getString(
9068            resolver, Settings.Global.DEBUG_APP);
9069        boolean waitForDebugger = Settings.Global.getInt(
9070            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9071        boolean alwaysFinishActivities = Settings.Global.getInt(
9072            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9073        boolean forceRtl = Settings.Global.getInt(
9074                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9075        // Transfer any global setting for forcing RTL layout, into a System Property
9076        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9077
9078        Configuration configuration = new Configuration();
9079        Settings.System.getConfiguration(resolver, configuration);
9080        if (forceRtl) {
9081            // This will take care of setting the correct layout direction flags
9082            configuration.setLayoutDirection(configuration.locale);
9083        }
9084
9085        synchronized (this) {
9086            mDebugApp = mOrigDebugApp = debugApp;
9087            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9088            mAlwaysFinishActivities = alwaysFinishActivities;
9089            // This happens before any activities are started, so we can
9090            // change mConfiguration in-place.
9091            updateConfigurationLocked(configuration, null, false, true);
9092            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9093        }
9094    }
9095
9096    public boolean testIsSystemReady() {
9097        // no need to synchronize(this) just to read & return the value
9098        return mSystemReady;
9099    }
9100
9101    private static File getCalledPreBootReceiversFile() {
9102        File dataDir = Environment.getDataDirectory();
9103        File systemDir = new File(dataDir, "system");
9104        File fname = new File(systemDir, "called_pre_boots.dat");
9105        return fname;
9106    }
9107
9108    static final int LAST_DONE_VERSION = 10000;
9109
9110    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9111        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9112        File file = getCalledPreBootReceiversFile();
9113        FileInputStream fis = null;
9114        try {
9115            fis = new FileInputStream(file);
9116            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9117            int fvers = dis.readInt();
9118            if (fvers == LAST_DONE_VERSION) {
9119                String vers = dis.readUTF();
9120                String codename = dis.readUTF();
9121                String build = dis.readUTF();
9122                if (android.os.Build.VERSION.RELEASE.equals(vers)
9123                        && android.os.Build.VERSION.CODENAME.equals(codename)
9124                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9125                    int num = dis.readInt();
9126                    while (num > 0) {
9127                        num--;
9128                        String pkg = dis.readUTF();
9129                        String cls = dis.readUTF();
9130                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9131                    }
9132                }
9133            }
9134        } catch (FileNotFoundException e) {
9135        } catch (IOException e) {
9136            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9137        } finally {
9138            if (fis != null) {
9139                try {
9140                    fis.close();
9141                } catch (IOException e) {
9142                }
9143            }
9144        }
9145        return lastDoneReceivers;
9146    }
9147
9148    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9149        File file = getCalledPreBootReceiversFile();
9150        FileOutputStream fos = null;
9151        DataOutputStream dos = null;
9152        try {
9153            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9154            fos = new FileOutputStream(file);
9155            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9156            dos.writeInt(LAST_DONE_VERSION);
9157            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9158            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9159            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9160            dos.writeInt(list.size());
9161            for (int i=0; i<list.size(); i++) {
9162                dos.writeUTF(list.get(i).getPackageName());
9163                dos.writeUTF(list.get(i).getClassName());
9164            }
9165        } catch (IOException e) {
9166            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9167            file.delete();
9168        } finally {
9169            FileUtils.sync(fos);
9170            if (dos != null) {
9171                try {
9172                    dos.close();
9173                } catch (IOException e) {
9174                    // TODO Auto-generated catch block
9175                    e.printStackTrace();
9176                }
9177            }
9178        }
9179    }
9180
9181    public void systemReady(final Runnable goingCallback) {
9182        synchronized(this) {
9183            if (mSystemReady) {
9184                if (goingCallback != null) goingCallback.run();
9185                return;
9186            }
9187
9188            // Check to see if there are any update receivers to run.
9189            if (!mDidUpdate) {
9190                if (mWaitingUpdate) {
9191                    return;
9192                }
9193                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9194                List<ResolveInfo> ris = null;
9195                try {
9196                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9197                            intent, null, 0, 0);
9198                } catch (RemoteException e) {
9199                }
9200                if (ris != null) {
9201                    for (int i=ris.size()-1; i>=0; i--) {
9202                        if ((ris.get(i).activityInfo.applicationInfo.flags
9203                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9204                            ris.remove(i);
9205                        }
9206                    }
9207                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9208
9209                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9210
9211                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9212                    for (int i=0; i<ris.size(); i++) {
9213                        ActivityInfo ai = ris.get(i).activityInfo;
9214                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9215                        if (lastDoneReceivers.contains(comp)) {
9216                            ris.remove(i);
9217                            i--;
9218                        }
9219                    }
9220
9221                    final int[] users = getUsersLocked();
9222                    for (int i=0; i<ris.size(); i++) {
9223                        ActivityInfo ai = ris.get(i).activityInfo;
9224                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9225                        doneReceivers.add(comp);
9226                        intent.setComponent(comp);
9227                        for (int j=0; j<users.length; j++) {
9228                            IIntentReceiver finisher = null;
9229                            if (i == ris.size()-1 && j == users.length-1) {
9230                                finisher = new IIntentReceiver.Stub() {
9231                                    public void performReceive(Intent intent, int resultCode,
9232                                            String data, Bundle extras, boolean ordered,
9233                                            boolean sticky, int sendingUser) {
9234                                        // The raw IIntentReceiver interface is called
9235                                        // with the AM lock held, so redispatch to
9236                                        // execute our code without the lock.
9237                                        mHandler.post(new Runnable() {
9238                                            public void run() {
9239                                                synchronized (ActivityManagerService.this) {
9240                                                    mDidUpdate = true;
9241                                                }
9242                                                writeLastDonePreBootReceivers(doneReceivers);
9243                                                showBootMessage(mContext.getText(
9244                                                        R.string.android_upgrading_complete),
9245                                                        false);
9246                                                systemReady(goingCallback);
9247                                            }
9248                                        });
9249                                    }
9250                                };
9251                            }
9252                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9253                                    + " for user " + users[j]);
9254                            broadcastIntentLocked(null, null, intent, null, finisher,
9255                                    0, null, null, null, AppOpsManager.OP_NONE,
9256                                    true, false, MY_PID, Process.SYSTEM_UID,
9257                                    users[j]);
9258                            if (finisher != null) {
9259                                mWaitingUpdate = true;
9260                            }
9261                        }
9262                    }
9263                }
9264                if (mWaitingUpdate) {
9265                    return;
9266                }
9267                mDidUpdate = true;
9268            }
9269
9270            mAppOpsService.systemReady();
9271            mSystemReady = true;
9272            if (!mStartRunning) {
9273                return;
9274            }
9275        }
9276
9277        ArrayList<ProcessRecord> procsToKill = null;
9278        synchronized(mPidsSelfLocked) {
9279            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9280                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9281                if (!isAllowedWhileBooting(proc.info)){
9282                    if (procsToKill == null) {
9283                        procsToKill = new ArrayList<ProcessRecord>();
9284                    }
9285                    procsToKill.add(proc);
9286                }
9287            }
9288        }
9289
9290        synchronized(this) {
9291            if (procsToKill != null) {
9292                for (int i=procsToKill.size()-1; i>=0; i--) {
9293                    ProcessRecord proc = procsToKill.get(i);
9294                    Slog.i(TAG, "Removing system update proc: " + proc);
9295                    removeProcessLocked(proc, true, false, "system update done");
9296                }
9297            }
9298
9299            // Now that we have cleaned up any update processes, we
9300            // are ready to start launching real processes and know that
9301            // we won't trample on them any more.
9302            mProcessesReady = true;
9303        }
9304
9305        Slog.i(TAG, "System now ready");
9306        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9307            SystemClock.uptimeMillis());
9308
9309        synchronized(this) {
9310            // Make sure we have no pre-ready processes sitting around.
9311
9312            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9313                ResolveInfo ri = mContext.getPackageManager()
9314                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9315                                STOCK_PM_FLAGS);
9316                CharSequence errorMsg = null;
9317                if (ri != null) {
9318                    ActivityInfo ai = ri.activityInfo;
9319                    ApplicationInfo app = ai.applicationInfo;
9320                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9321                        mTopAction = Intent.ACTION_FACTORY_TEST;
9322                        mTopData = null;
9323                        mTopComponent = new ComponentName(app.packageName,
9324                                ai.name);
9325                    } else {
9326                        errorMsg = mContext.getResources().getText(
9327                                com.android.internal.R.string.factorytest_not_system);
9328                    }
9329                } else {
9330                    errorMsg = mContext.getResources().getText(
9331                            com.android.internal.R.string.factorytest_no_action);
9332                }
9333                if (errorMsg != null) {
9334                    mTopAction = null;
9335                    mTopData = null;
9336                    mTopComponent = null;
9337                    Message msg = Message.obtain();
9338                    msg.what = SHOW_FACTORY_ERROR_MSG;
9339                    msg.getData().putCharSequence("msg", errorMsg);
9340                    mHandler.sendMessage(msg);
9341                }
9342            }
9343        }
9344
9345        retrieveSettings();
9346
9347        synchronized (this) {
9348            readGrantedUriPermissionsLocked();
9349        }
9350
9351        if (goingCallback != null) goingCallback.run();
9352
9353        synchronized (this) {
9354            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9355                try {
9356                    List apps = AppGlobals.getPackageManager().
9357                        getPersistentApplications(STOCK_PM_FLAGS);
9358                    if (apps != null) {
9359                        int N = apps.size();
9360                        int i;
9361                        for (i=0; i<N; i++) {
9362                            ApplicationInfo info
9363                                = (ApplicationInfo)apps.get(i);
9364                            if (info != null &&
9365                                    !info.packageName.equals("android")) {
9366                                addAppLocked(info, false);
9367                            }
9368                        }
9369                    }
9370                } catch (RemoteException ex) {
9371                    // pm is in same process, this will never happen.
9372                }
9373            }
9374
9375            // Start up initial activity.
9376            mBooting = true;
9377
9378            try {
9379                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9380                    Message msg = Message.obtain();
9381                    msg.what = SHOW_UID_ERROR_MSG;
9382                    mHandler.sendMessage(msg);
9383                }
9384            } catch (RemoteException e) {
9385            }
9386
9387            long ident = Binder.clearCallingIdentity();
9388            try {
9389                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9390                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9391                        | Intent.FLAG_RECEIVER_FOREGROUND);
9392                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9393                broadcastIntentLocked(null, null, intent,
9394                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9395                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9396                intent = new Intent(Intent.ACTION_USER_STARTING);
9397                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9398                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9399                broadcastIntentLocked(null, null, intent,
9400                        null, new IIntentReceiver.Stub() {
9401                            @Override
9402                            public void performReceive(Intent intent, int resultCode, String data,
9403                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9404                                    throws RemoteException {
9405                            }
9406                        }, 0, null, null,
9407                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9408                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9409            } finally {
9410                Binder.restoreCallingIdentity(ident);
9411            }
9412            mStackSupervisor.resumeTopActivitiesLocked();
9413            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9414        }
9415    }
9416
9417    private boolean makeAppCrashingLocked(ProcessRecord app,
9418            String shortMsg, String longMsg, String stackTrace) {
9419        app.crashing = true;
9420        app.crashingReport = generateProcessError(app,
9421                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9422        startAppProblemLocked(app);
9423        app.stopFreezingAllLocked();
9424        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9425    }
9426
9427    private void makeAppNotRespondingLocked(ProcessRecord app,
9428            String activity, String shortMsg, String longMsg) {
9429        app.notResponding = true;
9430        app.notRespondingReport = generateProcessError(app,
9431                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9432                activity, shortMsg, longMsg, null);
9433        startAppProblemLocked(app);
9434        app.stopFreezingAllLocked();
9435    }
9436
9437    /**
9438     * Generate a process error record, suitable for attachment to a ProcessRecord.
9439     *
9440     * @param app The ProcessRecord in which the error occurred.
9441     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9442     *                      ActivityManager.AppErrorStateInfo
9443     * @param activity The activity associated with the crash, if known.
9444     * @param shortMsg Short message describing the crash.
9445     * @param longMsg Long message describing the crash.
9446     * @param stackTrace Full crash stack trace, may be null.
9447     *
9448     * @return Returns a fully-formed AppErrorStateInfo record.
9449     */
9450    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9451            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9452        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9453
9454        report.condition = condition;
9455        report.processName = app.processName;
9456        report.pid = app.pid;
9457        report.uid = app.info.uid;
9458        report.tag = activity;
9459        report.shortMsg = shortMsg;
9460        report.longMsg = longMsg;
9461        report.stackTrace = stackTrace;
9462
9463        return report;
9464    }
9465
9466    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9467        synchronized (this) {
9468            app.crashing = false;
9469            app.crashingReport = null;
9470            app.notResponding = false;
9471            app.notRespondingReport = null;
9472            if (app.anrDialog == fromDialog) {
9473                app.anrDialog = null;
9474            }
9475            if (app.waitDialog == fromDialog) {
9476                app.waitDialog = null;
9477            }
9478            if (app.pid > 0 && app.pid != MY_PID) {
9479                handleAppCrashLocked(app, null, null, null);
9480                killUnneededProcessLocked(app, "user request after error");
9481            }
9482        }
9483    }
9484
9485    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9486            String stackTrace) {
9487        long now = SystemClock.uptimeMillis();
9488
9489        Long crashTime;
9490        if (!app.isolated) {
9491            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9492        } else {
9493            crashTime = null;
9494        }
9495        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9496            // This process loses!
9497            Slog.w(TAG, "Process " + app.info.processName
9498                    + " has crashed too many times: killing!");
9499            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9500                    app.userId, app.info.processName, app.uid);
9501            mStackSupervisor.handleAppCrashLocked(app);
9502            if (!app.persistent) {
9503                // We don't want to start this process again until the user
9504                // explicitly does so...  but for persistent process, we really
9505                // need to keep it running.  If a persistent process is actually
9506                // repeatedly crashing, then badness for everyone.
9507                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9508                        app.info.processName);
9509                if (!app.isolated) {
9510                    // XXX We don't have a way to mark isolated processes
9511                    // as bad, since they don't have a peristent identity.
9512                    mBadProcesses.put(app.info.processName, app.uid,
9513                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9514                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9515                }
9516                app.bad = true;
9517                app.removed = true;
9518                // Don't let services in this process be restarted and potentially
9519                // annoy the user repeatedly.  Unless it is persistent, since those
9520                // processes run critical code.
9521                removeProcessLocked(app, false, false, "crash");
9522                mStackSupervisor.resumeTopActivitiesLocked();
9523                return false;
9524            }
9525            mStackSupervisor.resumeTopActivitiesLocked();
9526        } else {
9527            mStackSupervisor.finishTopRunningActivityLocked(app);
9528        }
9529
9530        // Bump up the crash count of any services currently running in the proc.
9531        for (int i=app.services.size()-1; i>=0; i--) {
9532            // Any services running in the application need to be placed
9533            // back in the pending list.
9534            ServiceRecord sr = app.services.valueAt(i);
9535            sr.crashCount++;
9536        }
9537
9538        // If the crashing process is what we consider to be the "home process" and it has been
9539        // replaced by a third-party app, clear the package preferred activities from packages
9540        // with a home activity running in the process to prevent a repeatedly crashing app
9541        // from blocking the user to manually clear the list.
9542        final ArrayList<ActivityRecord> activities = app.activities;
9543        if (app == mHomeProcess && activities.size() > 0
9544                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9545            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9546                final ActivityRecord r = activities.get(activityNdx);
9547                if (r.isHomeActivity()) {
9548                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9549                    try {
9550                        ActivityThread.getPackageManager()
9551                                .clearPackagePreferredActivities(r.packageName);
9552                    } catch (RemoteException c) {
9553                        // pm is in same process, this will never happen.
9554                    }
9555                }
9556            }
9557        }
9558
9559        if (!app.isolated) {
9560            // XXX Can't keep track of crash times for isolated processes,
9561            // because they don't have a perisistent identity.
9562            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9563        }
9564
9565        return true;
9566    }
9567
9568    void startAppProblemLocked(ProcessRecord app) {
9569        if (app.userId == mCurrentUserId) {
9570            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9571                    mContext, app.info.packageName, app.info.flags);
9572        } else {
9573            // If this app is not running under the current user, then we
9574            // can't give it a report button because that would require
9575            // launching the report UI under a different user.
9576            app.errorReportReceiver = null;
9577        }
9578        skipCurrentReceiverLocked(app);
9579    }
9580
9581    void skipCurrentReceiverLocked(ProcessRecord app) {
9582        for (BroadcastQueue queue : mBroadcastQueues) {
9583            queue.skipCurrentReceiverLocked(app);
9584        }
9585    }
9586
9587    /**
9588     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9589     * The application process will exit immediately after this call returns.
9590     * @param app object of the crashing app, null for the system server
9591     * @param crashInfo describing the exception
9592     */
9593    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9594        ProcessRecord r = findAppProcess(app, "Crash");
9595        final String processName = app == null ? "system_server"
9596                : (r == null ? "unknown" : r.processName);
9597
9598        handleApplicationCrashInner("crash", r, processName, crashInfo);
9599    }
9600
9601    /* Native crash reporting uses this inner version because it needs to be somewhat
9602     * decoupled from the AM-managed cleanup lifecycle
9603     */
9604    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
9605            ApplicationErrorReport.CrashInfo crashInfo) {
9606        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
9607                UserHandle.getUserId(Binder.getCallingUid()), processName,
9608                r == null ? -1 : r.info.flags,
9609                crashInfo.exceptionClassName,
9610                crashInfo.exceptionMessage,
9611                crashInfo.throwFileName,
9612                crashInfo.throwLineNumber);
9613
9614        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
9615
9616        crashApplication(r, crashInfo);
9617    }
9618
9619    public void handleApplicationStrictModeViolation(
9620            IBinder app,
9621            int violationMask,
9622            StrictMode.ViolationInfo info) {
9623        ProcessRecord r = findAppProcess(app, "StrictMode");
9624        if (r == null) {
9625            return;
9626        }
9627
9628        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
9629            Integer stackFingerprint = info.hashCode();
9630            boolean logIt = true;
9631            synchronized (mAlreadyLoggedViolatedStacks) {
9632                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
9633                    logIt = false;
9634                    // TODO: sub-sample into EventLog for these, with
9635                    // the info.durationMillis?  Then we'd get
9636                    // the relative pain numbers, without logging all
9637                    // the stack traces repeatedly.  We'd want to do
9638                    // likewise in the client code, which also does
9639                    // dup suppression, before the Binder call.
9640                } else {
9641                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
9642                        mAlreadyLoggedViolatedStacks.clear();
9643                    }
9644                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
9645                }
9646            }
9647            if (logIt) {
9648                logStrictModeViolationToDropBox(r, info);
9649            }
9650        }
9651
9652        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
9653            AppErrorResult result = new AppErrorResult();
9654            synchronized (this) {
9655                final long origId = Binder.clearCallingIdentity();
9656
9657                Message msg = Message.obtain();
9658                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
9659                HashMap<String, Object> data = new HashMap<String, Object>();
9660                data.put("result", result);
9661                data.put("app", r);
9662                data.put("violationMask", violationMask);
9663                data.put("info", info);
9664                msg.obj = data;
9665                mHandler.sendMessage(msg);
9666
9667                Binder.restoreCallingIdentity(origId);
9668            }
9669            int res = result.get();
9670            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
9671        }
9672    }
9673
9674    // Depending on the policy in effect, there could be a bunch of
9675    // these in quick succession so we try to batch these together to
9676    // minimize disk writes, number of dropbox entries, and maximize
9677    // compression, by having more fewer, larger records.
9678    private void logStrictModeViolationToDropBox(
9679            ProcessRecord process,
9680            StrictMode.ViolationInfo info) {
9681        if (info == null) {
9682            return;
9683        }
9684        final boolean isSystemApp = process == null ||
9685                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
9686                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
9687        final String processName = process == null ? "unknown" : process.processName;
9688        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
9689        final DropBoxManager dbox = (DropBoxManager)
9690                mContext.getSystemService(Context.DROPBOX_SERVICE);
9691
9692        // Exit early if the dropbox isn't configured to accept this report type.
9693        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9694
9695        boolean bufferWasEmpty;
9696        boolean needsFlush;
9697        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
9698        synchronized (sb) {
9699            bufferWasEmpty = sb.length() == 0;
9700            appendDropBoxProcessHeaders(process, processName, sb);
9701            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9702            sb.append("System-App: ").append(isSystemApp).append("\n");
9703            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
9704            if (info.violationNumThisLoop != 0) {
9705                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
9706            }
9707            if (info.numAnimationsRunning != 0) {
9708                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
9709            }
9710            if (info.broadcastIntentAction != null) {
9711                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
9712            }
9713            if (info.durationMillis != -1) {
9714                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
9715            }
9716            if (info.numInstances != -1) {
9717                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
9718            }
9719            if (info.tags != null) {
9720                for (String tag : info.tags) {
9721                    sb.append("Span-Tag: ").append(tag).append("\n");
9722                }
9723            }
9724            sb.append("\n");
9725            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
9726                sb.append(info.crashInfo.stackTrace);
9727            }
9728            sb.append("\n");
9729
9730            // Only buffer up to ~64k.  Various logging bits truncate
9731            // things at 128k.
9732            needsFlush = (sb.length() > 64 * 1024);
9733        }
9734
9735        // Flush immediately if the buffer's grown too large, or this
9736        // is a non-system app.  Non-system apps are isolated with a
9737        // different tag & policy and not batched.
9738        //
9739        // Batching is useful during internal testing with
9740        // StrictMode settings turned up high.  Without batching,
9741        // thousands of separate files could be created on boot.
9742        if (!isSystemApp || needsFlush) {
9743            new Thread("Error dump: " + dropboxTag) {
9744                @Override
9745                public void run() {
9746                    String report;
9747                    synchronized (sb) {
9748                        report = sb.toString();
9749                        sb.delete(0, sb.length());
9750                        sb.trimToSize();
9751                    }
9752                    if (report.length() != 0) {
9753                        dbox.addText(dropboxTag, report);
9754                    }
9755                }
9756            }.start();
9757            return;
9758        }
9759
9760        // System app batching:
9761        if (!bufferWasEmpty) {
9762            // An existing dropbox-writing thread is outstanding, so
9763            // we don't need to start it up.  The existing thread will
9764            // catch the buffer appends we just did.
9765            return;
9766        }
9767
9768        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
9769        // (After this point, we shouldn't access AMS internal data structures.)
9770        new Thread("Error dump: " + dropboxTag) {
9771            @Override
9772            public void run() {
9773                // 5 second sleep to let stacks arrive and be batched together
9774                try {
9775                    Thread.sleep(5000);  // 5 seconds
9776                } catch (InterruptedException e) {}
9777
9778                String errorReport;
9779                synchronized (mStrictModeBuffer) {
9780                    errorReport = mStrictModeBuffer.toString();
9781                    if (errorReport.length() == 0) {
9782                        return;
9783                    }
9784                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
9785                    mStrictModeBuffer.trimToSize();
9786                }
9787                dbox.addText(dropboxTag, errorReport);
9788            }
9789        }.start();
9790    }
9791
9792    /**
9793     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
9794     * @param app object of the crashing app, null for the system server
9795     * @param tag reported by the caller
9796     * @param crashInfo describing the context of the error
9797     * @return true if the process should exit immediately (WTF is fatal)
9798     */
9799    public boolean handleApplicationWtf(IBinder app, String tag,
9800            ApplicationErrorReport.CrashInfo crashInfo) {
9801        ProcessRecord r = findAppProcess(app, "WTF");
9802        final String processName = app == null ? "system_server"
9803                : (r == null ? "unknown" : r.processName);
9804
9805        EventLog.writeEvent(EventLogTags.AM_WTF,
9806                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
9807                processName,
9808                r == null ? -1 : r.info.flags,
9809                tag, crashInfo.exceptionMessage);
9810
9811        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
9812
9813        if (r != null && r.pid != Process.myPid() &&
9814                Settings.Global.getInt(mContext.getContentResolver(),
9815                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
9816            crashApplication(r, crashInfo);
9817            return true;
9818        } else {
9819            return false;
9820        }
9821    }
9822
9823    /**
9824     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
9825     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
9826     */
9827    private ProcessRecord findAppProcess(IBinder app, String reason) {
9828        if (app == null) {
9829            return null;
9830        }
9831
9832        synchronized (this) {
9833            final int NP = mProcessNames.getMap().size();
9834            for (int ip=0; ip<NP; ip++) {
9835                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
9836                final int NA = apps.size();
9837                for (int ia=0; ia<NA; ia++) {
9838                    ProcessRecord p = apps.valueAt(ia);
9839                    if (p.thread != null && p.thread.asBinder() == app) {
9840                        return p;
9841                    }
9842                }
9843            }
9844
9845            Slog.w(TAG, "Can't find mystery application for " + reason
9846                    + " from pid=" + Binder.getCallingPid()
9847                    + " uid=" + Binder.getCallingUid() + ": " + app);
9848            return null;
9849        }
9850    }
9851
9852    /**
9853     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
9854     * to append various headers to the dropbox log text.
9855     */
9856    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
9857            StringBuilder sb) {
9858        // Watchdog thread ends up invoking this function (with
9859        // a null ProcessRecord) to add the stack file to dropbox.
9860        // Do not acquire a lock on this (am) in such cases, as it
9861        // could cause a potential deadlock, if and when watchdog
9862        // is invoked due to unavailability of lock on am and it
9863        // would prevent watchdog from killing system_server.
9864        if (process == null) {
9865            sb.append("Process: ").append(processName).append("\n");
9866            return;
9867        }
9868        // Note: ProcessRecord 'process' is guarded by the service
9869        // instance.  (notably process.pkgList, which could otherwise change
9870        // concurrently during execution of this method)
9871        synchronized (this) {
9872            sb.append("Process: ").append(processName).append("\n");
9873            int flags = process.info.flags;
9874            IPackageManager pm = AppGlobals.getPackageManager();
9875            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
9876            for (int ip=0; ip<process.pkgList.size(); ip++) {
9877                String pkg = process.pkgList.keyAt(ip);
9878                sb.append("Package: ").append(pkg);
9879                try {
9880                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
9881                    if (pi != null) {
9882                        sb.append(" v").append(pi.versionCode);
9883                        if (pi.versionName != null) {
9884                            sb.append(" (").append(pi.versionName).append(")");
9885                        }
9886                    }
9887                } catch (RemoteException e) {
9888                    Slog.e(TAG, "Error getting package info: " + pkg, e);
9889                }
9890                sb.append("\n");
9891            }
9892        }
9893    }
9894
9895    private static String processClass(ProcessRecord process) {
9896        if (process == null || process.pid == MY_PID) {
9897            return "system_server";
9898        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
9899            return "system_app";
9900        } else {
9901            return "data_app";
9902        }
9903    }
9904
9905    /**
9906     * Write a description of an error (crash, WTF, ANR) to the drop box.
9907     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
9908     * @param process which caused the error, null means the system server
9909     * @param activity which triggered the error, null if unknown
9910     * @param parent activity related to the error, null if unknown
9911     * @param subject line related to the error, null if absent
9912     * @param report in long form describing the error, null if absent
9913     * @param logFile to include in the report, null if none
9914     * @param crashInfo giving an application stack trace, null if absent
9915     */
9916    public void addErrorToDropBox(String eventType,
9917            ProcessRecord process, String processName, ActivityRecord activity,
9918            ActivityRecord parent, String subject,
9919            final String report, final File logFile,
9920            final ApplicationErrorReport.CrashInfo crashInfo) {
9921        // NOTE -- this must never acquire the ActivityManagerService lock,
9922        // otherwise the watchdog may be prevented from resetting the system.
9923
9924        final String dropboxTag = processClass(process) + "_" + eventType;
9925        final DropBoxManager dbox = (DropBoxManager)
9926                mContext.getSystemService(Context.DROPBOX_SERVICE);
9927
9928        // Exit early if the dropbox isn't configured to accept this report type.
9929        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9930
9931        final StringBuilder sb = new StringBuilder(1024);
9932        appendDropBoxProcessHeaders(process, processName, sb);
9933        if (activity != null) {
9934            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
9935        }
9936        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
9937            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
9938        }
9939        if (parent != null && parent != activity) {
9940            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
9941        }
9942        if (subject != null) {
9943            sb.append("Subject: ").append(subject).append("\n");
9944        }
9945        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9946        if (Debug.isDebuggerConnected()) {
9947            sb.append("Debugger: Connected\n");
9948        }
9949        sb.append("\n");
9950
9951        // Do the rest in a worker thread to avoid blocking the caller on I/O
9952        // (After this point, we shouldn't access AMS internal data structures.)
9953        Thread worker = new Thread("Error dump: " + dropboxTag) {
9954            @Override
9955            public void run() {
9956                if (report != null) {
9957                    sb.append(report);
9958                }
9959                if (logFile != null) {
9960                    try {
9961                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
9962                                    "\n\n[[TRUNCATED]]"));
9963                    } catch (IOException e) {
9964                        Slog.e(TAG, "Error reading " + logFile, e);
9965                    }
9966                }
9967                if (crashInfo != null && crashInfo.stackTrace != null) {
9968                    sb.append(crashInfo.stackTrace);
9969                }
9970
9971                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
9972                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
9973                if (lines > 0) {
9974                    sb.append("\n");
9975
9976                    // Merge several logcat streams, and take the last N lines
9977                    InputStreamReader input = null;
9978                    try {
9979                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
9980                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
9981                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
9982
9983                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
9984                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
9985                        input = new InputStreamReader(logcat.getInputStream());
9986
9987                        int num;
9988                        char[] buf = new char[8192];
9989                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
9990                    } catch (IOException e) {
9991                        Slog.e(TAG, "Error running logcat", e);
9992                    } finally {
9993                        if (input != null) try { input.close(); } catch (IOException e) {}
9994                    }
9995                }
9996
9997                dbox.addText(dropboxTag, sb.toString());
9998            }
9999        };
10000
10001        if (process == null) {
10002            // If process is null, we are being called from some internal code
10003            // and may be about to die -- run this synchronously.
10004            worker.run();
10005        } else {
10006            worker.start();
10007        }
10008    }
10009
10010    /**
10011     * Bring up the "unexpected error" dialog box for a crashing app.
10012     * Deal with edge cases (intercepts from instrumented applications,
10013     * ActivityController, error intent receivers, that sort of thing).
10014     * @param r the application crashing
10015     * @param crashInfo describing the failure
10016     */
10017    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10018        long timeMillis = System.currentTimeMillis();
10019        String shortMsg = crashInfo.exceptionClassName;
10020        String longMsg = crashInfo.exceptionMessage;
10021        String stackTrace = crashInfo.stackTrace;
10022        if (shortMsg != null && longMsg != null) {
10023            longMsg = shortMsg + ": " + longMsg;
10024        } else if (shortMsg != null) {
10025            longMsg = shortMsg;
10026        }
10027
10028        AppErrorResult result = new AppErrorResult();
10029        synchronized (this) {
10030            if (mController != null) {
10031                try {
10032                    String name = r != null ? r.processName : null;
10033                    int pid = r != null ? r.pid : Binder.getCallingPid();
10034                    if (!mController.appCrashed(name, pid,
10035                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10036                        Slog.w(TAG, "Force-killing crashed app " + name
10037                                + " at watcher's request");
10038                        Process.killProcess(pid);
10039                        return;
10040                    }
10041                } catch (RemoteException e) {
10042                    mController = null;
10043                    Watchdog.getInstance().setActivityController(null);
10044                }
10045            }
10046
10047            final long origId = Binder.clearCallingIdentity();
10048
10049            // If this process is running instrumentation, finish it.
10050            if (r != null && r.instrumentationClass != null) {
10051                Slog.w(TAG, "Error in app " + r.processName
10052                      + " running instrumentation " + r.instrumentationClass + ":");
10053                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10054                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10055                Bundle info = new Bundle();
10056                info.putString("shortMsg", shortMsg);
10057                info.putString("longMsg", longMsg);
10058                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10059                Binder.restoreCallingIdentity(origId);
10060                return;
10061            }
10062
10063            // If we can't identify the process or it's already exceeded its crash quota,
10064            // quit right away without showing a crash dialog.
10065            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10066                Binder.restoreCallingIdentity(origId);
10067                return;
10068            }
10069
10070            Message msg = Message.obtain();
10071            msg.what = SHOW_ERROR_MSG;
10072            HashMap data = new HashMap();
10073            data.put("result", result);
10074            data.put("app", r);
10075            msg.obj = data;
10076            mHandler.sendMessage(msg);
10077
10078            Binder.restoreCallingIdentity(origId);
10079        }
10080
10081        int res = result.get();
10082
10083        Intent appErrorIntent = null;
10084        synchronized (this) {
10085            if (r != null && !r.isolated) {
10086                // XXX Can't keep track of crash time for isolated processes,
10087                // since they don't have a persistent identity.
10088                mProcessCrashTimes.put(r.info.processName, r.uid,
10089                        SystemClock.uptimeMillis());
10090            }
10091            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10092                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10093            }
10094        }
10095
10096        if (appErrorIntent != null) {
10097            try {
10098                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10099            } catch (ActivityNotFoundException e) {
10100                Slog.w(TAG, "bug report receiver dissappeared", e);
10101            }
10102        }
10103    }
10104
10105    Intent createAppErrorIntentLocked(ProcessRecord r,
10106            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10107        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10108        if (report == null) {
10109            return null;
10110        }
10111        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10112        result.setComponent(r.errorReportReceiver);
10113        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10114        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10115        return result;
10116    }
10117
10118    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10119            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10120        if (r.errorReportReceiver == null) {
10121            return null;
10122        }
10123
10124        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10125            return null;
10126        }
10127
10128        ApplicationErrorReport report = new ApplicationErrorReport();
10129        report.packageName = r.info.packageName;
10130        report.installerPackageName = r.errorReportReceiver.getPackageName();
10131        report.processName = r.processName;
10132        report.time = timeMillis;
10133        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10134
10135        if (r.crashing || r.forceCrashReport) {
10136            report.type = ApplicationErrorReport.TYPE_CRASH;
10137            report.crashInfo = crashInfo;
10138        } else if (r.notResponding) {
10139            report.type = ApplicationErrorReport.TYPE_ANR;
10140            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10141
10142            report.anrInfo.activity = r.notRespondingReport.tag;
10143            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10144            report.anrInfo.info = r.notRespondingReport.longMsg;
10145        }
10146
10147        return report;
10148    }
10149
10150    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10151        enforceNotIsolatedCaller("getProcessesInErrorState");
10152        // assume our apps are happy - lazy create the list
10153        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10154
10155        final boolean allUsers = ActivityManager.checkUidPermission(
10156                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10157                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10158        int userId = UserHandle.getUserId(Binder.getCallingUid());
10159
10160        synchronized (this) {
10161
10162            // iterate across all processes
10163            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10164                ProcessRecord app = mLruProcesses.get(i);
10165                if (!allUsers && app.userId != userId) {
10166                    continue;
10167                }
10168                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10169                    // This one's in trouble, so we'll generate a report for it
10170                    // crashes are higher priority (in case there's a crash *and* an anr)
10171                    ActivityManager.ProcessErrorStateInfo report = null;
10172                    if (app.crashing) {
10173                        report = app.crashingReport;
10174                    } else if (app.notResponding) {
10175                        report = app.notRespondingReport;
10176                    }
10177
10178                    if (report != null) {
10179                        if (errList == null) {
10180                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10181                        }
10182                        errList.add(report);
10183                    } else {
10184                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10185                                " crashing = " + app.crashing +
10186                                " notResponding = " + app.notResponding);
10187                    }
10188                }
10189            }
10190        }
10191
10192        return errList;
10193    }
10194
10195    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10196        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10197            if (currApp != null) {
10198                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10199            }
10200            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10201        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10202            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10203        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10204            if (currApp != null) {
10205                currApp.lru = 0;
10206            }
10207            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10208        } else if (adj >= ProcessList.SERVICE_ADJ) {
10209            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10210        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10211            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10212        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10213            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10214        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10215            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10216        } else {
10217            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10218        }
10219    }
10220
10221    private void fillInProcMemInfo(ProcessRecord app,
10222            ActivityManager.RunningAppProcessInfo outInfo) {
10223        outInfo.pid = app.pid;
10224        outInfo.uid = app.info.uid;
10225        if (mHeavyWeightProcess == app) {
10226            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10227        }
10228        if (app.persistent) {
10229            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10230        }
10231        if (app.activities.size() > 0) {
10232            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10233        }
10234        outInfo.lastTrimLevel = app.trimMemoryLevel;
10235        int adj = app.curAdj;
10236        outInfo.importance = oomAdjToImportance(adj, outInfo);
10237        outInfo.importanceReasonCode = app.adjTypeCode;
10238    }
10239
10240    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10241        enforceNotIsolatedCaller("getRunningAppProcesses");
10242        // Lazy instantiation of list
10243        List<ActivityManager.RunningAppProcessInfo> runList = null;
10244        final boolean allUsers = ActivityManager.checkUidPermission(
10245                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10246                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10247        int userId = UserHandle.getUserId(Binder.getCallingUid());
10248        synchronized (this) {
10249            // Iterate across all processes
10250            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10251                ProcessRecord app = mLruProcesses.get(i);
10252                if (!allUsers && app.userId != userId) {
10253                    continue;
10254                }
10255                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10256                    // Generate process state info for running application
10257                    ActivityManager.RunningAppProcessInfo currApp =
10258                        new ActivityManager.RunningAppProcessInfo(app.processName,
10259                                app.pid, app.getPackageList());
10260                    fillInProcMemInfo(app, currApp);
10261                    if (app.adjSource instanceof ProcessRecord) {
10262                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10263                        currApp.importanceReasonImportance = oomAdjToImportance(
10264                                app.adjSourceOom, null);
10265                    } else if (app.adjSource instanceof ActivityRecord) {
10266                        ActivityRecord r = (ActivityRecord)app.adjSource;
10267                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10268                    }
10269                    if (app.adjTarget instanceof ComponentName) {
10270                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10271                    }
10272                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10273                    //        + " lru=" + currApp.lru);
10274                    if (runList == null) {
10275                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10276                    }
10277                    runList.add(currApp);
10278                }
10279            }
10280        }
10281        return runList;
10282    }
10283
10284    public List<ApplicationInfo> getRunningExternalApplications() {
10285        enforceNotIsolatedCaller("getRunningExternalApplications");
10286        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10287        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10288        if (runningApps != null && runningApps.size() > 0) {
10289            Set<String> extList = new HashSet<String>();
10290            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10291                if (app.pkgList != null) {
10292                    for (String pkg : app.pkgList) {
10293                        extList.add(pkg);
10294                    }
10295                }
10296            }
10297            IPackageManager pm = AppGlobals.getPackageManager();
10298            for (String pkg : extList) {
10299                try {
10300                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10301                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10302                        retList.add(info);
10303                    }
10304                } catch (RemoteException e) {
10305                }
10306            }
10307        }
10308        return retList;
10309    }
10310
10311    @Override
10312    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10313        enforceNotIsolatedCaller("getMyMemoryState");
10314        synchronized (this) {
10315            ProcessRecord proc;
10316            synchronized (mPidsSelfLocked) {
10317                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10318            }
10319            fillInProcMemInfo(proc, outInfo);
10320        }
10321    }
10322
10323    @Override
10324    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10325        if (checkCallingPermission(android.Manifest.permission.DUMP)
10326                != PackageManager.PERMISSION_GRANTED) {
10327            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10328                    + Binder.getCallingPid()
10329                    + ", uid=" + Binder.getCallingUid()
10330                    + " without permission "
10331                    + android.Manifest.permission.DUMP);
10332            return;
10333        }
10334
10335        boolean dumpAll = false;
10336        boolean dumpClient = false;
10337        String dumpPackage = null;
10338
10339        int opti = 0;
10340        while (opti < args.length) {
10341            String opt = args[opti];
10342            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10343                break;
10344            }
10345            opti++;
10346            if ("-a".equals(opt)) {
10347                dumpAll = true;
10348            } else if ("-c".equals(opt)) {
10349                dumpClient = true;
10350            } else if ("-h".equals(opt)) {
10351                pw.println("Activity manager dump options:");
10352                pw.println("  [-a] [-c] [-h] [cmd] ...");
10353                pw.println("  cmd may be one of:");
10354                pw.println("    a[ctivities]: activity stack state");
10355                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10356                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10357                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10358                pw.println("    o[om]: out of memory management");
10359                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10360                pw.println("    provider [COMP_SPEC]: provider client-side state");
10361                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10362                pw.println("    service [COMP_SPEC]: service client-side state");
10363                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10364                pw.println("    all: dump all activities");
10365                pw.println("    top: dump the top activity");
10366                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10367                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10368                pw.println("    a partial substring in a component name, a");
10369                pw.println("    hex object identifier.");
10370                pw.println("  -a: include all available server state.");
10371                pw.println("  -c: include client state.");
10372                return;
10373            } else {
10374                pw.println("Unknown argument: " + opt + "; use -h for help");
10375            }
10376        }
10377
10378        long origId = Binder.clearCallingIdentity();
10379        boolean more = false;
10380        // Is the caller requesting to dump a particular piece of data?
10381        if (opti < args.length) {
10382            String cmd = args[opti];
10383            opti++;
10384            if ("activities".equals(cmd) || "a".equals(cmd)) {
10385                synchronized (this) {
10386                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10387                }
10388            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10389                String[] newArgs;
10390                String name;
10391                if (opti >= args.length) {
10392                    name = null;
10393                    newArgs = EMPTY_STRING_ARRAY;
10394                } else {
10395                    name = args[opti];
10396                    opti++;
10397                    newArgs = new String[args.length - opti];
10398                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10399                            args.length - opti);
10400                }
10401                synchronized (this) {
10402                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10403                }
10404            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10405                String[] newArgs;
10406                String name;
10407                if (opti >= args.length) {
10408                    name = null;
10409                    newArgs = EMPTY_STRING_ARRAY;
10410                } else {
10411                    name = args[opti];
10412                    opti++;
10413                    newArgs = new String[args.length - opti];
10414                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10415                            args.length - opti);
10416                }
10417                synchronized (this) {
10418                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10419                }
10420            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10421                String[] newArgs;
10422                String name;
10423                if (opti >= args.length) {
10424                    name = null;
10425                    newArgs = EMPTY_STRING_ARRAY;
10426                } else {
10427                    name = args[opti];
10428                    opti++;
10429                    newArgs = new String[args.length - opti];
10430                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10431                            args.length - opti);
10432                }
10433                synchronized (this) {
10434                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10435                }
10436            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10437                synchronized (this) {
10438                    dumpOomLocked(fd, pw, args, opti, true);
10439                }
10440            } else if ("provider".equals(cmd)) {
10441                String[] newArgs;
10442                String name;
10443                if (opti >= args.length) {
10444                    name = null;
10445                    newArgs = EMPTY_STRING_ARRAY;
10446                } else {
10447                    name = args[opti];
10448                    opti++;
10449                    newArgs = new String[args.length - opti];
10450                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10451                }
10452                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10453                    pw.println("No providers match: " + name);
10454                    pw.println("Use -h for help.");
10455                }
10456            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10457                synchronized (this) {
10458                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10459                }
10460            } else if ("service".equals(cmd)) {
10461                String[] newArgs;
10462                String name;
10463                if (opti >= args.length) {
10464                    name = null;
10465                    newArgs = EMPTY_STRING_ARRAY;
10466                } else {
10467                    name = args[opti];
10468                    opti++;
10469                    newArgs = new String[args.length - opti];
10470                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10471                            args.length - opti);
10472                }
10473                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10474                    pw.println("No services match: " + name);
10475                    pw.println("Use -h for help.");
10476                }
10477            } else if ("package".equals(cmd)) {
10478                String[] newArgs;
10479                if (opti >= args.length) {
10480                    pw.println("package: no package name specified");
10481                    pw.println("Use -h for help.");
10482                } else {
10483                    dumpPackage = args[opti];
10484                    opti++;
10485                    newArgs = new String[args.length - opti];
10486                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10487                            args.length - opti);
10488                    args = newArgs;
10489                    opti = 0;
10490                    more = true;
10491                }
10492            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10493                synchronized (this) {
10494                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10495                }
10496            } else {
10497                // Dumping a single activity?
10498                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10499                    pw.println("Bad activity command, or no activities match: " + cmd);
10500                    pw.println("Use -h for help.");
10501                }
10502            }
10503            if (!more) {
10504                Binder.restoreCallingIdentity(origId);
10505                return;
10506            }
10507        }
10508
10509        // No piece of data specified, dump everything.
10510        synchronized (this) {
10511            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10512            pw.println();
10513            if (dumpAll) {
10514                pw.println("-------------------------------------------------------------------------------");
10515            }
10516            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10517            pw.println();
10518            if (dumpAll) {
10519                pw.println("-------------------------------------------------------------------------------");
10520            }
10521            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10522            pw.println();
10523            if (dumpAll) {
10524                pw.println("-------------------------------------------------------------------------------");
10525            }
10526            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10527            pw.println();
10528            if (dumpAll) {
10529                pw.println("-------------------------------------------------------------------------------");
10530            }
10531            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10532            pw.println();
10533            if (dumpAll) {
10534                pw.println("-------------------------------------------------------------------------------");
10535            }
10536            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10537        }
10538        Binder.restoreCallingIdentity(origId);
10539    }
10540
10541    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10542            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10543        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10544
10545        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10546                dumpPackage);
10547        boolean needSep = printedAnything;
10548
10549        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10550                dumpPackage, needSep, "  mFocusedActivity: ");
10551        if (printed) {
10552            printedAnything = true;
10553            needSep = false;
10554        }
10555
10556        if (dumpPackage == null) {
10557            if (needSep) {
10558                pw.println();
10559            }
10560            needSep = true;
10561            printedAnything = true;
10562            mStackSupervisor.dump(pw, "  ");
10563        }
10564
10565        if (mRecentTasks.size() > 0) {
10566            boolean printedHeader = false;
10567
10568            final int N = mRecentTasks.size();
10569            for (int i=0; i<N; i++) {
10570                TaskRecord tr = mRecentTasks.get(i);
10571                if (dumpPackage != null) {
10572                    if (tr.realActivity == null ||
10573                            !dumpPackage.equals(tr.realActivity)) {
10574                        continue;
10575                    }
10576                }
10577                if (!printedHeader) {
10578                    if (needSep) {
10579                        pw.println();
10580                    }
10581                    pw.println("  Recent tasks:");
10582                    printedHeader = true;
10583                    printedAnything = true;
10584                }
10585                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10586                        pw.println(tr);
10587                if (dumpAll) {
10588                    mRecentTasks.get(i).dump(pw, "    ");
10589                }
10590            }
10591        }
10592
10593        if (!printedAnything) {
10594            pw.println("  (nothing)");
10595        }
10596    }
10597
10598    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10599            int opti, boolean dumpAll, String dumpPackage) {
10600        boolean needSep = false;
10601        boolean printedAnything = false;
10602        int numPers = 0;
10603
10604        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
10605
10606        if (dumpAll) {
10607            final int NP = mProcessNames.getMap().size();
10608            for (int ip=0; ip<NP; ip++) {
10609                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
10610                final int NA = procs.size();
10611                for (int ia=0; ia<NA; ia++) {
10612                    ProcessRecord r = procs.valueAt(ia);
10613                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10614                        continue;
10615                    }
10616                    if (!needSep) {
10617                        pw.println("  All known processes:");
10618                        needSep = true;
10619                        printedAnything = true;
10620                    }
10621                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
10622                        pw.print(" UID "); pw.print(procs.keyAt(ia));
10623                        pw.print(" "); pw.println(r);
10624                    r.dump(pw, "    ");
10625                    if (r.persistent) {
10626                        numPers++;
10627                    }
10628                }
10629            }
10630        }
10631
10632        if (mIsolatedProcesses.size() > 0) {
10633            boolean printed = false;
10634            for (int i=0; i<mIsolatedProcesses.size(); i++) {
10635                ProcessRecord r = mIsolatedProcesses.valueAt(i);
10636                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10637                    continue;
10638                }
10639                if (!printed) {
10640                    if (needSep) {
10641                        pw.println();
10642                    }
10643                    pw.println("  Isolated process list (sorted by uid):");
10644                    printedAnything = true;
10645                    printed = true;
10646                    needSep = true;
10647                }
10648                pw.println(String.format("%sIsolated #%2d: %s",
10649                        "    ", i, r.toString()));
10650            }
10651        }
10652
10653        if (mLruProcesses.size() > 0) {
10654            if (needSep) {
10655                pw.println();
10656            }
10657            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
10658                    pw.print(" total, non-act at ");
10659                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10660                    pw.print(", non-svc at ");
10661                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10662                    pw.println("):");
10663            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
10664            needSep = true;
10665            printedAnything = true;
10666        }
10667
10668        if (dumpAll || dumpPackage != null) {
10669            synchronized (mPidsSelfLocked) {
10670                boolean printed = false;
10671                for (int i=0; i<mPidsSelfLocked.size(); i++) {
10672                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
10673                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10674                        continue;
10675                    }
10676                    if (!printed) {
10677                        if (needSep) pw.println();
10678                        needSep = true;
10679                        pw.println("  PID mappings:");
10680                        printed = true;
10681                        printedAnything = true;
10682                    }
10683                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
10684                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
10685                }
10686            }
10687        }
10688
10689        if (mForegroundProcesses.size() > 0) {
10690            synchronized (mPidsSelfLocked) {
10691                boolean printed = false;
10692                for (int i=0; i<mForegroundProcesses.size(); i++) {
10693                    ProcessRecord r = mPidsSelfLocked.get(
10694                            mForegroundProcesses.valueAt(i).pid);
10695                    if (dumpPackage != null && (r == null
10696                            || !r.pkgList.containsKey(dumpPackage))) {
10697                        continue;
10698                    }
10699                    if (!printed) {
10700                        if (needSep) pw.println();
10701                        needSep = true;
10702                        pw.println("  Foreground Processes:");
10703                        printed = true;
10704                        printedAnything = true;
10705                    }
10706                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
10707                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
10708                }
10709            }
10710        }
10711
10712        if (mPersistentStartingProcesses.size() > 0) {
10713            if (needSep) pw.println();
10714            needSep = true;
10715            printedAnything = true;
10716            pw.println("  Persisent processes that are starting:");
10717            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
10718                    "Starting Norm", "Restarting PERS", dumpPackage);
10719        }
10720
10721        if (mRemovedProcesses.size() > 0) {
10722            if (needSep) pw.println();
10723            needSep = true;
10724            printedAnything = true;
10725            pw.println("  Processes that are being removed:");
10726            dumpProcessList(pw, this, mRemovedProcesses, "    ",
10727                    "Removed Norm", "Removed PERS", dumpPackage);
10728        }
10729
10730        if (mProcessesOnHold.size() > 0) {
10731            if (needSep) pw.println();
10732            needSep = true;
10733            printedAnything = true;
10734            pw.println("  Processes that are on old until the system is ready:");
10735            dumpProcessList(pw, this, mProcessesOnHold, "    ",
10736                    "OnHold Norm", "OnHold PERS", dumpPackage);
10737        }
10738
10739        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
10740
10741        if (mProcessCrashTimes.getMap().size() > 0) {
10742            boolean printed = false;
10743            long now = SystemClock.uptimeMillis();
10744            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
10745            final int NP = pmap.size();
10746            for (int ip=0; ip<NP; ip++) {
10747                String pname = pmap.keyAt(ip);
10748                SparseArray<Long> uids = pmap.valueAt(ip);
10749                final int N = uids.size();
10750                for (int i=0; i<N; i++) {
10751                    int puid = uids.keyAt(i);
10752                    ProcessRecord r = mProcessNames.get(pname, puid);
10753                    if (dumpPackage != null && (r == null
10754                            || !r.pkgList.containsKey(dumpPackage))) {
10755                        continue;
10756                    }
10757                    if (!printed) {
10758                        if (needSep) pw.println();
10759                        needSep = true;
10760                        pw.println("  Time since processes crashed:");
10761                        printed = true;
10762                        printedAnything = true;
10763                    }
10764                    pw.print("    Process "); pw.print(pname);
10765                            pw.print(" uid "); pw.print(puid);
10766                            pw.print(": last crashed ");
10767                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
10768                            pw.println(" ago");
10769                }
10770            }
10771        }
10772
10773        if (mBadProcesses.getMap().size() > 0) {
10774            boolean printed = false;
10775            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
10776            final int NP = pmap.size();
10777            for (int ip=0; ip<NP; ip++) {
10778                String pname = pmap.keyAt(ip);
10779                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
10780                final int N = uids.size();
10781                for (int i=0; i<N; i++) {
10782                    int puid = uids.keyAt(i);
10783                    ProcessRecord r = mProcessNames.get(pname, puid);
10784                    if (dumpPackage != null && (r == null
10785                            || !r.pkgList.containsKey(dumpPackage))) {
10786                        continue;
10787                    }
10788                    if (!printed) {
10789                        if (needSep) pw.println();
10790                        needSep = true;
10791                        pw.println("  Bad processes:");
10792                        printedAnything = true;
10793                    }
10794                    BadProcessInfo info = uids.valueAt(i);
10795                    pw.print("    Bad process "); pw.print(pname);
10796                            pw.print(" uid "); pw.print(puid);
10797                            pw.print(": crashed at time "); pw.println(info.time);
10798                    if (info.shortMsg != null) {
10799                        pw.print("      Short msg: "); pw.println(info.shortMsg);
10800                    }
10801                    if (info.longMsg != null) {
10802                        pw.print("      Long msg: "); pw.println(info.longMsg);
10803                    }
10804                    if (info.stack != null) {
10805                        pw.println("      Stack:");
10806                        int lastPos = 0;
10807                        for (int pos=0; pos<info.stack.length(); pos++) {
10808                            if (info.stack.charAt(pos) == '\n') {
10809                                pw.print("        ");
10810                                pw.write(info.stack, lastPos, pos-lastPos);
10811                                pw.println();
10812                                lastPos = pos+1;
10813                            }
10814                        }
10815                        if (lastPos < info.stack.length()) {
10816                            pw.print("        ");
10817                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
10818                            pw.println();
10819                        }
10820                    }
10821                }
10822            }
10823        }
10824
10825        if (dumpPackage == null) {
10826            pw.println();
10827            needSep = false;
10828            pw.println("  mStartedUsers:");
10829            for (int i=0; i<mStartedUsers.size(); i++) {
10830                UserStartedState uss = mStartedUsers.valueAt(i);
10831                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
10832                        pw.print(": "); uss.dump("", pw);
10833            }
10834            pw.print("  mStartedUserArray: [");
10835            for (int i=0; i<mStartedUserArray.length; i++) {
10836                if (i > 0) pw.print(", ");
10837                pw.print(mStartedUserArray[i]);
10838            }
10839            pw.println("]");
10840            pw.print("  mUserLru: [");
10841            for (int i=0; i<mUserLru.size(); i++) {
10842                if (i > 0) pw.print(", ");
10843                pw.print(mUserLru.get(i));
10844            }
10845            pw.println("]");
10846            if (dumpAll) {
10847                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
10848            }
10849        }
10850        if (mHomeProcess != null && (dumpPackage == null
10851                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
10852            if (needSep) {
10853                pw.println();
10854                needSep = false;
10855            }
10856            pw.println("  mHomeProcess: " + mHomeProcess);
10857        }
10858        if (mPreviousProcess != null && (dumpPackage == null
10859                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
10860            if (needSep) {
10861                pw.println();
10862                needSep = false;
10863            }
10864            pw.println("  mPreviousProcess: " + mPreviousProcess);
10865        }
10866        if (dumpAll) {
10867            StringBuilder sb = new StringBuilder(128);
10868            sb.append("  mPreviousProcessVisibleTime: ");
10869            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
10870            pw.println(sb);
10871        }
10872        if (mHeavyWeightProcess != null && (dumpPackage == null
10873                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
10874            if (needSep) {
10875                pw.println();
10876                needSep = false;
10877            }
10878            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
10879        }
10880        if (dumpPackage == null) {
10881            pw.println("  mConfiguration: " + mConfiguration);
10882        }
10883        if (dumpAll) {
10884            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
10885            if (mCompatModePackages.getPackages().size() > 0) {
10886                boolean printed = false;
10887                for (Map.Entry<String, Integer> entry
10888                        : mCompatModePackages.getPackages().entrySet()) {
10889                    String pkg = entry.getKey();
10890                    int mode = entry.getValue();
10891                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
10892                        continue;
10893                    }
10894                    if (!printed) {
10895                        pw.println("  mScreenCompatPackages:");
10896                        printed = true;
10897                    }
10898                    pw.print("    "); pw.print(pkg); pw.print(": ");
10899                            pw.print(mode); pw.println();
10900                }
10901            }
10902        }
10903        if (dumpPackage == null) {
10904            if (mSleeping || mWentToSleep || mLockScreenShown) {
10905                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
10906                        + " mLockScreenShown " + mLockScreenShown);
10907            }
10908            if (mShuttingDown) {
10909                pw.println("  mShuttingDown=" + mShuttingDown);
10910            }
10911        }
10912        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
10913                || mOrigWaitForDebugger) {
10914            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
10915                    || dumpPackage.equals(mOrigDebugApp)) {
10916                if (needSep) {
10917                    pw.println();
10918                    needSep = false;
10919                }
10920                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
10921                        + " mDebugTransient=" + mDebugTransient
10922                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
10923            }
10924        }
10925        if (mOpenGlTraceApp != null) {
10926            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
10927                if (needSep) {
10928                    pw.println();
10929                    needSep = false;
10930                }
10931                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
10932            }
10933        }
10934        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
10935                || mProfileFd != null) {
10936            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
10937                if (needSep) {
10938                    pw.println();
10939                    needSep = false;
10940                }
10941                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
10942                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
10943                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
10944                        + mAutoStopProfiler);
10945            }
10946        }
10947        if (dumpPackage == null) {
10948            if (mAlwaysFinishActivities || mController != null) {
10949                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
10950                        + " mController=" + mController);
10951            }
10952            if (dumpAll) {
10953                pw.println("  Total persistent processes: " + numPers);
10954                pw.println("  mStartRunning=" + mStartRunning
10955                        + " mProcessesReady=" + mProcessesReady
10956                        + " mSystemReady=" + mSystemReady);
10957                pw.println("  mBooting=" + mBooting
10958                        + " mBooted=" + mBooted
10959                        + " mFactoryTest=" + mFactoryTest);
10960                pw.print("  mLastPowerCheckRealtime=");
10961                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
10962                        pw.println("");
10963                pw.print("  mLastPowerCheckUptime=");
10964                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
10965                        pw.println("");
10966                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
10967                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
10968                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
10969                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
10970                        + " (" + mLruProcesses.size() + " total)"
10971                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
10972                        + " mNumServiceProcs=" + mNumServiceProcs
10973                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
10974                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
10975                        + " mLastMemoryLevel" + mLastMemoryLevel
10976                        + " mLastNumProcesses" + mLastNumProcesses);
10977                long now = SystemClock.uptimeMillis();
10978                pw.print("  mLastIdleTime=");
10979                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
10980                        pw.print(" mLowRamSinceLastIdle=");
10981                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
10982                        pw.println();
10983            }
10984        }
10985
10986        if (!printedAnything) {
10987            pw.println("  (nothing)");
10988        }
10989    }
10990
10991    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
10992            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
10993        if (mProcessesToGc.size() > 0) {
10994            boolean printed = false;
10995            long now = SystemClock.uptimeMillis();
10996            for (int i=0; i<mProcessesToGc.size(); i++) {
10997                ProcessRecord proc = mProcessesToGc.get(i);
10998                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
10999                    continue;
11000                }
11001                if (!printed) {
11002                    if (needSep) pw.println();
11003                    needSep = true;
11004                    pw.println("  Processes that are waiting to GC:");
11005                    printed = true;
11006                }
11007                pw.print("    Process "); pw.println(proc);
11008                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11009                        pw.print(", last gced=");
11010                        pw.print(now-proc.lastRequestedGc);
11011                        pw.print(" ms ago, last lowMem=");
11012                        pw.print(now-proc.lastLowMemory);
11013                        pw.println(" ms ago");
11014
11015            }
11016        }
11017        return needSep;
11018    }
11019
11020    void printOomLevel(PrintWriter pw, String name, int adj) {
11021        pw.print("    ");
11022        if (adj >= 0) {
11023            pw.print(' ');
11024            if (adj < 10) pw.print(' ');
11025        } else {
11026            if (adj > -10) pw.print(' ');
11027        }
11028        pw.print(adj);
11029        pw.print(": ");
11030        pw.print(name);
11031        pw.print(" (");
11032        pw.print(mProcessList.getMemLevel(adj)/1024);
11033        pw.println(" kB)");
11034    }
11035
11036    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11037            int opti, boolean dumpAll) {
11038        boolean needSep = false;
11039
11040        if (mLruProcesses.size() > 0) {
11041            if (needSep) pw.println();
11042            needSep = true;
11043            pw.println("  OOM levels:");
11044            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11045            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11046            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11047            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11048            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11049            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11050            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11051            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11052            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11053            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11054            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11055            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11056            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11057
11058            if (needSep) pw.println();
11059            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11060                    pw.print(" total, non-act at ");
11061                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11062                    pw.print(", non-svc at ");
11063                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11064                    pw.println("):");
11065            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11066            needSep = true;
11067        }
11068
11069        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11070
11071        pw.println();
11072        pw.println("  mHomeProcess: " + mHomeProcess);
11073        pw.println("  mPreviousProcess: " + mPreviousProcess);
11074        if (mHeavyWeightProcess != null) {
11075            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11076        }
11077
11078        return true;
11079    }
11080
11081    /**
11082     * There are three ways to call this:
11083     *  - no provider specified: dump all the providers
11084     *  - a flattened component name that matched an existing provider was specified as the
11085     *    first arg: dump that one provider
11086     *  - the first arg isn't the flattened component name of an existing provider:
11087     *    dump all providers whose component contains the first arg as a substring
11088     */
11089    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11090            int opti, boolean dumpAll) {
11091        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11092    }
11093
11094    static class ItemMatcher {
11095        ArrayList<ComponentName> components;
11096        ArrayList<String> strings;
11097        ArrayList<Integer> objects;
11098        boolean all;
11099
11100        ItemMatcher() {
11101            all = true;
11102        }
11103
11104        void build(String name) {
11105            ComponentName componentName = ComponentName.unflattenFromString(name);
11106            if (componentName != null) {
11107                if (components == null) {
11108                    components = new ArrayList<ComponentName>();
11109                }
11110                components.add(componentName);
11111                all = false;
11112            } else {
11113                int objectId = 0;
11114                // Not a '/' separated full component name; maybe an object ID?
11115                try {
11116                    objectId = Integer.parseInt(name, 16);
11117                    if (objects == null) {
11118                        objects = new ArrayList<Integer>();
11119                    }
11120                    objects.add(objectId);
11121                    all = false;
11122                } catch (RuntimeException e) {
11123                    // Not an integer; just do string match.
11124                    if (strings == null) {
11125                        strings = new ArrayList<String>();
11126                    }
11127                    strings.add(name);
11128                    all = false;
11129                }
11130            }
11131        }
11132
11133        int build(String[] args, int opti) {
11134            for (; opti<args.length; opti++) {
11135                String name = args[opti];
11136                if ("--".equals(name)) {
11137                    return opti+1;
11138                }
11139                build(name);
11140            }
11141            return opti;
11142        }
11143
11144        boolean match(Object object, ComponentName comp) {
11145            if (all) {
11146                return true;
11147            }
11148            if (components != null) {
11149                for (int i=0; i<components.size(); i++) {
11150                    if (components.get(i).equals(comp)) {
11151                        return true;
11152                    }
11153                }
11154            }
11155            if (objects != null) {
11156                for (int i=0; i<objects.size(); i++) {
11157                    if (System.identityHashCode(object) == objects.get(i)) {
11158                        return true;
11159                    }
11160                }
11161            }
11162            if (strings != null) {
11163                String flat = comp.flattenToString();
11164                for (int i=0; i<strings.size(); i++) {
11165                    if (flat.contains(strings.get(i))) {
11166                        return true;
11167                    }
11168                }
11169            }
11170            return false;
11171        }
11172    }
11173
11174    /**
11175     * There are three things that cmd can be:
11176     *  - a flattened component name that matches an existing activity
11177     *  - the cmd arg isn't the flattened component name of an existing activity:
11178     *    dump all activity whose component contains the cmd as a substring
11179     *  - A hex number of the ActivityRecord object instance.
11180     */
11181    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11182            int opti, boolean dumpAll) {
11183        ArrayList<ActivityRecord> activities;
11184
11185        synchronized (this) {
11186            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11187        }
11188
11189        if (activities.size() <= 0) {
11190            return false;
11191        }
11192
11193        String[] newArgs = new String[args.length - opti];
11194        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11195
11196        TaskRecord lastTask = null;
11197        boolean needSep = false;
11198        for (int i=activities.size()-1; i>=0; i--) {
11199            ActivityRecord r = activities.get(i);
11200            if (needSep) {
11201                pw.println();
11202            }
11203            needSep = true;
11204            synchronized (this) {
11205                if (lastTask != r.task) {
11206                    lastTask = r.task;
11207                    pw.print("TASK "); pw.print(lastTask.affinity);
11208                            pw.print(" id="); pw.println(lastTask.taskId);
11209                    if (dumpAll) {
11210                        lastTask.dump(pw, "  ");
11211                    }
11212                }
11213            }
11214            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11215        }
11216        return true;
11217    }
11218
11219    /**
11220     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11221     * there is a thread associated with the activity.
11222     */
11223    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11224            final ActivityRecord r, String[] args, boolean dumpAll) {
11225        String innerPrefix = prefix + "  ";
11226        synchronized (this) {
11227            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11228                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11229                    pw.print(" pid=");
11230                    if (r.app != null) pw.println(r.app.pid);
11231                    else pw.println("(not running)");
11232            if (dumpAll) {
11233                r.dump(pw, innerPrefix);
11234            }
11235        }
11236        if (r.app != null && r.app.thread != null) {
11237            // flush anything that is already in the PrintWriter since the thread is going
11238            // to write to the file descriptor directly
11239            pw.flush();
11240            try {
11241                TransferPipe tp = new TransferPipe();
11242                try {
11243                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11244                            r.appToken, innerPrefix, args);
11245                    tp.go(fd);
11246                } finally {
11247                    tp.kill();
11248                }
11249            } catch (IOException e) {
11250                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11251            } catch (RemoteException e) {
11252                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11253            }
11254        }
11255    }
11256
11257    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11258            int opti, boolean dumpAll, String dumpPackage) {
11259        boolean needSep = false;
11260        boolean onlyHistory = false;
11261        boolean printedAnything = false;
11262
11263        if ("history".equals(dumpPackage)) {
11264            if (opti < args.length && "-s".equals(args[opti])) {
11265                dumpAll = false;
11266            }
11267            onlyHistory = true;
11268            dumpPackage = null;
11269        }
11270
11271        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11272        if (!onlyHistory && dumpAll) {
11273            if (mRegisteredReceivers.size() > 0) {
11274                boolean printed = false;
11275                Iterator it = mRegisteredReceivers.values().iterator();
11276                while (it.hasNext()) {
11277                    ReceiverList r = (ReceiverList)it.next();
11278                    if (dumpPackage != null && (r.app == null ||
11279                            !dumpPackage.equals(r.app.info.packageName))) {
11280                        continue;
11281                    }
11282                    if (!printed) {
11283                        pw.println("  Registered Receivers:");
11284                        needSep = true;
11285                        printed = true;
11286                        printedAnything = true;
11287                    }
11288                    pw.print("  * "); pw.println(r);
11289                    r.dump(pw, "    ");
11290                }
11291            }
11292
11293            if (mReceiverResolver.dump(pw, needSep ?
11294                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11295                    "    ", dumpPackage, false)) {
11296                needSep = true;
11297                printedAnything = true;
11298            }
11299        }
11300
11301        for (BroadcastQueue q : mBroadcastQueues) {
11302            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11303            printedAnything |= needSep;
11304        }
11305
11306        needSep = true;
11307
11308        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11309            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11310                if (needSep) {
11311                    pw.println();
11312                }
11313                needSep = true;
11314                printedAnything = true;
11315                pw.print("  Sticky broadcasts for user ");
11316                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11317                StringBuilder sb = new StringBuilder(128);
11318                for (Map.Entry<String, ArrayList<Intent>> ent
11319                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11320                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11321                    if (dumpAll) {
11322                        pw.println(":");
11323                        ArrayList<Intent> intents = ent.getValue();
11324                        final int N = intents.size();
11325                        for (int i=0; i<N; i++) {
11326                            sb.setLength(0);
11327                            sb.append("    Intent: ");
11328                            intents.get(i).toShortString(sb, false, true, false, false);
11329                            pw.println(sb.toString());
11330                            Bundle bundle = intents.get(i).getExtras();
11331                            if (bundle != null) {
11332                                pw.print("      ");
11333                                pw.println(bundle.toString());
11334                            }
11335                        }
11336                    } else {
11337                        pw.println("");
11338                    }
11339                }
11340            }
11341        }
11342
11343        if (!onlyHistory && dumpAll) {
11344            pw.println();
11345            for (BroadcastQueue queue : mBroadcastQueues) {
11346                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11347                        + queue.mBroadcastsScheduled);
11348            }
11349            pw.println("  mHandler:");
11350            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11351            needSep = true;
11352            printedAnything = true;
11353        }
11354
11355        if (!printedAnything) {
11356            pw.println("  (nothing)");
11357        }
11358    }
11359
11360    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11361            int opti, boolean dumpAll, String dumpPackage) {
11362        boolean needSep;
11363        boolean printedAnything = false;
11364
11365        ItemMatcher matcher = new ItemMatcher();
11366        matcher.build(args, opti);
11367
11368        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11369
11370        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11371        printedAnything |= needSep;
11372
11373        if (mLaunchingProviders.size() > 0) {
11374            boolean printed = false;
11375            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11376                ContentProviderRecord r = mLaunchingProviders.get(i);
11377                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11378                    continue;
11379                }
11380                if (!printed) {
11381                    if (needSep) pw.println();
11382                    needSep = true;
11383                    pw.println("  Launching content providers:");
11384                    printed = true;
11385                    printedAnything = true;
11386                }
11387                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11388                        pw.println(r);
11389            }
11390        }
11391
11392        if (mGrantedUriPermissions.size() > 0) {
11393            boolean printed = false;
11394            int dumpUid = -2;
11395            if (dumpPackage != null) {
11396                try {
11397                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11398                } catch (NameNotFoundException e) {
11399                    dumpUid = -1;
11400                }
11401            }
11402            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11403                int uid = mGrantedUriPermissions.keyAt(i);
11404                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11405                    continue;
11406                }
11407                ArrayMap<Uri, UriPermission> perms
11408                        = mGrantedUriPermissions.valueAt(i);
11409                if (!printed) {
11410                    if (needSep) pw.println();
11411                    needSep = true;
11412                    pw.println("  Granted Uri Permissions:");
11413                    printed = true;
11414                    printedAnything = true;
11415                }
11416                pw.print("  * UID "); pw.print(uid);
11417                        pw.println(" holds:");
11418                for (UriPermission perm : perms.values()) {
11419                    pw.print("    "); pw.println(perm);
11420                    if (dumpAll) {
11421                        perm.dump(pw, "      ");
11422                    }
11423                }
11424            }
11425        }
11426
11427        if (!printedAnything) {
11428            pw.println("  (nothing)");
11429        }
11430    }
11431
11432    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11433            int opti, boolean dumpAll, String dumpPackage) {
11434        boolean printed = false;
11435
11436        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11437
11438        if (mIntentSenderRecords.size() > 0) {
11439            Iterator<WeakReference<PendingIntentRecord>> it
11440                    = mIntentSenderRecords.values().iterator();
11441            while (it.hasNext()) {
11442                WeakReference<PendingIntentRecord> ref = it.next();
11443                PendingIntentRecord rec = ref != null ? ref.get(): null;
11444                if (dumpPackage != null && (rec == null
11445                        || !dumpPackage.equals(rec.key.packageName))) {
11446                    continue;
11447                }
11448                printed = true;
11449                if (rec != null) {
11450                    pw.print("  * "); pw.println(rec);
11451                    if (dumpAll) {
11452                        rec.dump(pw, "    ");
11453                    }
11454                } else {
11455                    pw.print("  * "); pw.println(ref);
11456                }
11457            }
11458        }
11459
11460        if (!printed) {
11461            pw.println("  (nothing)");
11462        }
11463    }
11464
11465    private static final int dumpProcessList(PrintWriter pw,
11466            ActivityManagerService service, List list,
11467            String prefix, String normalLabel, String persistentLabel,
11468            String dumpPackage) {
11469        int numPers = 0;
11470        final int N = list.size()-1;
11471        for (int i=N; i>=0; i--) {
11472            ProcessRecord r = (ProcessRecord)list.get(i);
11473            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11474                continue;
11475            }
11476            pw.println(String.format("%s%s #%2d: %s",
11477                    prefix, (r.persistent ? persistentLabel : normalLabel),
11478                    i, r.toString()));
11479            if (r.persistent) {
11480                numPers++;
11481            }
11482        }
11483        return numPers;
11484    }
11485
11486    private static final boolean dumpProcessOomList(PrintWriter pw,
11487            ActivityManagerService service, List<ProcessRecord> origList,
11488            String prefix, String normalLabel, String persistentLabel,
11489            boolean inclDetails, String dumpPackage) {
11490
11491        ArrayList<Pair<ProcessRecord, Integer>> list
11492                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11493        for (int i=0; i<origList.size(); i++) {
11494            ProcessRecord r = origList.get(i);
11495            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11496                continue;
11497            }
11498            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11499        }
11500
11501        if (list.size() <= 0) {
11502            return false;
11503        }
11504
11505        Comparator<Pair<ProcessRecord, Integer>> comparator
11506                = new Comparator<Pair<ProcessRecord, Integer>>() {
11507            @Override
11508            public int compare(Pair<ProcessRecord, Integer> object1,
11509                    Pair<ProcessRecord, Integer> object2) {
11510                if (object1.first.setAdj != object2.first.setAdj) {
11511                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11512                }
11513                if (object1.second.intValue() != object2.second.intValue()) {
11514                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11515                }
11516                return 0;
11517            }
11518        };
11519
11520        Collections.sort(list, comparator);
11521
11522        final long curRealtime = SystemClock.elapsedRealtime();
11523        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11524        final long curUptime = SystemClock.uptimeMillis();
11525        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11526
11527        for (int i=list.size()-1; i>=0; i--) {
11528            ProcessRecord r = list.get(i).first;
11529            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11530            char schedGroup;
11531            switch (r.setSchedGroup) {
11532                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11533                    schedGroup = 'B';
11534                    break;
11535                case Process.THREAD_GROUP_DEFAULT:
11536                    schedGroup = 'F';
11537                    break;
11538                default:
11539                    schedGroup = '?';
11540                    break;
11541            }
11542            char foreground;
11543            if (r.foregroundActivities) {
11544                foreground = 'A';
11545            } else if (r.foregroundServices) {
11546                foreground = 'S';
11547            } else {
11548                foreground = ' ';
11549            }
11550            String procState = ProcessList.makeProcStateString(r.curProcState);
11551            pw.print(prefix);
11552            pw.print(r.persistent ? persistentLabel : normalLabel);
11553            pw.print(" #");
11554            int num = (origList.size()-1)-list.get(i).second;
11555            if (num < 10) pw.print(' ');
11556            pw.print(num);
11557            pw.print(": ");
11558            pw.print(oomAdj);
11559            pw.print(' ');
11560            pw.print(schedGroup);
11561            pw.print('/');
11562            pw.print(foreground);
11563            pw.print('/');
11564            pw.print(procState);
11565            pw.print(" trm:");
11566            if (r.trimMemoryLevel < 10) pw.print(' ');
11567            pw.print(r.trimMemoryLevel);
11568            pw.print(' ');
11569            pw.print(r.toShortString());
11570            pw.print(" (");
11571            pw.print(r.adjType);
11572            pw.println(')');
11573            if (r.adjSource != null || r.adjTarget != null) {
11574                pw.print(prefix);
11575                pw.print("    ");
11576                if (r.adjTarget instanceof ComponentName) {
11577                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11578                } else if (r.adjTarget != null) {
11579                    pw.print(r.adjTarget.toString());
11580                } else {
11581                    pw.print("{null}");
11582                }
11583                pw.print("<=");
11584                if (r.adjSource instanceof ProcessRecord) {
11585                    pw.print("Proc{");
11586                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11587                    pw.println("}");
11588                } else if (r.adjSource != null) {
11589                    pw.println(r.adjSource.toString());
11590                } else {
11591                    pw.println("{null}");
11592                }
11593            }
11594            if (inclDetails) {
11595                pw.print(prefix);
11596                pw.print("    ");
11597                pw.print("oom: max="); pw.print(r.maxAdj);
11598                pw.print(" curRaw="); pw.print(r.curRawAdj);
11599                pw.print(" setRaw="); pw.print(r.setRawAdj);
11600                pw.print(" cur="); pw.print(r.curAdj);
11601                pw.print(" set="); pw.println(r.setAdj);
11602                pw.print(prefix);
11603                pw.print("    ");
11604                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
11605                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
11606                pw.print(" lastPss="); pw.print(r.lastPss);
11607                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
11608                pw.print(prefix);
11609                pw.print("    ");
11610                pw.print("keeping="); pw.print(r.keeping);
11611                pw.print(" cached="); pw.print(r.cached);
11612                pw.print(" empty="); pw.print(r.empty);
11613                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
11614
11615                if (!r.keeping) {
11616                    if (r.lastWakeTime != 0) {
11617                        long wtime;
11618                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
11619                        synchronized (stats) {
11620                            wtime = stats.getProcessWakeTime(r.info.uid,
11621                                    r.pid, curRealtime);
11622                        }
11623                        long timeUsed = wtime - r.lastWakeTime;
11624                        pw.print(prefix);
11625                        pw.print("    ");
11626                        pw.print("keep awake over ");
11627                        TimeUtils.formatDuration(realtimeSince, pw);
11628                        pw.print(" used ");
11629                        TimeUtils.formatDuration(timeUsed, pw);
11630                        pw.print(" (");
11631                        pw.print((timeUsed*100)/realtimeSince);
11632                        pw.println("%)");
11633                    }
11634                    if (r.lastCpuTime != 0) {
11635                        long timeUsed = r.curCpuTime - r.lastCpuTime;
11636                        pw.print(prefix);
11637                        pw.print("    ");
11638                        pw.print("run cpu over ");
11639                        TimeUtils.formatDuration(uptimeSince, pw);
11640                        pw.print(" used ");
11641                        TimeUtils.formatDuration(timeUsed, pw);
11642                        pw.print(" (");
11643                        pw.print((timeUsed*100)/uptimeSince);
11644                        pw.println("%)");
11645                    }
11646                }
11647            }
11648        }
11649        return true;
11650    }
11651
11652    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
11653        ArrayList<ProcessRecord> procs;
11654        synchronized (this) {
11655            if (args != null && args.length > start
11656                    && args[start].charAt(0) != '-') {
11657                procs = new ArrayList<ProcessRecord>();
11658                int pid = -1;
11659                try {
11660                    pid = Integer.parseInt(args[start]);
11661                } catch (NumberFormatException e) {
11662                }
11663                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11664                    ProcessRecord proc = mLruProcesses.get(i);
11665                    if (proc.pid == pid) {
11666                        procs.add(proc);
11667                    } else if (proc.processName.equals(args[start])) {
11668                        procs.add(proc);
11669                    }
11670                }
11671                if (procs.size() <= 0) {
11672                    return null;
11673                }
11674            } else {
11675                procs = new ArrayList<ProcessRecord>(mLruProcesses);
11676            }
11677        }
11678        return procs;
11679    }
11680
11681    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
11682            PrintWriter pw, String[] args) {
11683        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11684        if (procs == null) {
11685            pw.println("No process found for: " + args[0]);
11686            return;
11687        }
11688
11689        long uptime = SystemClock.uptimeMillis();
11690        long realtime = SystemClock.elapsedRealtime();
11691        pw.println("Applications Graphics Acceleration Info:");
11692        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11693
11694        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11695            ProcessRecord r = procs.get(i);
11696            if (r.thread != null) {
11697                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
11698                pw.flush();
11699                try {
11700                    TransferPipe tp = new TransferPipe();
11701                    try {
11702                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
11703                        tp.go(fd);
11704                    } finally {
11705                        tp.kill();
11706                    }
11707                } catch (IOException e) {
11708                    pw.println("Failure while dumping the app: " + r);
11709                    pw.flush();
11710                } catch (RemoteException e) {
11711                    pw.println("Got a RemoteException while dumping the app " + r);
11712                    pw.flush();
11713                }
11714            }
11715        }
11716    }
11717
11718    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
11719        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11720        if (procs == null) {
11721            pw.println("No process found for: " + args[0]);
11722            return;
11723        }
11724
11725        pw.println("Applications Database Info:");
11726
11727        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11728            ProcessRecord r = procs.get(i);
11729            if (r.thread != null) {
11730                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
11731                pw.flush();
11732                try {
11733                    TransferPipe tp = new TransferPipe();
11734                    try {
11735                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
11736                        tp.go(fd);
11737                    } finally {
11738                        tp.kill();
11739                    }
11740                } catch (IOException e) {
11741                    pw.println("Failure while dumping the app: " + r);
11742                    pw.flush();
11743                } catch (RemoteException e) {
11744                    pw.println("Got a RemoteException while dumping the app " + r);
11745                    pw.flush();
11746                }
11747            }
11748        }
11749    }
11750
11751    final static class MemItem {
11752        final boolean isProc;
11753        final String label;
11754        final String shortLabel;
11755        final long pss;
11756        final int id;
11757        final boolean hasActivities;
11758        ArrayList<MemItem> subitems;
11759
11760        public MemItem(String _label, String _shortLabel, long _pss, int _id,
11761                boolean _hasActivities) {
11762            isProc = true;
11763            label = _label;
11764            shortLabel = _shortLabel;
11765            pss = _pss;
11766            id = _id;
11767            hasActivities = _hasActivities;
11768        }
11769
11770        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
11771            isProc = false;
11772            label = _label;
11773            shortLabel = _shortLabel;
11774            pss = _pss;
11775            id = _id;
11776            hasActivities = false;
11777        }
11778    }
11779
11780    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
11781            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
11782        if (sort && !isCompact) {
11783            Collections.sort(items, new Comparator<MemItem>() {
11784                @Override
11785                public int compare(MemItem lhs, MemItem rhs) {
11786                    if (lhs.pss < rhs.pss) {
11787                        return 1;
11788                    } else if (lhs.pss > rhs.pss) {
11789                        return -1;
11790                    }
11791                    return 0;
11792                }
11793            });
11794        }
11795
11796        for (int i=0; i<items.size(); i++) {
11797            MemItem mi = items.get(i);
11798            if (!isCompact) {
11799                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
11800            } else if (mi.isProc) {
11801                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
11802                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
11803                pw.println(mi.hasActivities ? ",a" : ",e");
11804            } else {
11805                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
11806                pw.println(mi.pss);
11807            }
11808            if (mi.subitems != null) {
11809                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
11810                        true, isCompact);
11811            }
11812        }
11813    }
11814
11815    // These are in KB.
11816    static final long[] DUMP_MEM_BUCKETS = new long[] {
11817        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
11818        120*1024, 160*1024, 200*1024,
11819        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
11820        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
11821    };
11822
11823    static final void appendMemBucket(StringBuilder out, long memKB, String label,
11824            boolean stackLike) {
11825        int start = label.lastIndexOf('.');
11826        if (start >= 0) start++;
11827        else start = 0;
11828        int end = label.length();
11829        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
11830            if (DUMP_MEM_BUCKETS[i] >= memKB) {
11831                long bucket = DUMP_MEM_BUCKETS[i]/1024;
11832                out.append(bucket);
11833                out.append(stackLike ? "MB." : "MB ");
11834                out.append(label, start, end);
11835                return;
11836            }
11837        }
11838        out.append(memKB/1024);
11839        out.append(stackLike ? "MB." : "MB ");
11840        out.append(label, start, end);
11841    }
11842
11843    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
11844            ProcessList.NATIVE_ADJ,
11845            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
11846            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
11847            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
11848            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
11849            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
11850    };
11851    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
11852            "Native",
11853            "System", "Persistent", "Foreground",
11854            "Visible", "Perceptible",
11855            "Heavy Weight", "Backup",
11856            "A Services", "Home",
11857            "Previous", "B Services", "Cached"
11858    };
11859    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
11860            "native",
11861            "sys", "pers", "fore",
11862            "vis", "percept",
11863            "heavy", "backup",
11864            "servicea", "home",
11865            "prev", "serviceb", "cached"
11866    };
11867
11868    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
11869            long realtime, boolean isCheckinRequest, boolean isCompact) {
11870        if (isCheckinRequest || isCompact) {
11871            // short checkin version
11872            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
11873        } else {
11874            pw.println("Applications Memory Usage (kB):");
11875            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11876        }
11877    }
11878
11879    final void dumpApplicationMemoryUsage(FileDescriptor fd,
11880            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
11881        boolean dumpDetails = false;
11882        boolean dumpFullDetails = false;
11883        boolean dumpDalvik = false;
11884        boolean oomOnly = false;
11885        boolean isCompact = false;
11886        boolean localOnly = false;
11887
11888        int opti = 0;
11889        while (opti < args.length) {
11890            String opt = args[opti];
11891            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11892                break;
11893            }
11894            opti++;
11895            if ("-a".equals(opt)) {
11896                dumpDetails = true;
11897                dumpFullDetails = true;
11898                dumpDalvik = true;
11899            } else if ("-d".equals(opt)) {
11900                dumpDalvik = true;
11901            } else if ("-c".equals(opt)) {
11902                isCompact = true;
11903            } else if ("--oom".equals(opt)) {
11904                oomOnly = true;
11905            } else if ("--local".equals(opt)) {
11906                localOnly = true;
11907            } else if ("-h".equals(opt)) {
11908                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
11909                pw.println("  -a: include all available information for each process.");
11910                pw.println("  -d: include dalvik details when dumping process details.");
11911                pw.println("  -c: dump in a compact machine-parseable representation.");
11912                pw.println("  --oom: only show processes organized by oom adj.");
11913                pw.println("  --local: only collect details locally, don't call process.");
11914                pw.println("If [process] is specified it can be the name or ");
11915                pw.println("pid of a specific process to dump.");
11916                return;
11917            } else {
11918                pw.println("Unknown argument: " + opt + "; use -h for help");
11919            }
11920        }
11921
11922        final boolean isCheckinRequest = scanArgs(args, "--checkin");
11923        long uptime = SystemClock.uptimeMillis();
11924        long realtime = SystemClock.elapsedRealtime();
11925        final long[] tmpLong = new long[1];
11926
11927        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
11928        if (procs == null) {
11929            // No Java processes.  Maybe they want to print a native process.
11930            if (args != null && args.length > opti
11931                    && args[opti].charAt(0) != '-') {
11932                ArrayList<ProcessCpuTracker.Stats> nativeProcs
11933                        = new ArrayList<ProcessCpuTracker.Stats>();
11934                updateCpuStatsNow();
11935                int findPid = -1;
11936                try {
11937                    findPid = Integer.parseInt(args[opti]);
11938                } catch (NumberFormatException e) {
11939                }
11940                synchronized (mProcessCpuThread) {
11941                    final int N = mProcessCpuTracker.countStats();
11942                    for (int i=0; i<N; i++) {
11943                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
11944                        if (st.pid == findPid || (st.baseName != null
11945                                && st.baseName.equals(args[opti]))) {
11946                            nativeProcs.add(st);
11947                        }
11948                    }
11949                }
11950                if (nativeProcs.size() > 0) {
11951                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
11952                            isCompact);
11953                    Debug.MemoryInfo mi = null;
11954                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
11955                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
11956                        final int pid = r.pid;
11957                        if (!isCheckinRequest && dumpDetails) {
11958                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
11959                        }
11960                        if (mi == null) {
11961                            mi = new Debug.MemoryInfo();
11962                        }
11963                        if (dumpDetails || (!brief && !oomOnly)) {
11964                            Debug.getMemoryInfo(pid, mi);
11965                        } else {
11966                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
11967                            mi.dalvikPrivateDirty = (int)tmpLong[0];
11968                        }
11969                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
11970                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
11971                        if (isCheckinRequest) {
11972                            pw.println();
11973                        }
11974                    }
11975                    return;
11976                }
11977            }
11978            pw.println("No process found for: " + args[opti]);
11979            return;
11980        }
11981
11982        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
11983            dumpDetails = true;
11984        }
11985
11986        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
11987
11988        String[] innerArgs = new String[args.length-opti];
11989        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
11990
11991        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
11992        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
11993        long nativePss=0, dalvikPss=0, otherPss=0;
11994        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
11995
11996        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
11997        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
11998                new ArrayList[DUMP_MEM_OOM_LABEL.length];
11999
12000        long totalPss = 0;
12001        long cachedPss = 0;
12002
12003        Debug.MemoryInfo mi = null;
12004        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12005            final ProcessRecord r = procs.get(i);
12006            final IApplicationThread thread;
12007            final int pid;
12008            final int oomAdj;
12009            final boolean hasActivities;
12010            synchronized (this) {
12011                thread = r.thread;
12012                pid = r.pid;
12013                oomAdj = r.getSetAdjWithServices();
12014                hasActivities = r.activities.size() > 0;
12015            }
12016            if (thread != null) {
12017                if (!isCheckinRequest && dumpDetails) {
12018                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12019                }
12020                if (mi == null) {
12021                    mi = new Debug.MemoryInfo();
12022                }
12023                if (dumpDetails || (!brief && !oomOnly)) {
12024                    Debug.getMemoryInfo(pid, mi);
12025                } else {
12026                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12027                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12028                }
12029                if (dumpDetails) {
12030                    if (localOnly) {
12031                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12032                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12033                        if (isCheckinRequest) {
12034                            pw.println();
12035                        }
12036                    } else {
12037                        try {
12038                            pw.flush();
12039                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12040                                    dumpDalvik, innerArgs);
12041                        } catch (RemoteException e) {
12042                            if (!isCheckinRequest) {
12043                                pw.println("Got RemoteException!");
12044                                pw.flush();
12045                            }
12046                        }
12047                    }
12048                }
12049
12050                final long myTotalPss = mi.getTotalPss();
12051                final long myTotalUss = mi.getTotalUss();
12052
12053                synchronized (this) {
12054                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12055                        // Record this for posterity if the process has been stable.
12056                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12057                    }
12058                }
12059
12060                if (!isCheckinRequest && mi != null) {
12061                    totalPss += myTotalPss;
12062                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12063                            (hasActivities ? " / activities)" : ")"),
12064                            r.processName, myTotalPss, pid, hasActivities);
12065                    procMems.add(pssItem);
12066                    procMemsMap.put(pid, pssItem);
12067
12068                    nativePss += mi.nativePss;
12069                    dalvikPss += mi.dalvikPss;
12070                    otherPss += mi.otherPss;
12071                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12072                        long mem = mi.getOtherPss(j);
12073                        miscPss[j] += mem;
12074                        otherPss -= mem;
12075                    }
12076
12077                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12078                        cachedPss += myTotalPss;
12079                    }
12080
12081                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12082                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12083                                || oomIndex == (oomPss.length-1)) {
12084                            oomPss[oomIndex] += myTotalPss;
12085                            if (oomProcs[oomIndex] == null) {
12086                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12087                            }
12088                            oomProcs[oomIndex].add(pssItem);
12089                            break;
12090                        }
12091                    }
12092                }
12093            }
12094        }
12095
12096        if (!isCheckinRequest && procs.size() > 1) {
12097            // If we are showing aggregations, also look for native processes to
12098            // include so that our aggregations are more accurate.
12099            updateCpuStatsNow();
12100            synchronized (mProcessCpuThread) {
12101                final int N = mProcessCpuTracker.countStats();
12102                for (int i=0; i<N; i++) {
12103                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12104                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12105                        if (mi == null) {
12106                            mi = new Debug.MemoryInfo();
12107                        }
12108                        if (!brief && !oomOnly) {
12109                            Debug.getMemoryInfo(st.pid, mi);
12110                        } else {
12111                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12112                            mi.nativePrivateDirty = (int)tmpLong[0];
12113                        }
12114
12115                        final long myTotalPss = mi.getTotalPss();
12116                        totalPss += myTotalPss;
12117
12118                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12119                                st.name, myTotalPss, st.pid, false);
12120                        procMems.add(pssItem);
12121
12122                        nativePss += mi.nativePss;
12123                        dalvikPss += mi.dalvikPss;
12124                        otherPss += mi.otherPss;
12125                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12126                            long mem = mi.getOtherPss(j);
12127                            miscPss[j] += mem;
12128                            otherPss -= mem;
12129                        }
12130                        oomPss[0] += myTotalPss;
12131                        if (oomProcs[0] == null) {
12132                            oomProcs[0] = new ArrayList<MemItem>();
12133                        }
12134                        oomProcs[0].add(pssItem);
12135                    }
12136                }
12137            }
12138
12139            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12140
12141            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12142            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12143            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12144            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12145                String label = Debug.MemoryInfo.getOtherLabel(j);
12146                catMems.add(new MemItem(label, label, miscPss[j], j));
12147            }
12148
12149            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12150            for (int j=0; j<oomPss.length; j++) {
12151                if (oomPss[j] != 0) {
12152                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12153                            : DUMP_MEM_OOM_LABEL[j];
12154                    MemItem item = new MemItem(label, label, oomPss[j],
12155                            DUMP_MEM_OOM_ADJ[j]);
12156                    item.subitems = oomProcs[j];
12157                    oomMems.add(item);
12158                }
12159            }
12160
12161            if (!brief && !oomOnly && !isCompact) {
12162                pw.println();
12163                pw.println("Total PSS by process:");
12164                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12165                pw.println();
12166            }
12167            if (!isCompact) {
12168                pw.println("Total PSS by OOM adjustment:");
12169            }
12170            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12171            if (!brief && !oomOnly) {
12172                PrintWriter out = categoryPw != null ? categoryPw : pw;
12173                if (!isCompact) {
12174                    out.println();
12175                    out.println("Total PSS by category:");
12176                }
12177                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12178            }
12179            if (!isCompact) {
12180                pw.println();
12181            }
12182            MemInfoReader memInfo = new MemInfoReader();
12183            memInfo.readMemInfo();
12184            if (!brief) {
12185                if (!isCompact) {
12186                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12187                    pw.print(" kB (status ");
12188                    switch (mLastMemoryLevel) {
12189                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12190                            pw.println("normal)");
12191                            break;
12192                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12193                            pw.println("moderate)");
12194                            break;
12195                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12196                            pw.println("low)");
12197                            break;
12198                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12199                            pw.println("critical)");
12200                            break;
12201                        default:
12202                            pw.print(mLastMemoryLevel);
12203                            pw.println(")");
12204                            break;
12205                    }
12206                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12207                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12208                            pw.print(cachedPss); pw.print(" cached pss + ");
12209                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12210                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12211                } else {
12212                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12213                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12214                            + memInfo.getFreeSizeKb()); pw.print(",");
12215                    pw.println(totalPss - cachedPss);
12216                }
12217            }
12218            if (!isCompact) {
12219                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12220                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12221                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12222                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12223                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12224                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12225                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12226                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12227                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12228                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12229                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12230            }
12231            if (!brief) {
12232                if (memInfo.getZramTotalSizeKb() != 0) {
12233                    if (!isCompact) {
12234                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12235                                pw.print(" kB physical used for ");
12236                                pw.print(memInfo.getSwapTotalSizeKb()
12237                                        - memInfo.getSwapFreeSizeKb());
12238                                pw.print(" kB in swap (");
12239                                pw.print(memInfo.getSwapTotalSizeKb());
12240                                pw.println(" kB total swap)");
12241                    } else {
12242                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12243                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12244                                pw.println(memInfo.getSwapFreeSizeKb());
12245                    }
12246                }
12247                final int[] SINGLE_LONG_FORMAT = new int[] {
12248                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12249                };
12250                long[] longOut = new long[1];
12251                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12252                        SINGLE_LONG_FORMAT, null, longOut, null);
12253                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12254                longOut[0] = 0;
12255                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12256                        SINGLE_LONG_FORMAT, null, longOut, null);
12257                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12258                longOut[0] = 0;
12259                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12260                        SINGLE_LONG_FORMAT, null, longOut, null);
12261                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12262                longOut[0] = 0;
12263                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12264                        SINGLE_LONG_FORMAT, null, longOut, null);
12265                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12266                if (!isCompact) {
12267                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12268                        pw.print("      KSM: "); pw.print(sharing);
12269                                pw.print(" kB saved from shared ");
12270                                pw.print(shared); pw.println(" kB");
12271                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12272                                pw.print(voltile); pw.println(" kB volatile");
12273                    }
12274                    pw.print("   Tuning: ");
12275                    pw.print(ActivityManager.staticGetMemoryClass());
12276                    pw.print(" (large ");
12277                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12278                    pw.print("), oom ");
12279                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12280                    pw.print(" kB");
12281                    pw.print(", restore limit ");
12282                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12283                    pw.print(" kB");
12284                    if (ActivityManager.isLowRamDeviceStatic()) {
12285                        pw.print(" (low-ram)");
12286                    }
12287                    if (ActivityManager.isHighEndGfx()) {
12288                        pw.print(" (high-end-gfx)");
12289                    }
12290                    pw.println();
12291                } else {
12292                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12293                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12294                    pw.println(voltile);
12295                    pw.print("tuning,");
12296                    pw.print(ActivityManager.staticGetMemoryClass());
12297                    pw.print(',');
12298                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12299                    pw.print(',');
12300                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12301                    if (ActivityManager.isLowRamDeviceStatic()) {
12302                        pw.print(",low-ram");
12303                    }
12304                    if (ActivityManager.isHighEndGfx()) {
12305                        pw.print(",high-end-gfx");
12306                    }
12307                    pw.println();
12308                }
12309            }
12310        }
12311    }
12312
12313    /**
12314     * Searches array of arguments for the specified string
12315     * @param args array of argument strings
12316     * @param value value to search for
12317     * @return true if the value is contained in the array
12318     */
12319    private static boolean scanArgs(String[] args, String value) {
12320        if (args != null) {
12321            for (String arg : args) {
12322                if (value.equals(arg)) {
12323                    return true;
12324                }
12325            }
12326        }
12327        return false;
12328    }
12329
12330    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12331            ContentProviderRecord cpr, boolean always) {
12332        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12333
12334        if (!inLaunching || always) {
12335            synchronized (cpr) {
12336                cpr.launchingApp = null;
12337                cpr.notifyAll();
12338            }
12339            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12340            String names[] = cpr.info.authority.split(";");
12341            for (int j = 0; j < names.length; j++) {
12342                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12343            }
12344        }
12345
12346        for (int i=0; i<cpr.connections.size(); i++) {
12347            ContentProviderConnection conn = cpr.connections.get(i);
12348            if (conn.waiting) {
12349                // If this connection is waiting for the provider, then we don't
12350                // need to mess with its process unless we are always removing
12351                // or for some reason the provider is not currently launching.
12352                if (inLaunching && !always) {
12353                    continue;
12354                }
12355            }
12356            ProcessRecord capp = conn.client;
12357            conn.dead = true;
12358            if (conn.stableCount > 0) {
12359                if (!capp.persistent && capp.thread != null
12360                        && capp.pid != 0
12361                        && capp.pid != MY_PID) {
12362                    killUnneededProcessLocked(capp, "depends on provider "
12363                            + cpr.name.flattenToShortString()
12364                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12365                }
12366            } else if (capp.thread != null && conn.provider.provider != null) {
12367                try {
12368                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12369                } catch (RemoteException e) {
12370                }
12371                // In the protocol here, we don't expect the client to correctly
12372                // clean up this connection, we'll just remove it.
12373                cpr.connections.remove(i);
12374                conn.client.conProviders.remove(conn);
12375            }
12376        }
12377
12378        if (inLaunching && always) {
12379            mLaunchingProviders.remove(cpr);
12380        }
12381        return inLaunching;
12382    }
12383
12384    /**
12385     * Main code for cleaning up a process when it has gone away.  This is
12386     * called both as a result of the process dying, or directly when stopping
12387     * a process when running in single process mode.
12388     */
12389    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12390            boolean restarting, boolean allowRestart, int index) {
12391        if (index >= 0) {
12392            removeLruProcessLocked(app);
12393            ProcessList.remove(app.pid);
12394        }
12395
12396        mProcessesToGc.remove(app);
12397        mPendingPssProcesses.remove(app);
12398
12399        // Dismiss any open dialogs.
12400        if (app.crashDialog != null && !app.forceCrashReport) {
12401            app.crashDialog.dismiss();
12402            app.crashDialog = null;
12403        }
12404        if (app.anrDialog != null) {
12405            app.anrDialog.dismiss();
12406            app.anrDialog = null;
12407        }
12408        if (app.waitDialog != null) {
12409            app.waitDialog.dismiss();
12410            app.waitDialog = null;
12411        }
12412
12413        app.crashing = false;
12414        app.notResponding = false;
12415
12416        app.resetPackageList(mProcessStats);
12417        app.unlinkDeathRecipient();
12418        app.makeInactive(mProcessStats);
12419        app.forcingToForeground = null;
12420        updateProcessForegroundLocked(app, false, false);
12421        app.foregroundActivities = false;
12422        app.hasShownUi = false;
12423        app.hasAboveClient = false;
12424
12425        mServices.killServicesLocked(app, allowRestart);
12426
12427        boolean restart = false;
12428
12429        // Remove published content providers.
12430        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12431            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12432            final boolean always = app.bad || !allowRestart;
12433            if (removeDyingProviderLocked(app, cpr, always) || always) {
12434                // We left the provider in the launching list, need to
12435                // restart it.
12436                restart = true;
12437            }
12438
12439            cpr.provider = null;
12440            cpr.proc = null;
12441        }
12442        app.pubProviders.clear();
12443
12444        // Take care of any launching providers waiting for this process.
12445        if (checkAppInLaunchingProvidersLocked(app, false)) {
12446            restart = true;
12447        }
12448
12449        // Unregister from connected content providers.
12450        if (!app.conProviders.isEmpty()) {
12451            for (int i=0; i<app.conProviders.size(); i++) {
12452                ContentProviderConnection conn = app.conProviders.get(i);
12453                conn.provider.connections.remove(conn);
12454            }
12455            app.conProviders.clear();
12456        }
12457
12458        // At this point there may be remaining entries in mLaunchingProviders
12459        // where we were the only one waiting, so they are no longer of use.
12460        // Look for these and clean up if found.
12461        // XXX Commented out for now.  Trying to figure out a way to reproduce
12462        // the actual situation to identify what is actually going on.
12463        if (false) {
12464            for (int i=0; i<mLaunchingProviders.size(); i++) {
12465                ContentProviderRecord cpr = (ContentProviderRecord)
12466                        mLaunchingProviders.get(i);
12467                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12468                    synchronized (cpr) {
12469                        cpr.launchingApp = null;
12470                        cpr.notifyAll();
12471                    }
12472                }
12473            }
12474        }
12475
12476        skipCurrentReceiverLocked(app);
12477
12478        // Unregister any receivers.
12479        for (int i=app.receivers.size()-1; i>=0; i--) {
12480            removeReceiverLocked(app.receivers.valueAt(i));
12481        }
12482        app.receivers.clear();
12483
12484        // If the app is undergoing backup, tell the backup manager about it
12485        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12486            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12487                    + mBackupTarget.appInfo + " died during backup");
12488            try {
12489                IBackupManager bm = IBackupManager.Stub.asInterface(
12490                        ServiceManager.getService(Context.BACKUP_SERVICE));
12491                bm.agentDisconnected(app.info.packageName);
12492            } catch (RemoteException e) {
12493                // can't happen; backup manager is local
12494            }
12495        }
12496
12497        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12498            ProcessChangeItem item = mPendingProcessChanges.get(i);
12499            if (item.pid == app.pid) {
12500                mPendingProcessChanges.remove(i);
12501                mAvailProcessChanges.add(item);
12502            }
12503        }
12504        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12505
12506        // If the caller is restarting this app, then leave it in its
12507        // current lists and let the caller take care of it.
12508        if (restarting) {
12509            return;
12510        }
12511
12512        if (!app.persistent || app.isolated) {
12513            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12514                    "Removing non-persistent process during cleanup: " + app);
12515            mProcessNames.remove(app.processName, app.uid);
12516            mIsolatedProcesses.remove(app.uid);
12517            if (mHeavyWeightProcess == app) {
12518                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12519                        mHeavyWeightProcess.userId, 0));
12520                mHeavyWeightProcess = null;
12521            }
12522        } else if (!app.removed) {
12523            // This app is persistent, so we need to keep its record around.
12524            // If it is not already on the pending app list, add it there
12525            // and start a new process for it.
12526            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12527                mPersistentStartingProcesses.add(app);
12528                restart = true;
12529            }
12530        }
12531        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12532                "Clean-up removing on hold: " + app);
12533        mProcessesOnHold.remove(app);
12534
12535        if (app == mHomeProcess) {
12536            mHomeProcess = null;
12537        }
12538        if (app == mPreviousProcess) {
12539            mPreviousProcess = null;
12540        }
12541
12542        if (restart && !app.isolated) {
12543            // We have components that still need to be running in the
12544            // process, so re-launch it.
12545            mProcessNames.put(app.processName, app.uid, app);
12546            startProcessLocked(app, "restart", app.processName);
12547        } else if (app.pid > 0 && app.pid != MY_PID) {
12548            // Goodbye!
12549            boolean removed;
12550            synchronized (mPidsSelfLocked) {
12551                mPidsSelfLocked.remove(app.pid);
12552                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12553            }
12554            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
12555                    app.processName, app.info.uid);
12556            if (app.isolated) {
12557                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
12558            }
12559            app.setPid(0);
12560        }
12561    }
12562
12563    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12564        // Look through the content providers we are waiting to have launched,
12565        // and if any run in this process then either schedule a restart of
12566        // the process or kill the client waiting for it if this process has
12567        // gone bad.
12568        int NL = mLaunchingProviders.size();
12569        boolean restart = false;
12570        for (int i=0; i<NL; i++) {
12571            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12572            if (cpr.launchingApp == app) {
12573                if (!alwaysBad && !app.bad) {
12574                    restart = true;
12575                } else {
12576                    removeDyingProviderLocked(app, cpr, true);
12577                    // cpr should have been removed from mLaunchingProviders
12578                    NL = mLaunchingProviders.size();
12579                    i--;
12580                }
12581            }
12582        }
12583        return restart;
12584    }
12585
12586    // =========================================================
12587    // SERVICES
12588    // =========================================================
12589
12590    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12591            int flags) {
12592        enforceNotIsolatedCaller("getServices");
12593        synchronized (this) {
12594            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12595        }
12596    }
12597
12598    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12599        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12600        synchronized (this) {
12601            return mServices.getRunningServiceControlPanelLocked(name);
12602        }
12603    }
12604
12605    public ComponentName startService(IApplicationThread caller, Intent service,
12606            String resolvedType, int userId) {
12607        enforceNotIsolatedCaller("startService");
12608        // Refuse possible leaked file descriptors
12609        if (service != null && service.hasFileDescriptors() == true) {
12610            throw new IllegalArgumentException("File descriptors passed in Intent");
12611        }
12612
12613        if (DEBUG_SERVICE)
12614            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
12615        synchronized(this) {
12616            final int callingPid = Binder.getCallingPid();
12617            final int callingUid = Binder.getCallingUid();
12618            final long origId = Binder.clearCallingIdentity();
12619            ComponentName res = mServices.startServiceLocked(caller, service,
12620                    resolvedType, callingPid, callingUid, userId);
12621            Binder.restoreCallingIdentity(origId);
12622            return res;
12623        }
12624    }
12625
12626    ComponentName startServiceInPackage(int uid,
12627            Intent service, String resolvedType, int userId) {
12628        synchronized(this) {
12629            if (DEBUG_SERVICE)
12630                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
12631            final long origId = Binder.clearCallingIdentity();
12632            ComponentName res = mServices.startServiceLocked(null, service,
12633                    resolvedType, -1, uid, userId);
12634            Binder.restoreCallingIdentity(origId);
12635            return res;
12636        }
12637    }
12638
12639    public int stopService(IApplicationThread caller, Intent service,
12640            String resolvedType, int userId) {
12641        enforceNotIsolatedCaller("stopService");
12642        // Refuse possible leaked file descriptors
12643        if (service != null && service.hasFileDescriptors() == true) {
12644            throw new IllegalArgumentException("File descriptors passed in Intent");
12645        }
12646
12647        synchronized(this) {
12648            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
12649        }
12650    }
12651
12652    public IBinder peekService(Intent service, String resolvedType) {
12653        enforceNotIsolatedCaller("peekService");
12654        // Refuse possible leaked file descriptors
12655        if (service != null && service.hasFileDescriptors() == true) {
12656            throw new IllegalArgumentException("File descriptors passed in Intent");
12657        }
12658        synchronized(this) {
12659            return mServices.peekServiceLocked(service, resolvedType);
12660        }
12661    }
12662
12663    public boolean stopServiceToken(ComponentName className, IBinder token,
12664            int startId) {
12665        synchronized(this) {
12666            return mServices.stopServiceTokenLocked(className, token, startId);
12667        }
12668    }
12669
12670    public void setServiceForeground(ComponentName className, IBinder token,
12671            int id, Notification notification, boolean removeNotification) {
12672        synchronized(this) {
12673            mServices.setServiceForegroundLocked(className, token, id, notification,
12674                    removeNotification);
12675        }
12676    }
12677
12678    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
12679            boolean requireFull, String name, String callerPackage) {
12680        final int callingUserId = UserHandle.getUserId(callingUid);
12681        if (callingUserId != userId) {
12682            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
12683                if ((requireFull || checkComponentPermission(
12684                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12685                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
12686                        && checkComponentPermission(
12687                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
12688                                callingPid, callingUid, -1, true)
12689                                != PackageManager.PERMISSION_GRANTED) {
12690                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
12691                        // In this case, they would like to just execute as their
12692                        // owner user instead of failing.
12693                        userId = callingUserId;
12694                    } else {
12695                        StringBuilder builder = new StringBuilder(128);
12696                        builder.append("Permission Denial: ");
12697                        builder.append(name);
12698                        if (callerPackage != null) {
12699                            builder.append(" from ");
12700                            builder.append(callerPackage);
12701                        }
12702                        builder.append(" asks to run as user ");
12703                        builder.append(userId);
12704                        builder.append(" but is calling from user ");
12705                        builder.append(UserHandle.getUserId(callingUid));
12706                        builder.append("; this requires ");
12707                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
12708                        if (!requireFull) {
12709                            builder.append(" or ");
12710                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
12711                        }
12712                        String msg = builder.toString();
12713                        Slog.w(TAG, msg);
12714                        throw new SecurityException(msg);
12715                    }
12716                }
12717            }
12718            if (userId == UserHandle.USER_CURRENT
12719                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
12720                // Note that we may be accessing this outside of a lock...
12721                // shouldn't be a big deal, if this is being called outside
12722                // of a locked context there is intrinsically a race with
12723                // the value the caller will receive and someone else changing it.
12724                userId = mCurrentUserId;
12725            }
12726            if (!allowAll && userId < 0) {
12727                throw new IllegalArgumentException(
12728                        "Call does not support special user #" + userId);
12729            }
12730        }
12731        return userId;
12732    }
12733
12734    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
12735            String className, int flags) {
12736        boolean result = false;
12737        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
12738            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
12739                if (ActivityManager.checkUidPermission(
12740                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12741                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
12742                    ComponentName comp = new ComponentName(aInfo.packageName, className);
12743                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
12744                            + " requests FLAG_SINGLE_USER, but app does not hold "
12745                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
12746                    Slog.w(TAG, msg);
12747                    throw new SecurityException(msg);
12748                }
12749                result = true;
12750            }
12751        } else if (componentProcessName == aInfo.packageName) {
12752            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
12753        } else if ("system".equals(componentProcessName)) {
12754            result = true;
12755        }
12756        if (DEBUG_MU) {
12757            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
12758                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
12759        }
12760        return result;
12761    }
12762
12763    public int bindService(IApplicationThread caller, IBinder token,
12764            Intent service, String resolvedType,
12765            IServiceConnection connection, int flags, int userId) {
12766        enforceNotIsolatedCaller("bindService");
12767        // Refuse possible leaked file descriptors
12768        if (service != null && service.hasFileDescriptors() == true) {
12769            throw new IllegalArgumentException("File descriptors passed in Intent");
12770        }
12771
12772        synchronized(this) {
12773            return mServices.bindServiceLocked(caller, token, service, resolvedType,
12774                    connection, flags, userId);
12775        }
12776    }
12777
12778    public boolean unbindService(IServiceConnection connection) {
12779        synchronized (this) {
12780            return mServices.unbindServiceLocked(connection);
12781        }
12782    }
12783
12784    public void publishService(IBinder token, Intent intent, IBinder service) {
12785        // Refuse possible leaked file descriptors
12786        if (intent != null && intent.hasFileDescriptors() == true) {
12787            throw new IllegalArgumentException("File descriptors passed in Intent");
12788        }
12789
12790        synchronized(this) {
12791            if (!(token instanceof ServiceRecord)) {
12792                throw new IllegalArgumentException("Invalid service token");
12793            }
12794            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
12795        }
12796    }
12797
12798    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
12799        // Refuse possible leaked file descriptors
12800        if (intent != null && intent.hasFileDescriptors() == true) {
12801            throw new IllegalArgumentException("File descriptors passed in Intent");
12802        }
12803
12804        synchronized(this) {
12805            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
12806        }
12807    }
12808
12809    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
12810        synchronized(this) {
12811            if (!(token instanceof ServiceRecord)) {
12812                throw new IllegalArgumentException("Invalid service token");
12813            }
12814            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
12815        }
12816    }
12817
12818    // =========================================================
12819    // BACKUP AND RESTORE
12820    // =========================================================
12821
12822    // Cause the target app to be launched if necessary and its backup agent
12823    // instantiated.  The backup agent will invoke backupAgentCreated() on the
12824    // activity manager to announce its creation.
12825    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
12826        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
12827        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
12828
12829        synchronized(this) {
12830            // !!! TODO: currently no check here that we're already bound
12831            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
12832            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12833            synchronized (stats) {
12834                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
12835            }
12836
12837            // Backup agent is now in use, its package can't be stopped.
12838            try {
12839                AppGlobals.getPackageManager().setPackageStoppedState(
12840                        app.packageName, false, UserHandle.getUserId(app.uid));
12841            } catch (RemoteException e) {
12842            } catch (IllegalArgumentException e) {
12843                Slog.w(TAG, "Failed trying to unstop package "
12844                        + app.packageName + ": " + e);
12845            }
12846
12847            BackupRecord r = new BackupRecord(ss, app, backupMode);
12848            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
12849                    ? new ComponentName(app.packageName, app.backupAgentName)
12850                    : new ComponentName("android", "FullBackupAgent");
12851            // startProcessLocked() returns existing proc's record if it's already running
12852            ProcessRecord proc = startProcessLocked(app.processName, app,
12853                    false, 0, "backup", hostingName, false, false, false);
12854            if (proc == null) {
12855                Slog.e(TAG, "Unable to start backup agent process " + r);
12856                return false;
12857            }
12858
12859            r.app = proc;
12860            mBackupTarget = r;
12861            mBackupAppName = app.packageName;
12862
12863            // Try not to kill the process during backup
12864            updateOomAdjLocked(proc);
12865
12866            // If the process is already attached, schedule the creation of the backup agent now.
12867            // If it is not yet live, this will be done when it attaches to the framework.
12868            if (proc.thread != null) {
12869                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
12870                try {
12871                    proc.thread.scheduleCreateBackupAgent(app,
12872                            compatibilityInfoForPackageLocked(app), backupMode);
12873                } catch (RemoteException e) {
12874                    // Will time out on the backup manager side
12875                }
12876            } else {
12877                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
12878            }
12879            // Invariants: at this point, the target app process exists and the application
12880            // is either already running or in the process of coming up.  mBackupTarget and
12881            // mBackupAppName describe the app, so that when it binds back to the AM we
12882            // know that it's scheduled for a backup-agent operation.
12883        }
12884
12885        return true;
12886    }
12887
12888    @Override
12889    public void clearPendingBackup() {
12890        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
12891        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
12892
12893        synchronized (this) {
12894            mBackupTarget = null;
12895            mBackupAppName = null;
12896        }
12897    }
12898
12899    // A backup agent has just come up
12900    public void backupAgentCreated(String agentPackageName, IBinder agent) {
12901        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
12902                + " = " + agent);
12903
12904        synchronized(this) {
12905            if (!agentPackageName.equals(mBackupAppName)) {
12906                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
12907                return;
12908            }
12909        }
12910
12911        long oldIdent = Binder.clearCallingIdentity();
12912        try {
12913            IBackupManager bm = IBackupManager.Stub.asInterface(
12914                    ServiceManager.getService(Context.BACKUP_SERVICE));
12915            bm.agentConnected(agentPackageName, agent);
12916        } catch (RemoteException e) {
12917            // can't happen; the backup manager service is local
12918        } catch (Exception e) {
12919            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
12920            e.printStackTrace();
12921        } finally {
12922            Binder.restoreCallingIdentity(oldIdent);
12923        }
12924    }
12925
12926    // done with this agent
12927    public void unbindBackupAgent(ApplicationInfo appInfo) {
12928        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
12929        if (appInfo == null) {
12930            Slog.w(TAG, "unbind backup agent for null app");
12931            return;
12932        }
12933
12934        synchronized(this) {
12935            try {
12936                if (mBackupAppName == null) {
12937                    Slog.w(TAG, "Unbinding backup agent with no active backup");
12938                    return;
12939                }
12940
12941                if (!mBackupAppName.equals(appInfo.packageName)) {
12942                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
12943                    return;
12944                }
12945
12946                // Not backing this app up any more; reset its OOM adjustment
12947                final ProcessRecord proc = mBackupTarget.app;
12948                updateOomAdjLocked(proc);
12949
12950                // If the app crashed during backup, 'thread' will be null here
12951                if (proc.thread != null) {
12952                    try {
12953                        proc.thread.scheduleDestroyBackupAgent(appInfo,
12954                                compatibilityInfoForPackageLocked(appInfo));
12955                    } catch (Exception e) {
12956                        Slog.e(TAG, "Exception when unbinding backup agent:");
12957                        e.printStackTrace();
12958                    }
12959                }
12960            } finally {
12961                mBackupTarget = null;
12962                mBackupAppName = null;
12963            }
12964        }
12965    }
12966    // =========================================================
12967    // BROADCASTS
12968    // =========================================================
12969
12970    private final List getStickiesLocked(String action, IntentFilter filter,
12971            List cur, int userId) {
12972        final ContentResolver resolver = mContext.getContentResolver();
12973        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
12974        if (stickies == null) {
12975            return cur;
12976        }
12977        final ArrayList<Intent> list = stickies.get(action);
12978        if (list == null) {
12979            return cur;
12980        }
12981        int N = list.size();
12982        for (int i=0; i<N; i++) {
12983            Intent intent = list.get(i);
12984            if (filter.match(resolver, intent, true, TAG) >= 0) {
12985                if (cur == null) {
12986                    cur = new ArrayList<Intent>();
12987                }
12988                cur.add(intent);
12989            }
12990        }
12991        return cur;
12992    }
12993
12994    boolean isPendingBroadcastProcessLocked(int pid) {
12995        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
12996                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
12997    }
12998
12999    void skipPendingBroadcastLocked(int pid) {
13000            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13001            for (BroadcastQueue queue : mBroadcastQueues) {
13002                queue.skipPendingBroadcastLocked(pid);
13003            }
13004    }
13005
13006    // The app just attached; send any pending broadcasts that it should receive
13007    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13008        boolean didSomething = false;
13009        for (BroadcastQueue queue : mBroadcastQueues) {
13010            didSomething |= queue.sendPendingBroadcastsLocked(app);
13011        }
13012        return didSomething;
13013    }
13014
13015    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13016            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13017        enforceNotIsolatedCaller("registerReceiver");
13018        int callingUid;
13019        int callingPid;
13020        synchronized(this) {
13021            ProcessRecord callerApp = null;
13022            if (caller != null) {
13023                callerApp = getRecordForAppLocked(caller);
13024                if (callerApp == null) {
13025                    throw new SecurityException(
13026                            "Unable to find app for caller " + caller
13027                            + " (pid=" + Binder.getCallingPid()
13028                            + ") when registering receiver " + receiver);
13029                }
13030                if (callerApp.info.uid != Process.SYSTEM_UID &&
13031                        !callerApp.pkgList.containsKey(callerPackage) &&
13032                        !"android".equals(callerPackage)) {
13033                    throw new SecurityException("Given caller package " + callerPackage
13034                            + " is not running in process " + callerApp);
13035                }
13036                callingUid = callerApp.info.uid;
13037                callingPid = callerApp.pid;
13038            } else {
13039                callerPackage = null;
13040                callingUid = Binder.getCallingUid();
13041                callingPid = Binder.getCallingPid();
13042            }
13043
13044            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13045                    true, true, "registerReceiver", callerPackage);
13046
13047            List allSticky = null;
13048
13049            // Look for any matching sticky broadcasts...
13050            Iterator actions = filter.actionsIterator();
13051            if (actions != null) {
13052                while (actions.hasNext()) {
13053                    String action = (String)actions.next();
13054                    allSticky = getStickiesLocked(action, filter, allSticky,
13055                            UserHandle.USER_ALL);
13056                    allSticky = getStickiesLocked(action, filter, allSticky,
13057                            UserHandle.getUserId(callingUid));
13058                }
13059            } else {
13060                allSticky = getStickiesLocked(null, filter, allSticky,
13061                        UserHandle.USER_ALL);
13062                allSticky = getStickiesLocked(null, filter, allSticky,
13063                        UserHandle.getUserId(callingUid));
13064            }
13065
13066            // The first sticky in the list is returned directly back to
13067            // the client.
13068            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13069
13070            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13071                    + ": " + sticky);
13072
13073            if (receiver == null) {
13074                return sticky;
13075            }
13076
13077            ReceiverList rl
13078                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13079            if (rl == null) {
13080                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13081                        userId, receiver);
13082                if (rl.app != null) {
13083                    rl.app.receivers.add(rl);
13084                } else {
13085                    try {
13086                        receiver.asBinder().linkToDeath(rl, 0);
13087                    } catch (RemoteException e) {
13088                        return sticky;
13089                    }
13090                    rl.linkedToDeath = true;
13091                }
13092                mRegisteredReceivers.put(receiver.asBinder(), rl);
13093            } else if (rl.uid != callingUid) {
13094                throw new IllegalArgumentException(
13095                        "Receiver requested to register for uid " + callingUid
13096                        + " was previously registered for uid " + rl.uid);
13097            } else if (rl.pid != callingPid) {
13098                throw new IllegalArgumentException(
13099                        "Receiver requested to register for pid " + callingPid
13100                        + " was previously registered for pid " + rl.pid);
13101            } else if (rl.userId != userId) {
13102                throw new IllegalArgumentException(
13103                        "Receiver requested to register for user " + userId
13104                        + " was previously registered for user " + rl.userId);
13105            }
13106            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13107                    permission, callingUid, userId);
13108            rl.add(bf);
13109            if (!bf.debugCheck()) {
13110                Slog.w(TAG, "==> For Dynamic broadast");
13111            }
13112            mReceiverResolver.addFilter(bf);
13113
13114            // Enqueue broadcasts for all existing stickies that match
13115            // this filter.
13116            if (allSticky != null) {
13117                ArrayList receivers = new ArrayList();
13118                receivers.add(bf);
13119
13120                int N = allSticky.size();
13121                for (int i=0; i<N; i++) {
13122                    Intent intent = (Intent)allSticky.get(i);
13123                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13124                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13125                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13126                            null, null, false, true, true, -1);
13127                    queue.enqueueParallelBroadcastLocked(r);
13128                    queue.scheduleBroadcastsLocked();
13129                }
13130            }
13131
13132            return sticky;
13133        }
13134    }
13135
13136    public void unregisterReceiver(IIntentReceiver receiver) {
13137        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13138
13139        final long origId = Binder.clearCallingIdentity();
13140        try {
13141            boolean doTrim = false;
13142
13143            synchronized(this) {
13144                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13145                if (rl != null) {
13146                    if (rl.curBroadcast != null) {
13147                        BroadcastRecord r = rl.curBroadcast;
13148                        final boolean doNext = finishReceiverLocked(
13149                                receiver.asBinder(), r.resultCode, r.resultData,
13150                                r.resultExtras, r.resultAbort);
13151                        if (doNext) {
13152                            doTrim = true;
13153                            r.queue.processNextBroadcast(false);
13154                        }
13155                    }
13156
13157                    if (rl.app != null) {
13158                        rl.app.receivers.remove(rl);
13159                    }
13160                    removeReceiverLocked(rl);
13161                    if (rl.linkedToDeath) {
13162                        rl.linkedToDeath = false;
13163                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13164                    }
13165                }
13166            }
13167
13168            // If we actually concluded any broadcasts, we might now be able
13169            // to trim the recipients' apps from our working set
13170            if (doTrim) {
13171                trimApplications();
13172                return;
13173            }
13174
13175        } finally {
13176            Binder.restoreCallingIdentity(origId);
13177        }
13178    }
13179
13180    void removeReceiverLocked(ReceiverList rl) {
13181        mRegisteredReceivers.remove(rl.receiver.asBinder());
13182        int N = rl.size();
13183        for (int i=0; i<N; i++) {
13184            mReceiverResolver.removeFilter(rl.get(i));
13185        }
13186    }
13187
13188    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13189        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13190            ProcessRecord r = mLruProcesses.get(i);
13191            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13192                try {
13193                    r.thread.dispatchPackageBroadcast(cmd, packages);
13194                } catch (RemoteException ex) {
13195                }
13196            }
13197        }
13198    }
13199
13200    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13201            int[] users) {
13202        List<ResolveInfo> receivers = null;
13203        try {
13204            HashSet<ComponentName> singleUserReceivers = null;
13205            boolean scannedFirstReceivers = false;
13206            for (int user : users) {
13207                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13208                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13209                if (user != 0 && newReceivers != null) {
13210                    // If this is not the primary user, we need to check for
13211                    // any receivers that should be filtered out.
13212                    for (int i=0; i<newReceivers.size(); i++) {
13213                        ResolveInfo ri = newReceivers.get(i);
13214                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13215                            newReceivers.remove(i);
13216                            i--;
13217                        }
13218                    }
13219                }
13220                if (newReceivers != null && newReceivers.size() == 0) {
13221                    newReceivers = null;
13222                }
13223                if (receivers == null) {
13224                    receivers = newReceivers;
13225                } else if (newReceivers != null) {
13226                    // We need to concatenate the additional receivers
13227                    // found with what we have do far.  This would be easy,
13228                    // but we also need to de-dup any receivers that are
13229                    // singleUser.
13230                    if (!scannedFirstReceivers) {
13231                        // Collect any single user receivers we had already retrieved.
13232                        scannedFirstReceivers = true;
13233                        for (int i=0; i<receivers.size(); i++) {
13234                            ResolveInfo ri = receivers.get(i);
13235                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13236                                ComponentName cn = new ComponentName(
13237                                        ri.activityInfo.packageName, ri.activityInfo.name);
13238                                if (singleUserReceivers == null) {
13239                                    singleUserReceivers = new HashSet<ComponentName>();
13240                                }
13241                                singleUserReceivers.add(cn);
13242                            }
13243                        }
13244                    }
13245                    // Add the new results to the existing results, tracking
13246                    // and de-dupping single user receivers.
13247                    for (int i=0; i<newReceivers.size(); i++) {
13248                        ResolveInfo ri = newReceivers.get(i);
13249                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13250                            ComponentName cn = new ComponentName(
13251                                    ri.activityInfo.packageName, ri.activityInfo.name);
13252                            if (singleUserReceivers == null) {
13253                                singleUserReceivers = new HashSet<ComponentName>();
13254                            }
13255                            if (!singleUserReceivers.contains(cn)) {
13256                                singleUserReceivers.add(cn);
13257                                receivers.add(ri);
13258                            }
13259                        } else {
13260                            receivers.add(ri);
13261                        }
13262                    }
13263                }
13264            }
13265        } catch (RemoteException ex) {
13266            // pm is in same process, this will never happen.
13267        }
13268        return receivers;
13269    }
13270
13271    private final int broadcastIntentLocked(ProcessRecord callerApp,
13272            String callerPackage, Intent intent, String resolvedType,
13273            IIntentReceiver resultTo, int resultCode, String resultData,
13274            Bundle map, String requiredPermission, int appOp,
13275            boolean ordered, boolean sticky, int callingPid, int callingUid,
13276            int userId) {
13277        intent = new Intent(intent);
13278
13279        // By default broadcasts do not go to stopped apps.
13280        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13281
13282        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13283            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13284            + " ordered=" + ordered + " userid=" + userId);
13285        if ((resultTo != null) && !ordered) {
13286            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13287        }
13288
13289        userId = handleIncomingUser(callingPid, callingUid, userId,
13290                true, false, "broadcast", callerPackage);
13291
13292        // Make sure that the user who is receiving this broadcast is started.
13293        // If not, we will just skip it.
13294        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13295            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13296                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13297                Slog.w(TAG, "Skipping broadcast of " + intent
13298                        + ": user " + userId + " is stopped");
13299                return ActivityManager.BROADCAST_SUCCESS;
13300            }
13301        }
13302
13303        /*
13304         * Prevent non-system code (defined here to be non-persistent
13305         * processes) from sending protected broadcasts.
13306         */
13307        int callingAppId = UserHandle.getAppId(callingUid);
13308        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13309            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13310            callingUid == 0) {
13311            // Always okay.
13312        } else if (callerApp == null || !callerApp.persistent) {
13313            try {
13314                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13315                        intent.getAction())) {
13316                    String msg = "Permission Denial: not allowed to send broadcast "
13317                            + intent.getAction() + " from pid="
13318                            + callingPid + ", uid=" + callingUid;
13319                    Slog.w(TAG, msg);
13320                    throw new SecurityException(msg);
13321                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13322                    // Special case for compatibility: we don't want apps to send this,
13323                    // but historically it has not been protected and apps may be using it
13324                    // to poke their own app widget.  So, instead of making it protected,
13325                    // just limit it to the caller.
13326                    if (callerApp == null) {
13327                        String msg = "Permission Denial: not allowed to send broadcast "
13328                                + intent.getAction() + " from unknown caller.";
13329                        Slog.w(TAG, msg);
13330                        throw new SecurityException(msg);
13331                    } else if (intent.getComponent() != null) {
13332                        // They are good enough to send to an explicit component...  verify
13333                        // it is being sent to the calling app.
13334                        if (!intent.getComponent().getPackageName().equals(
13335                                callerApp.info.packageName)) {
13336                            String msg = "Permission Denial: not allowed to send broadcast "
13337                                    + intent.getAction() + " to "
13338                                    + intent.getComponent().getPackageName() + " from "
13339                                    + callerApp.info.packageName;
13340                            Slog.w(TAG, msg);
13341                            throw new SecurityException(msg);
13342                        }
13343                    } else {
13344                        // Limit broadcast to their own package.
13345                        intent.setPackage(callerApp.info.packageName);
13346                    }
13347                }
13348            } catch (RemoteException e) {
13349                Slog.w(TAG, "Remote exception", e);
13350                return ActivityManager.BROADCAST_SUCCESS;
13351            }
13352        }
13353
13354        // Handle special intents: if this broadcast is from the package
13355        // manager about a package being removed, we need to remove all of
13356        // its activities from the history stack.
13357        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13358                intent.getAction());
13359        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13360                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13361                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13362                || uidRemoved) {
13363            if (checkComponentPermission(
13364                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13365                    callingPid, callingUid, -1, true)
13366                    == PackageManager.PERMISSION_GRANTED) {
13367                if (uidRemoved) {
13368                    final Bundle intentExtras = intent.getExtras();
13369                    final int uid = intentExtras != null
13370                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13371                    if (uid >= 0) {
13372                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13373                        synchronized (bs) {
13374                            bs.removeUidStatsLocked(uid);
13375                        }
13376                        mAppOpsService.uidRemoved(uid);
13377                    }
13378                } else {
13379                    // If resources are unavailable just force stop all
13380                    // those packages and flush the attribute cache as well.
13381                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13382                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13383                        if (list != null && (list.length > 0)) {
13384                            for (String pkg : list) {
13385                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13386                                        "storage unmount");
13387                            }
13388                            sendPackageBroadcastLocked(
13389                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13390                        }
13391                    } else {
13392                        Uri data = intent.getData();
13393                        String ssp;
13394                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13395                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13396                                    intent.getAction());
13397                            boolean fullUninstall = removed &&
13398                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13399                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13400                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13401                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13402                                        false, fullUninstall, userId,
13403                                        removed ? "pkg removed" : "pkg changed");
13404                            }
13405                            if (removed) {
13406                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13407                                        new String[] {ssp}, userId);
13408                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13409                                    mAppOpsService.packageRemoved(
13410                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13411
13412                                    // Remove all permissions granted from/to this package
13413                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13414                                }
13415                            }
13416                        }
13417                    }
13418                }
13419            } else {
13420                String msg = "Permission Denial: " + intent.getAction()
13421                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13422                        + ", uid=" + callingUid + ")"
13423                        + " requires "
13424                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13425                Slog.w(TAG, msg);
13426                throw new SecurityException(msg);
13427            }
13428
13429        // Special case for adding a package: by default turn on compatibility
13430        // mode.
13431        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13432            Uri data = intent.getData();
13433            String ssp;
13434            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13435                mCompatModePackages.handlePackageAddedLocked(ssp,
13436                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13437            }
13438        }
13439
13440        /*
13441         * If this is the time zone changed action, queue up a message that will reset the timezone
13442         * of all currently running processes. This message will get queued up before the broadcast
13443         * happens.
13444         */
13445        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13446            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13447        }
13448
13449        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13450            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13451        }
13452
13453        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13454            ProxyProperties proxy = intent.getParcelableExtra("proxy");
13455            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13456        }
13457
13458        // Add to the sticky list if requested.
13459        if (sticky) {
13460            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13461                    callingPid, callingUid)
13462                    != PackageManager.PERMISSION_GRANTED) {
13463                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13464                        + callingPid + ", uid=" + callingUid
13465                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13466                Slog.w(TAG, msg);
13467                throw new SecurityException(msg);
13468            }
13469            if (requiredPermission != null) {
13470                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13471                        + " and enforce permission " + requiredPermission);
13472                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13473            }
13474            if (intent.getComponent() != null) {
13475                throw new SecurityException(
13476                        "Sticky broadcasts can't target a specific component");
13477            }
13478            // We use userId directly here, since the "all" target is maintained
13479            // as a separate set of sticky broadcasts.
13480            if (userId != UserHandle.USER_ALL) {
13481                // But first, if this is not a broadcast to all users, then
13482                // make sure it doesn't conflict with an existing broadcast to
13483                // all users.
13484                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13485                        UserHandle.USER_ALL);
13486                if (stickies != null) {
13487                    ArrayList<Intent> list = stickies.get(intent.getAction());
13488                    if (list != null) {
13489                        int N = list.size();
13490                        int i;
13491                        for (i=0; i<N; i++) {
13492                            if (intent.filterEquals(list.get(i))) {
13493                                throw new IllegalArgumentException(
13494                                        "Sticky broadcast " + intent + " for user "
13495                                        + userId + " conflicts with existing global broadcast");
13496                            }
13497                        }
13498                    }
13499                }
13500            }
13501            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13502            if (stickies == null) {
13503                stickies = new ArrayMap<String, ArrayList<Intent>>();
13504                mStickyBroadcasts.put(userId, stickies);
13505            }
13506            ArrayList<Intent> list = stickies.get(intent.getAction());
13507            if (list == null) {
13508                list = new ArrayList<Intent>();
13509                stickies.put(intent.getAction(), list);
13510            }
13511            int N = list.size();
13512            int i;
13513            for (i=0; i<N; i++) {
13514                if (intent.filterEquals(list.get(i))) {
13515                    // This sticky already exists, replace it.
13516                    list.set(i, new Intent(intent));
13517                    break;
13518                }
13519            }
13520            if (i >= N) {
13521                list.add(new Intent(intent));
13522            }
13523        }
13524
13525        int[] users;
13526        if (userId == UserHandle.USER_ALL) {
13527            // Caller wants broadcast to go to all started users.
13528            users = mStartedUserArray;
13529        } else {
13530            // Caller wants broadcast to go to one specific user.
13531            users = new int[] {userId};
13532        }
13533
13534        // Figure out who all will receive this broadcast.
13535        List receivers = null;
13536        List<BroadcastFilter> registeredReceivers = null;
13537        // Need to resolve the intent to interested receivers...
13538        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13539                 == 0) {
13540            receivers = collectReceiverComponents(intent, resolvedType, users);
13541        }
13542        if (intent.getComponent() == null) {
13543            registeredReceivers = mReceiverResolver.queryIntent(intent,
13544                    resolvedType, false, userId);
13545        }
13546
13547        final boolean replacePending =
13548                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13549
13550        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13551                + " replacePending=" + replacePending);
13552
13553        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13554        if (!ordered && NR > 0) {
13555            // If we are not serializing this broadcast, then send the
13556            // registered receivers separately so they don't wait for the
13557            // components to be launched.
13558            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13559            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13560                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13561                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13562                    ordered, sticky, false, userId);
13563            if (DEBUG_BROADCAST) Slog.v(
13564                    TAG, "Enqueueing parallel broadcast " + r);
13565            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13566            if (!replaced) {
13567                queue.enqueueParallelBroadcastLocked(r);
13568                queue.scheduleBroadcastsLocked();
13569            }
13570            registeredReceivers = null;
13571            NR = 0;
13572        }
13573
13574        // Merge into one list.
13575        int ir = 0;
13576        if (receivers != null) {
13577            // A special case for PACKAGE_ADDED: do not allow the package
13578            // being added to see this broadcast.  This prevents them from
13579            // using this as a back door to get run as soon as they are
13580            // installed.  Maybe in the future we want to have a special install
13581            // broadcast or such for apps, but we'd like to deliberately make
13582            // this decision.
13583            String skipPackages[] = null;
13584            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13585                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13586                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13587                Uri data = intent.getData();
13588                if (data != null) {
13589                    String pkgName = data.getSchemeSpecificPart();
13590                    if (pkgName != null) {
13591                        skipPackages = new String[] { pkgName };
13592                    }
13593                }
13594            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13595                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13596            }
13597            if (skipPackages != null && (skipPackages.length > 0)) {
13598                for (String skipPackage : skipPackages) {
13599                    if (skipPackage != null) {
13600                        int NT = receivers.size();
13601                        for (int it=0; it<NT; it++) {
13602                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
13603                            if (curt.activityInfo.packageName.equals(skipPackage)) {
13604                                receivers.remove(it);
13605                                it--;
13606                                NT--;
13607                            }
13608                        }
13609                    }
13610                }
13611            }
13612
13613            int NT = receivers != null ? receivers.size() : 0;
13614            int it = 0;
13615            ResolveInfo curt = null;
13616            BroadcastFilter curr = null;
13617            while (it < NT && ir < NR) {
13618                if (curt == null) {
13619                    curt = (ResolveInfo)receivers.get(it);
13620                }
13621                if (curr == null) {
13622                    curr = registeredReceivers.get(ir);
13623                }
13624                if (curr.getPriority() >= curt.priority) {
13625                    // Insert this broadcast record into the final list.
13626                    receivers.add(it, curr);
13627                    ir++;
13628                    curr = null;
13629                    it++;
13630                    NT++;
13631                } else {
13632                    // Skip to the next ResolveInfo in the final list.
13633                    it++;
13634                    curt = null;
13635                }
13636            }
13637        }
13638        while (ir < NR) {
13639            if (receivers == null) {
13640                receivers = new ArrayList();
13641            }
13642            receivers.add(registeredReceivers.get(ir));
13643            ir++;
13644        }
13645
13646        if ((receivers != null && receivers.size() > 0)
13647                || resultTo != null) {
13648            BroadcastQueue queue = broadcastQueueForIntent(intent);
13649            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13650                    callerPackage, callingPid, callingUid, resolvedType,
13651                    requiredPermission, appOp, receivers, resultTo, resultCode,
13652                    resultData, map, ordered, sticky, false, userId);
13653            if (DEBUG_BROADCAST) Slog.v(
13654                    TAG, "Enqueueing ordered broadcast " + r
13655                    + ": prev had " + queue.mOrderedBroadcasts.size());
13656            if (DEBUG_BROADCAST) {
13657                int seq = r.intent.getIntExtra("seq", -1);
13658                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
13659            }
13660            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
13661            if (!replaced) {
13662                queue.enqueueOrderedBroadcastLocked(r);
13663                queue.scheduleBroadcastsLocked();
13664            }
13665        }
13666
13667        return ActivityManager.BROADCAST_SUCCESS;
13668    }
13669
13670    final Intent verifyBroadcastLocked(Intent intent) {
13671        // Refuse possible leaked file descriptors
13672        if (intent != null && intent.hasFileDescriptors() == true) {
13673            throw new IllegalArgumentException("File descriptors passed in Intent");
13674        }
13675
13676        int flags = intent.getFlags();
13677
13678        if (!mProcessesReady) {
13679            // if the caller really truly claims to know what they're doing, go
13680            // ahead and allow the broadcast without launching any receivers
13681            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
13682                intent = new Intent(intent);
13683                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13684            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
13685                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
13686                        + " before boot completion");
13687                throw new IllegalStateException("Cannot broadcast before boot completed");
13688            }
13689        }
13690
13691        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
13692            throw new IllegalArgumentException(
13693                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
13694        }
13695
13696        return intent;
13697    }
13698
13699    public final int broadcastIntent(IApplicationThread caller,
13700            Intent intent, String resolvedType, IIntentReceiver resultTo,
13701            int resultCode, String resultData, Bundle map,
13702            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
13703        enforceNotIsolatedCaller("broadcastIntent");
13704        synchronized(this) {
13705            intent = verifyBroadcastLocked(intent);
13706
13707            final ProcessRecord callerApp = getRecordForAppLocked(caller);
13708            final int callingPid = Binder.getCallingPid();
13709            final int callingUid = Binder.getCallingUid();
13710            final long origId = Binder.clearCallingIdentity();
13711            int res = broadcastIntentLocked(callerApp,
13712                    callerApp != null ? callerApp.info.packageName : null,
13713                    intent, resolvedType, resultTo,
13714                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
13715                    callingPid, callingUid, userId);
13716            Binder.restoreCallingIdentity(origId);
13717            return res;
13718        }
13719    }
13720
13721    int broadcastIntentInPackage(String packageName, int uid,
13722            Intent intent, String resolvedType, IIntentReceiver resultTo,
13723            int resultCode, String resultData, Bundle map,
13724            String requiredPermission, boolean serialized, boolean sticky, int userId) {
13725        synchronized(this) {
13726            intent = verifyBroadcastLocked(intent);
13727
13728            final long origId = Binder.clearCallingIdentity();
13729            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
13730                    resultTo, resultCode, resultData, map, requiredPermission,
13731                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
13732            Binder.restoreCallingIdentity(origId);
13733            return res;
13734        }
13735    }
13736
13737    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
13738        // Refuse possible leaked file descriptors
13739        if (intent != null && intent.hasFileDescriptors() == true) {
13740            throw new IllegalArgumentException("File descriptors passed in Intent");
13741        }
13742
13743        userId = handleIncomingUser(Binder.getCallingPid(),
13744                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
13745
13746        synchronized(this) {
13747            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
13748                    != PackageManager.PERMISSION_GRANTED) {
13749                String msg = "Permission Denial: unbroadcastIntent() from pid="
13750                        + Binder.getCallingPid()
13751                        + ", uid=" + Binder.getCallingUid()
13752                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13753                Slog.w(TAG, msg);
13754                throw new SecurityException(msg);
13755            }
13756            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13757            if (stickies != null) {
13758                ArrayList<Intent> list = stickies.get(intent.getAction());
13759                if (list != null) {
13760                    int N = list.size();
13761                    int i;
13762                    for (i=0; i<N; i++) {
13763                        if (intent.filterEquals(list.get(i))) {
13764                            list.remove(i);
13765                            break;
13766                        }
13767                    }
13768                    if (list.size() <= 0) {
13769                        stickies.remove(intent.getAction());
13770                    }
13771                }
13772                if (stickies.size() <= 0) {
13773                    mStickyBroadcasts.remove(userId);
13774                }
13775            }
13776        }
13777    }
13778
13779    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
13780            String resultData, Bundle resultExtras, boolean resultAbort) {
13781        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
13782        if (r == null) {
13783            Slog.w(TAG, "finishReceiver called but not found on queue");
13784            return false;
13785        }
13786
13787        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
13788    }
13789
13790    void backgroundServicesFinishedLocked(int userId) {
13791        for (BroadcastQueue queue : mBroadcastQueues) {
13792            queue.backgroundServicesFinishedLocked(userId);
13793        }
13794    }
13795
13796    public void finishReceiver(IBinder who, int resultCode, String resultData,
13797            Bundle resultExtras, boolean resultAbort) {
13798        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
13799
13800        // Refuse possible leaked file descriptors
13801        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
13802            throw new IllegalArgumentException("File descriptors passed in Bundle");
13803        }
13804
13805        final long origId = Binder.clearCallingIdentity();
13806        try {
13807            boolean doNext = false;
13808            BroadcastRecord r;
13809
13810            synchronized(this) {
13811                r = broadcastRecordForReceiverLocked(who);
13812                if (r != null) {
13813                    doNext = r.queue.finishReceiverLocked(r, resultCode,
13814                        resultData, resultExtras, resultAbort, true);
13815                }
13816            }
13817
13818            if (doNext) {
13819                r.queue.processNextBroadcast(false);
13820            }
13821            trimApplications();
13822        } finally {
13823            Binder.restoreCallingIdentity(origId);
13824        }
13825    }
13826
13827    // =========================================================
13828    // INSTRUMENTATION
13829    // =========================================================
13830
13831    public boolean startInstrumentation(ComponentName className,
13832            String profileFile, int flags, Bundle arguments,
13833            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
13834            int userId) {
13835        enforceNotIsolatedCaller("startInstrumentation");
13836        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
13837                userId, false, true, "startInstrumentation", null);
13838        // Refuse possible leaked file descriptors
13839        if (arguments != null && arguments.hasFileDescriptors()) {
13840            throw new IllegalArgumentException("File descriptors passed in Bundle");
13841        }
13842
13843        synchronized(this) {
13844            InstrumentationInfo ii = null;
13845            ApplicationInfo ai = null;
13846            try {
13847                ii = mContext.getPackageManager().getInstrumentationInfo(
13848                    className, STOCK_PM_FLAGS);
13849                ai = AppGlobals.getPackageManager().getApplicationInfo(
13850                        ii.targetPackage, STOCK_PM_FLAGS, userId);
13851            } catch (PackageManager.NameNotFoundException e) {
13852            } catch (RemoteException e) {
13853            }
13854            if (ii == null) {
13855                reportStartInstrumentationFailure(watcher, className,
13856                        "Unable to find instrumentation info for: " + className);
13857                return false;
13858            }
13859            if (ai == null) {
13860                reportStartInstrumentationFailure(watcher, className,
13861                        "Unable to find instrumentation target package: " + ii.targetPackage);
13862                return false;
13863            }
13864
13865            int match = mContext.getPackageManager().checkSignatures(
13866                    ii.targetPackage, ii.packageName);
13867            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
13868                String msg = "Permission Denial: starting instrumentation "
13869                        + className + " from pid="
13870                        + Binder.getCallingPid()
13871                        + ", uid=" + Binder.getCallingPid()
13872                        + " not allowed because package " + ii.packageName
13873                        + " does not have a signature matching the target "
13874                        + ii.targetPackage;
13875                reportStartInstrumentationFailure(watcher, className, msg);
13876                throw new SecurityException(msg);
13877            }
13878
13879            final long origId = Binder.clearCallingIdentity();
13880            // Instrumentation can kill and relaunch even persistent processes
13881            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
13882                    "start instr");
13883            ProcessRecord app = addAppLocked(ai, false);
13884            app.instrumentationClass = className;
13885            app.instrumentationInfo = ai;
13886            app.instrumentationProfileFile = profileFile;
13887            app.instrumentationArguments = arguments;
13888            app.instrumentationWatcher = watcher;
13889            app.instrumentationUiAutomationConnection = uiAutomationConnection;
13890            app.instrumentationResultClass = className;
13891            Binder.restoreCallingIdentity(origId);
13892        }
13893
13894        return true;
13895    }
13896
13897    /**
13898     * Report errors that occur while attempting to start Instrumentation.  Always writes the
13899     * error to the logs, but if somebody is watching, send the report there too.  This enables
13900     * the "am" command to report errors with more information.
13901     *
13902     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
13903     * @param cn The component name of the instrumentation.
13904     * @param report The error report.
13905     */
13906    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
13907            ComponentName cn, String report) {
13908        Slog.w(TAG, report);
13909        try {
13910            if (watcher != null) {
13911                Bundle results = new Bundle();
13912                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
13913                results.putString("Error", report);
13914                watcher.instrumentationStatus(cn, -1, results);
13915            }
13916        } catch (RemoteException e) {
13917            Slog.w(TAG, e);
13918        }
13919    }
13920
13921    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
13922        if (app.instrumentationWatcher != null) {
13923            try {
13924                // NOTE:  IInstrumentationWatcher *must* be oneway here
13925                app.instrumentationWatcher.instrumentationFinished(
13926                    app.instrumentationClass,
13927                    resultCode,
13928                    results);
13929            } catch (RemoteException e) {
13930            }
13931        }
13932        if (app.instrumentationUiAutomationConnection != null) {
13933            try {
13934                app.instrumentationUiAutomationConnection.shutdown();
13935            } catch (RemoteException re) {
13936                /* ignore */
13937            }
13938            // Only a UiAutomation can set this flag and now that
13939            // it is finished we make sure it is reset to its default.
13940            mUserIsMonkey = false;
13941        }
13942        app.instrumentationWatcher = null;
13943        app.instrumentationUiAutomationConnection = null;
13944        app.instrumentationClass = null;
13945        app.instrumentationInfo = null;
13946        app.instrumentationProfileFile = null;
13947        app.instrumentationArguments = null;
13948
13949        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
13950                "finished inst");
13951    }
13952
13953    public void finishInstrumentation(IApplicationThread target,
13954            int resultCode, Bundle results) {
13955        int userId = UserHandle.getCallingUserId();
13956        // Refuse possible leaked file descriptors
13957        if (results != null && results.hasFileDescriptors()) {
13958            throw new IllegalArgumentException("File descriptors passed in Intent");
13959        }
13960
13961        synchronized(this) {
13962            ProcessRecord app = getRecordForAppLocked(target);
13963            if (app == null) {
13964                Slog.w(TAG, "finishInstrumentation: no app for " + target);
13965                return;
13966            }
13967            final long origId = Binder.clearCallingIdentity();
13968            finishInstrumentationLocked(app, resultCode, results);
13969            Binder.restoreCallingIdentity(origId);
13970        }
13971    }
13972
13973    // =========================================================
13974    // CONFIGURATION
13975    // =========================================================
13976
13977    public ConfigurationInfo getDeviceConfigurationInfo() {
13978        ConfigurationInfo config = new ConfigurationInfo();
13979        synchronized (this) {
13980            config.reqTouchScreen = mConfiguration.touchscreen;
13981            config.reqKeyboardType = mConfiguration.keyboard;
13982            config.reqNavigation = mConfiguration.navigation;
13983            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
13984                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
13985                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
13986            }
13987            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
13988                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
13989                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
13990            }
13991            config.reqGlEsVersion = GL_ES_VERSION;
13992        }
13993        return config;
13994    }
13995
13996    ActivityStack getFocusedStack() {
13997        return mStackSupervisor.getFocusedStack();
13998    }
13999
14000    public Configuration getConfiguration() {
14001        Configuration ci;
14002        synchronized(this) {
14003            ci = new Configuration(mConfiguration);
14004        }
14005        return ci;
14006    }
14007
14008    public void updatePersistentConfiguration(Configuration values) {
14009        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14010                "updateConfiguration()");
14011        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14012                "updateConfiguration()");
14013        if (values == null) {
14014            throw new NullPointerException("Configuration must not be null");
14015        }
14016
14017        synchronized(this) {
14018            final long origId = Binder.clearCallingIdentity();
14019            updateConfigurationLocked(values, null, true, false);
14020            Binder.restoreCallingIdentity(origId);
14021        }
14022    }
14023
14024    public void updateConfiguration(Configuration values) {
14025        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14026                "updateConfiguration()");
14027
14028        synchronized(this) {
14029            if (values == null && mWindowManager != null) {
14030                // sentinel: fetch the current configuration from the window manager
14031                values = mWindowManager.computeNewConfiguration();
14032            }
14033
14034            if (mWindowManager != null) {
14035                mProcessList.applyDisplaySize(mWindowManager);
14036            }
14037
14038            final long origId = Binder.clearCallingIdentity();
14039            if (values != null) {
14040                Settings.System.clearConfiguration(values);
14041            }
14042            updateConfigurationLocked(values, null, false, false);
14043            Binder.restoreCallingIdentity(origId);
14044        }
14045    }
14046
14047    /**
14048     * Do either or both things: (1) change the current configuration, and (2)
14049     * make sure the given activity is running with the (now) current
14050     * configuration.  Returns true if the activity has been left running, or
14051     * false if <var>starting</var> is being destroyed to match the new
14052     * configuration.
14053     * @param persistent TODO
14054     */
14055    boolean updateConfigurationLocked(Configuration values,
14056            ActivityRecord starting, boolean persistent, boolean initLocale) {
14057        int changes = 0;
14058
14059        if (values != null) {
14060            Configuration newConfig = new Configuration(mConfiguration);
14061            changes = newConfig.updateFrom(values);
14062            if (changes != 0) {
14063                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14064                    Slog.i(TAG, "Updating configuration to: " + values);
14065                }
14066
14067                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14068
14069                if (values.locale != null && !initLocale) {
14070                    saveLocaleLocked(values.locale,
14071                                     !values.locale.equals(mConfiguration.locale),
14072                                     values.userSetLocale);
14073                }
14074
14075                mConfigurationSeq++;
14076                if (mConfigurationSeq <= 0) {
14077                    mConfigurationSeq = 1;
14078                }
14079                newConfig.seq = mConfigurationSeq;
14080                mConfiguration = newConfig;
14081                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14082
14083                final Configuration configCopy = new Configuration(mConfiguration);
14084
14085                // TODO: If our config changes, should we auto dismiss any currently
14086                // showing dialogs?
14087                mShowDialogs = shouldShowDialogs(newConfig);
14088
14089                AttributeCache ac = AttributeCache.instance();
14090                if (ac != null) {
14091                    ac.updateConfiguration(configCopy);
14092                }
14093
14094                // Make sure all resources in our process are updated
14095                // right now, so that anyone who is going to retrieve
14096                // resource values after we return will be sure to get
14097                // the new ones.  This is especially important during
14098                // boot, where the first config change needs to guarantee
14099                // all resources have that config before following boot
14100                // code is executed.
14101                mSystemThread.applyConfigurationToResources(configCopy);
14102
14103                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14104                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14105                    msg.obj = new Configuration(configCopy);
14106                    mHandler.sendMessage(msg);
14107                }
14108
14109                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14110                    ProcessRecord app = mLruProcesses.get(i);
14111                    try {
14112                        if (app.thread != null) {
14113                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14114                                    + app.processName + " new config " + mConfiguration);
14115                            app.thread.scheduleConfigurationChanged(configCopy);
14116                        }
14117                    } catch (Exception e) {
14118                    }
14119                }
14120                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14121                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14122                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14123                        | Intent.FLAG_RECEIVER_FOREGROUND);
14124                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14125                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14126                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14127                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14128                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14129                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14130                    broadcastIntentLocked(null, null, intent,
14131                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14132                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14133                }
14134            }
14135        }
14136
14137        boolean kept = true;
14138        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14139        // mainStack is null during startup.
14140        if (mainStack != null) {
14141            if (changes != 0 && starting == null) {
14142                // If the configuration changed, and the caller is not already
14143                // in the process of starting an activity, then find the top
14144                // activity to check if its configuration needs to change.
14145                starting = mainStack.topRunningActivityLocked(null);
14146            }
14147
14148            if (starting != null) {
14149                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14150                // And we need to make sure at this point that all other activities
14151                // are made visible with the correct configuration.
14152                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14153            }
14154        }
14155
14156        if (values != null && mWindowManager != null) {
14157            mWindowManager.setNewConfiguration(mConfiguration);
14158        }
14159
14160        return kept;
14161    }
14162
14163    /**
14164     * Decide based on the configuration whether we should shouw the ANR,
14165     * crash, etc dialogs.  The idea is that if there is no affordnace to
14166     * press the on-screen buttons, we shouldn't show the dialog.
14167     *
14168     * A thought: SystemUI might also want to get told about this, the Power
14169     * dialog / global actions also might want different behaviors.
14170     */
14171    private static final boolean shouldShowDialogs(Configuration config) {
14172        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14173                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14174    }
14175
14176    /**
14177     * Save the locale.  You must be inside a synchronized (this) block.
14178     */
14179    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14180        if(isDiff) {
14181            SystemProperties.set("user.language", l.getLanguage());
14182            SystemProperties.set("user.region", l.getCountry());
14183        }
14184
14185        if(isPersist) {
14186            SystemProperties.set("persist.sys.language", l.getLanguage());
14187            SystemProperties.set("persist.sys.country", l.getCountry());
14188            SystemProperties.set("persist.sys.localevar", l.getVariant());
14189        }
14190    }
14191
14192    @Override
14193    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14194        ActivityRecord srec = ActivityRecord.forToken(token);
14195        return srec != null && srec.task.affinity != null &&
14196                srec.task.affinity.equals(destAffinity);
14197    }
14198
14199    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14200            Intent resultData) {
14201
14202        synchronized (this) {
14203            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14204            if (stack != null) {
14205                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14206            }
14207            return false;
14208        }
14209    }
14210
14211    public int getLaunchedFromUid(IBinder activityToken) {
14212        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14213        if (srec == null) {
14214            return -1;
14215        }
14216        return srec.launchedFromUid;
14217    }
14218
14219    public String getLaunchedFromPackage(IBinder activityToken) {
14220        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14221        if (srec == null) {
14222            return null;
14223        }
14224        return srec.launchedFromPackage;
14225    }
14226
14227    // =========================================================
14228    // LIFETIME MANAGEMENT
14229    // =========================================================
14230
14231    // Returns which broadcast queue the app is the current [or imminent] receiver
14232    // on, or 'null' if the app is not an active broadcast recipient.
14233    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14234        BroadcastRecord r = app.curReceiver;
14235        if (r != null) {
14236            return r.queue;
14237        }
14238
14239        // It's not the current receiver, but it might be starting up to become one
14240        synchronized (this) {
14241            for (BroadcastQueue queue : mBroadcastQueues) {
14242                r = queue.mPendingBroadcast;
14243                if (r != null && r.curApp == app) {
14244                    // found it; report which queue it's in
14245                    return queue;
14246                }
14247            }
14248        }
14249
14250        return null;
14251    }
14252
14253    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14254            boolean doingAll, long now) {
14255        if (mAdjSeq == app.adjSeq) {
14256            // This adjustment has already been computed.
14257            return app.curRawAdj;
14258        }
14259
14260        if (app.thread == null) {
14261            app.adjSeq = mAdjSeq;
14262            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14263            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14264            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14265        }
14266
14267        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14268        app.adjSource = null;
14269        app.adjTarget = null;
14270        app.empty = false;
14271        app.cached = false;
14272
14273        final int activitiesSize = app.activities.size();
14274
14275        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14276            // The max adjustment doesn't allow this app to be anything
14277            // below foreground, so it is not worth doing work for it.
14278            app.adjType = "fixed";
14279            app.adjSeq = mAdjSeq;
14280            app.curRawAdj = app.maxAdj;
14281            app.foregroundActivities = false;
14282            app.keeping = true;
14283            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14284            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14285            // System process can do UI, and when they do we want to have
14286            // them trim their memory after the user leaves the UI.  To
14287            // facilitate this, here we need to determine whether or not it
14288            // is currently showing UI.
14289            app.systemNoUi = true;
14290            if (app == TOP_APP) {
14291                app.systemNoUi = false;
14292            } else if (activitiesSize > 0) {
14293                for (int j = 0; j < activitiesSize; j++) {
14294                    final ActivityRecord r = app.activities.get(j);
14295                    if (r.visible) {
14296                        app.systemNoUi = false;
14297                    }
14298                }
14299            }
14300            if (!app.systemNoUi) {
14301                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14302            }
14303            return (app.curAdj=app.maxAdj);
14304        }
14305
14306        app.keeping = false;
14307        app.systemNoUi = false;
14308
14309        // Determine the importance of the process, starting with most
14310        // important to least, and assign an appropriate OOM adjustment.
14311        int adj;
14312        int schedGroup;
14313        int procState;
14314        boolean foregroundActivities = false;
14315        boolean interesting = false;
14316        BroadcastQueue queue;
14317        if (app == TOP_APP) {
14318            // The last app on the list is the foreground app.
14319            adj = ProcessList.FOREGROUND_APP_ADJ;
14320            schedGroup = Process.THREAD_GROUP_DEFAULT;
14321            app.adjType = "top-activity";
14322            foregroundActivities = true;
14323            interesting = true;
14324            procState = ActivityManager.PROCESS_STATE_TOP;
14325        } else if (app.instrumentationClass != null) {
14326            // Don't want to kill running instrumentation.
14327            adj = ProcessList.FOREGROUND_APP_ADJ;
14328            schedGroup = Process.THREAD_GROUP_DEFAULT;
14329            app.adjType = "instrumentation";
14330            interesting = true;
14331            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14332        } else if ((queue = isReceivingBroadcast(app)) != null) {
14333            // An app that is currently receiving a broadcast also
14334            // counts as being in the foreground for OOM killer purposes.
14335            // It's placed in a sched group based on the nature of the
14336            // broadcast as reflected by which queue it's active in.
14337            adj = ProcessList.FOREGROUND_APP_ADJ;
14338            schedGroup = (queue == mFgBroadcastQueue)
14339                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14340            app.adjType = "broadcast";
14341            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14342        } else if (app.executingServices.size() > 0) {
14343            // An app that is currently executing a service callback also
14344            // counts as being in the foreground.
14345            adj = ProcessList.FOREGROUND_APP_ADJ;
14346            schedGroup = app.execServicesFg ?
14347                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14348            app.adjType = "exec-service";
14349            procState = ActivityManager.PROCESS_STATE_SERVICE;
14350            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14351        } else {
14352            // As far as we know the process is empty.  We may change our mind later.
14353            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14354            // At this point we don't actually know the adjustment.  Use the cached adj
14355            // value that the caller wants us to.
14356            adj = cachedAdj;
14357            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14358            app.cached = true;
14359            app.empty = true;
14360            app.adjType = "cch-empty";
14361        }
14362
14363        // Examine all activities if not already foreground.
14364        if (!foregroundActivities && activitiesSize > 0) {
14365            for (int j = 0; j < activitiesSize; j++) {
14366                final ActivityRecord r = app.activities.get(j);
14367                if (r.app != app) {
14368                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14369                            + app + "?!?");
14370                    continue;
14371                }
14372                if (r.visible) {
14373                    // App has a visible activity; only upgrade adjustment.
14374                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14375                        adj = ProcessList.VISIBLE_APP_ADJ;
14376                        app.adjType = "visible";
14377                    }
14378                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14379                        procState = ActivityManager.PROCESS_STATE_TOP;
14380                    }
14381                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14382                    app.cached = false;
14383                    app.empty = false;
14384                    foregroundActivities = true;
14385                    break;
14386                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14387                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14388                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14389                        app.adjType = "pausing";
14390                    }
14391                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14392                        procState = ActivityManager.PROCESS_STATE_TOP;
14393                    }
14394                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14395                    app.cached = false;
14396                    app.empty = false;
14397                    foregroundActivities = true;
14398                } else if (r.state == ActivityState.STOPPING) {
14399                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14400                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14401                        app.adjType = "stopping";
14402                    }
14403                    // For the process state, we will at this point consider the
14404                    // process to be cached.  It will be cached either as an activity
14405                    // or empty depending on whether the activity is finishing.  We do
14406                    // this so that we can treat the process as cached for purposes of
14407                    // memory trimming (determing current memory level, trim command to
14408                    // send to process) since there can be an arbitrary number of stopping
14409                    // processes and they should soon all go into the cached state.
14410                    if (!r.finishing) {
14411                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14412                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14413                        }
14414                    }
14415                    app.cached = false;
14416                    app.empty = false;
14417                    foregroundActivities = true;
14418                } else {
14419                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14420                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14421                        app.adjType = "cch-act";
14422                    }
14423                }
14424            }
14425        }
14426
14427        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14428            if (app.foregroundServices) {
14429                // The user is aware of this app, so make it visible.
14430                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14431                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14432                app.cached = false;
14433                app.adjType = "fg-service";
14434                schedGroup = Process.THREAD_GROUP_DEFAULT;
14435            } else if (app.forcingToForeground != null) {
14436                // The user is aware of this app, so make it visible.
14437                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14438                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14439                app.cached = false;
14440                app.adjType = "force-fg";
14441                app.adjSource = app.forcingToForeground;
14442                schedGroup = Process.THREAD_GROUP_DEFAULT;
14443            }
14444        }
14445
14446        if (app.foregroundServices) {
14447            interesting = true;
14448        }
14449
14450        if (app == mHeavyWeightProcess) {
14451            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14452                // We don't want to kill the current heavy-weight process.
14453                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14454                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14455                app.cached = false;
14456                app.adjType = "heavy";
14457            }
14458            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14459                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14460            }
14461        }
14462
14463        if (app == mHomeProcess) {
14464            if (adj > ProcessList.HOME_APP_ADJ) {
14465                // This process is hosting what we currently consider to be the
14466                // home app, so we don't want to let it go into the background.
14467                adj = ProcessList.HOME_APP_ADJ;
14468                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14469                app.cached = false;
14470                app.adjType = "home";
14471            }
14472            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14473                procState = ActivityManager.PROCESS_STATE_HOME;
14474            }
14475        }
14476
14477        if (app == mPreviousProcess && app.activities.size() > 0) {
14478            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14479                // This was the previous process that showed UI to the user.
14480                // We want to try to keep it around more aggressively, to give
14481                // a good experience around switching between two apps.
14482                adj = ProcessList.PREVIOUS_APP_ADJ;
14483                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14484                app.cached = false;
14485                app.adjType = "previous";
14486            }
14487            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14488                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14489            }
14490        }
14491
14492        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14493                + " reason=" + app.adjType);
14494
14495        // By default, we use the computed adjustment.  It may be changed if
14496        // there are applications dependent on our services or providers, but
14497        // this gives us a baseline and makes sure we don't get into an
14498        // infinite recursion.
14499        app.adjSeq = mAdjSeq;
14500        app.curRawAdj = adj;
14501        app.hasStartedServices = false;
14502
14503        if (mBackupTarget != null && app == mBackupTarget.app) {
14504            // If possible we want to avoid killing apps while they're being backed up
14505            if (adj > ProcessList.BACKUP_APP_ADJ) {
14506                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14507                adj = ProcessList.BACKUP_APP_ADJ;
14508                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14509                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14510                }
14511                app.adjType = "backup";
14512                app.cached = false;
14513            }
14514            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14515                procState = ActivityManager.PROCESS_STATE_BACKUP;
14516            }
14517        }
14518
14519        boolean mayBeTop = false;
14520
14521        for (int is = app.services.size()-1;
14522                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14523                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14524                        || procState > ActivityManager.PROCESS_STATE_TOP);
14525                is--) {
14526            ServiceRecord s = app.services.valueAt(is);
14527            if (s.startRequested) {
14528                app.hasStartedServices = true;
14529                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14530                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14531                }
14532                if (app.hasShownUi && app != mHomeProcess) {
14533                    // If this process has shown some UI, let it immediately
14534                    // go to the LRU list because it may be pretty heavy with
14535                    // UI stuff.  We'll tag it with a label just to help
14536                    // debug and understand what is going on.
14537                    if (adj > ProcessList.SERVICE_ADJ) {
14538                        app.adjType = "cch-started-ui-services";
14539                    }
14540                } else {
14541                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14542                        // This service has seen some activity within
14543                        // recent memory, so we will keep its process ahead
14544                        // of the background processes.
14545                        if (adj > ProcessList.SERVICE_ADJ) {
14546                            adj = ProcessList.SERVICE_ADJ;
14547                            app.adjType = "started-services";
14548                            app.cached = false;
14549                        }
14550                    }
14551                    // If we have let the service slide into the background
14552                    // state, still have some text describing what it is doing
14553                    // even though the service no longer has an impact.
14554                    if (adj > ProcessList.SERVICE_ADJ) {
14555                        app.adjType = "cch-started-services";
14556                    }
14557                }
14558                // Don't kill this process because it is doing work; it
14559                // has said it is doing work.
14560                app.keeping = true;
14561            }
14562            for (int conni = s.connections.size()-1;
14563                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14564                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14565                            || procState > ActivityManager.PROCESS_STATE_TOP);
14566                    conni--) {
14567                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14568                for (int i = 0;
14569                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14570                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14571                                || procState > ActivityManager.PROCESS_STATE_TOP);
14572                        i++) {
14573                    // XXX should compute this based on the max of
14574                    // all connected clients.
14575                    ConnectionRecord cr = clist.get(i);
14576                    if (cr.binding.client == app) {
14577                        // Binding to ourself is not interesting.
14578                        continue;
14579                    }
14580                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14581                        ProcessRecord client = cr.binding.client;
14582                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14583                                TOP_APP, doingAll, now);
14584                        int clientProcState = client.curProcState;
14585                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14586                            // If the other app is cached for any reason, for purposes here
14587                            // we are going to consider it empty.  The specific cached state
14588                            // doesn't propagate except under certain conditions.
14589                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14590                        }
14591                        String adjType = null;
14592                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14593                            // Not doing bind OOM management, so treat
14594                            // this guy more like a started service.
14595                            if (app.hasShownUi && app != mHomeProcess) {
14596                                // If this process has shown some UI, let it immediately
14597                                // go to the LRU list because it may be pretty heavy with
14598                                // UI stuff.  We'll tag it with a label just to help
14599                                // debug and understand what is going on.
14600                                if (adj > clientAdj) {
14601                                    adjType = "cch-bound-ui-services";
14602                                }
14603                                app.cached = false;
14604                                clientAdj = adj;
14605                                clientProcState = procState;
14606                            } else {
14607                                if (now >= (s.lastActivity
14608                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14609                                    // This service has not seen activity within
14610                                    // recent memory, so allow it to drop to the
14611                                    // LRU list if there is no other reason to keep
14612                                    // it around.  We'll also tag it with a label just
14613                                    // to help debug and undertand what is going on.
14614                                    if (adj > clientAdj) {
14615                                        adjType = "cch-bound-services";
14616                                    }
14617                                    clientAdj = adj;
14618                                }
14619                            }
14620                        }
14621                        if (adj > clientAdj) {
14622                            // If this process has recently shown UI, and
14623                            // the process that is binding to it is less
14624                            // important than being visible, then we don't
14625                            // care about the binding as much as we care
14626                            // about letting this process get into the LRU
14627                            // list to be killed and restarted if needed for
14628                            // memory.
14629                            if (app.hasShownUi && app != mHomeProcess
14630                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14631                                adjType = "cch-bound-ui-services";
14632                            } else {
14633                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14634                                        |Context.BIND_IMPORTANT)) != 0) {
14635                                    adj = clientAdj;
14636                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14637                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14638                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14639                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14640                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
14641                                    adj = clientAdj;
14642                                } else {
14643                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14644                                        adj = ProcessList.VISIBLE_APP_ADJ;
14645                                    }
14646                                }
14647                                if (!client.cached) {
14648                                    app.cached = false;
14649                                }
14650                                if (client.keeping) {
14651                                    app.keeping = true;
14652                                }
14653                                adjType = "service";
14654                            }
14655                        }
14656                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14657                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14658                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14659                            }
14660                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14661                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14662                                    // Special handling of clients who are in the top state.
14663                                    // We *may* want to consider this process to be in the
14664                                    // top state as well, but only if there is not another
14665                                    // reason for it to be running.  Being on the top is a
14666                                    // special state, meaning you are specifically running
14667                                    // for the current top app.  If the process is already
14668                                    // running in the background for some other reason, it
14669                                    // is more important to continue considering it to be
14670                                    // in the background state.
14671                                    mayBeTop = true;
14672                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14673                                } else {
14674                                    // Special handling for above-top states (persistent
14675                                    // processes).  These should not bring the current process
14676                                    // into the top state, since they are not on top.  Instead
14677                                    // give them the best state after that.
14678                                    clientProcState =
14679                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14680                                }
14681                            }
14682                        } else {
14683                            if (clientProcState <
14684                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14685                                clientProcState =
14686                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14687                            }
14688                        }
14689                        if (procState > clientProcState) {
14690                            procState = clientProcState;
14691                        }
14692                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
14693                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
14694                            app.pendingUiClean = true;
14695                        }
14696                        if (adjType != null) {
14697                            app.adjType = adjType;
14698                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14699                                    .REASON_SERVICE_IN_USE;
14700                            app.adjSource = cr.binding.client;
14701                            app.adjSourceOom = clientAdj;
14702                            app.adjTarget = s.name;
14703                        }
14704                    }
14705                    final ActivityRecord a = cr.activity;
14706                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
14707                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
14708                                (a.visible || a.state == ActivityState.RESUMED
14709                                 || a.state == ActivityState.PAUSING)) {
14710                            adj = ProcessList.FOREGROUND_APP_ADJ;
14711                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14712                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14713                            }
14714                            app.cached = false;
14715                            app.adjType = "service";
14716                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14717                                    .REASON_SERVICE_IN_USE;
14718                            app.adjSource = a;
14719                            app.adjSourceOom = adj;
14720                            app.adjTarget = s.name;
14721                        }
14722                    }
14723                }
14724            }
14725        }
14726
14727        for (int provi = app.pubProviders.size()-1;
14728                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14729                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14730                        || procState > ActivityManager.PROCESS_STATE_TOP);
14731                provi--) {
14732            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
14733            for (int i = cpr.connections.size()-1;
14734                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14735                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14736                            || procState > ActivityManager.PROCESS_STATE_TOP);
14737                    i--) {
14738                ContentProviderConnection conn = cpr.connections.get(i);
14739                ProcessRecord client = conn.client;
14740                if (client == app) {
14741                    // Being our own client is not interesting.
14742                    continue;
14743                }
14744                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
14745                int clientProcState = client.curProcState;
14746                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14747                    // If the other app is cached for any reason, for purposes here
14748                    // we are going to consider it empty.
14749                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14750                }
14751                if (adj > clientAdj) {
14752                    if (app.hasShownUi && app != mHomeProcess
14753                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14754                        app.adjType = "cch-ui-provider";
14755                    } else {
14756                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
14757                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
14758                        app.adjType = "provider";
14759                    }
14760                    app.cached &= client.cached;
14761                    app.keeping |= client.keeping;
14762                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14763                            .REASON_PROVIDER_IN_USE;
14764                    app.adjSource = client;
14765                    app.adjSourceOom = clientAdj;
14766                    app.adjTarget = cpr.name;
14767                }
14768                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14769                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14770                        // Special handling of clients who are in the top state.
14771                        // We *may* want to consider this process to be in the
14772                        // top state as well, but only if there is not another
14773                        // reason for it to be running.  Being on the top is a
14774                        // special state, meaning you are specifically running
14775                        // for the current top app.  If the process is already
14776                        // running in the background for some other reason, it
14777                        // is more important to continue considering it to be
14778                        // in the background state.
14779                        mayBeTop = true;
14780                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14781                    } else {
14782                        // Special handling for above-top states (persistent
14783                        // processes).  These should not bring the current process
14784                        // into the top state, since they are not on top.  Instead
14785                        // give them the best state after that.
14786                        clientProcState =
14787                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14788                    }
14789                }
14790                if (procState > clientProcState) {
14791                    procState = clientProcState;
14792                }
14793                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14794                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14795                }
14796            }
14797            // If the provider has external (non-framework) process
14798            // dependencies, ensure that its adjustment is at least
14799            // FOREGROUND_APP_ADJ.
14800            if (cpr.hasExternalProcessHandles()) {
14801                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
14802                    adj = ProcessList.FOREGROUND_APP_ADJ;
14803                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14804                    app.cached = false;
14805                    app.keeping = true;
14806                    app.adjType = "provider";
14807                    app.adjTarget = cpr.name;
14808                }
14809                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
14810                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14811                }
14812            }
14813        }
14814
14815        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
14816            // A client of one of our services or providers is in the top state.  We
14817            // *may* want to be in the top state, but not if we are already running in
14818            // the background for some other reason.  For the decision here, we are going
14819            // to pick out a few specific states that we want to remain in when a client
14820            // is top (states that tend to be longer-term) and otherwise allow it to go
14821            // to the top state.
14822            switch (procState) {
14823                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
14824                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
14825                case ActivityManager.PROCESS_STATE_SERVICE:
14826                    // These all are longer-term states, so pull them up to the top
14827                    // of the background states, but not all the way to the top state.
14828                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14829                    break;
14830                default:
14831                    // Otherwise, top is a better choice, so take it.
14832                    procState = ActivityManager.PROCESS_STATE_TOP;
14833                    break;
14834            }
14835        }
14836
14837        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) {
14838            // This is a cached process, but with client activities.  Mark it so.
14839            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
14840            app.adjType = "cch-client-act";
14841        }
14842
14843        if (adj == ProcessList.SERVICE_ADJ) {
14844            if (doingAll) {
14845                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
14846                mNewNumServiceProcs++;
14847                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
14848                if (!app.serviceb) {
14849                    // This service isn't far enough down on the LRU list to
14850                    // normally be a B service, but if we are low on RAM and it
14851                    // is large we want to force it down since we would prefer to
14852                    // keep launcher over it.
14853                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
14854                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
14855                        app.serviceHighRam = true;
14856                        app.serviceb = true;
14857                        //Slog.i(TAG, "ADJ " + app + " high ram!");
14858                    } else {
14859                        mNewNumAServiceProcs++;
14860                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
14861                    }
14862                } else {
14863                    app.serviceHighRam = false;
14864                }
14865            }
14866            if (app.serviceb) {
14867                adj = ProcessList.SERVICE_B_ADJ;
14868            }
14869        }
14870
14871        app.curRawAdj = adj;
14872
14873        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
14874        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
14875        if (adj > app.maxAdj) {
14876            adj = app.maxAdj;
14877            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
14878                schedGroup = Process.THREAD_GROUP_DEFAULT;
14879            }
14880        }
14881        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
14882            app.keeping = true;
14883        }
14884
14885        // Do final modification to adj.  Everything we do between here and applying
14886        // the final setAdj must be done in this function, because we will also use
14887        // it when computing the final cached adj later.  Note that we don't need to
14888        // worry about this for max adj above, since max adj will always be used to
14889        // keep it out of the cached vaues.
14890        adj = app.modifyRawOomAdj(adj);
14891
14892        app.curProcState = procState;
14893
14894        int importance = app.memImportance;
14895        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
14896            app.curAdj = adj;
14897            app.curSchedGroup = schedGroup;
14898            if (!interesting) {
14899                // For this reporting, if there is not something explicitly
14900                // interesting in this process then we will push it to the
14901                // background importance.
14902                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14903            } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
14904                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14905            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
14906                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
14907            } else if (adj >= ProcessList.HOME_APP_ADJ) {
14908                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14909            } else if (adj >= ProcessList.SERVICE_ADJ) {
14910                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
14911            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14912                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
14913            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
14914                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
14915            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
14916                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
14917            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
14918                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
14919            } else {
14920                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
14921            }
14922        }
14923
14924        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
14925        if (foregroundActivities != app.foregroundActivities) {
14926            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
14927        }
14928        if (changes != 0) {
14929            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
14930            app.memImportance = importance;
14931            app.foregroundActivities = foregroundActivities;
14932            int i = mPendingProcessChanges.size()-1;
14933            ProcessChangeItem item = null;
14934            while (i >= 0) {
14935                item = mPendingProcessChanges.get(i);
14936                if (item.pid == app.pid) {
14937                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
14938                    break;
14939                }
14940                i--;
14941            }
14942            if (i < 0) {
14943                // No existing item in pending changes; need a new one.
14944                final int NA = mAvailProcessChanges.size();
14945                if (NA > 0) {
14946                    item = mAvailProcessChanges.remove(NA-1);
14947                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
14948                } else {
14949                    item = new ProcessChangeItem();
14950                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
14951                }
14952                item.changes = 0;
14953                item.pid = app.pid;
14954                item.uid = app.info.uid;
14955                if (mPendingProcessChanges.size() == 0) {
14956                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
14957                            "*** Enqueueing dispatch processes changed!");
14958                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
14959                }
14960                mPendingProcessChanges.add(item);
14961            }
14962            item.changes |= changes;
14963            item.importance = importance;
14964            item.foregroundActivities = foregroundActivities;
14965            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
14966                    + Integer.toHexString(System.identityHashCode(item))
14967                    + " " + app.toShortString() + ": changes=" + item.changes
14968                    + " importance=" + item.importance
14969                    + " foreground=" + item.foregroundActivities
14970                    + " type=" + app.adjType + " source=" + app.adjSource
14971                    + " target=" + app.adjTarget);
14972        }
14973
14974        return app.curRawAdj;
14975    }
14976
14977    /**
14978     * Schedule PSS collection of a process.
14979     */
14980    void requestPssLocked(ProcessRecord proc, int procState) {
14981        if (mPendingPssProcesses.contains(proc)) {
14982            return;
14983        }
14984        if (mPendingPssProcesses.size() == 0) {
14985            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
14986        }
14987        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
14988        proc.pssProcState = procState;
14989        mPendingPssProcesses.add(proc);
14990    }
14991
14992    /**
14993     * Schedule PSS collection of all processes.
14994     */
14995    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
14996        if (!always) {
14997            if (now < (mLastFullPssTime +
14998                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
14999                return;
15000            }
15001        }
15002        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15003        mLastFullPssTime = now;
15004        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15005        mPendingPssProcesses.clear();
15006        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15007            ProcessRecord app = mLruProcesses.get(i);
15008            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15009                app.pssProcState = app.setProcState;
15010                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15011                        mSleeping, now);
15012                mPendingPssProcesses.add(app);
15013            }
15014        }
15015        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15016    }
15017
15018    /**
15019     * Ask a given process to GC right now.
15020     */
15021    final void performAppGcLocked(ProcessRecord app) {
15022        try {
15023            app.lastRequestedGc = SystemClock.uptimeMillis();
15024            if (app.thread != null) {
15025                if (app.reportLowMemory) {
15026                    app.reportLowMemory = false;
15027                    app.thread.scheduleLowMemory();
15028                } else {
15029                    app.thread.processInBackground();
15030                }
15031            }
15032        } catch (Exception e) {
15033            // whatever.
15034        }
15035    }
15036
15037    /**
15038     * Returns true if things are idle enough to perform GCs.
15039     */
15040    private final boolean canGcNowLocked() {
15041        boolean processingBroadcasts = false;
15042        for (BroadcastQueue q : mBroadcastQueues) {
15043            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15044                processingBroadcasts = true;
15045            }
15046        }
15047        return !processingBroadcasts
15048                && (mSleeping || mStackSupervisor.allResumedActivitiesIdle());
15049    }
15050
15051    /**
15052     * Perform GCs on all processes that are waiting for it, but only
15053     * if things are idle.
15054     */
15055    final void performAppGcsLocked() {
15056        final int N = mProcessesToGc.size();
15057        if (N <= 0) {
15058            return;
15059        }
15060        if (canGcNowLocked()) {
15061            while (mProcessesToGc.size() > 0) {
15062                ProcessRecord proc = mProcessesToGc.remove(0);
15063                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15064                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15065                            <= SystemClock.uptimeMillis()) {
15066                        // To avoid spamming the system, we will GC processes one
15067                        // at a time, waiting a few seconds between each.
15068                        performAppGcLocked(proc);
15069                        scheduleAppGcsLocked();
15070                        return;
15071                    } else {
15072                        // It hasn't been long enough since we last GCed this
15073                        // process...  put it in the list to wait for its time.
15074                        addProcessToGcListLocked(proc);
15075                        break;
15076                    }
15077                }
15078            }
15079
15080            scheduleAppGcsLocked();
15081        }
15082    }
15083
15084    /**
15085     * If all looks good, perform GCs on all processes waiting for them.
15086     */
15087    final void performAppGcsIfAppropriateLocked() {
15088        if (canGcNowLocked()) {
15089            performAppGcsLocked();
15090            return;
15091        }
15092        // Still not idle, wait some more.
15093        scheduleAppGcsLocked();
15094    }
15095
15096    /**
15097     * Schedule the execution of all pending app GCs.
15098     */
15099    final void scheduleAppGcsLocked() {
15100        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15101
15102        if (mProcessesToGc.size() > 0) {
15103            // Schedule a GC for the time to the next process.
15104            ProcessRecord proc = mProcessesToGc.get(0);
15105            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15106
15107            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15108            long now = SystemClock.uptimeMillis();
15109            if (when < (now+GC_TIMEOUT)) {
15110                when = now + GC_TIMEOUT;
15111            }
15112            mHandler.sendMessageAtTime(msg, when);
15113        }
15114    }
15115
15116    /**
15117     * Add a process to the array of processes waiting to be GCed.  Keeps the
15118     * list in sorted order by the last GC time.  The process can't already be
15119     * on the list.
15120     */
15121    final void addProcessToGcListLocked(ProcessRecord proc) {
15122        boolean added = false;
15123        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15124            if (mProcessesToGc.get(i).lastRequestedGc <
15125                    proc.lastRequestedGc) {
15126                added = true;
15127                mProcessesToGc.add(i+1, proc);
15128                break;
15129            }
15130        }
15131        if (!added) {
15132            mProcessesToGc.add(0, proc);
15133        }
15134    }
15135
15136    /**
15137     * Set up to ask a process to GC itself.  This will either do it
15138     * immediately, or put it on the list of processes to gc the next
15139     * time things are idle.
15140     */
15141    final void scheduleAppGcLocked(ProcessRecord app) {
15142        long now = SystemClock.uptimeMillis();
15143        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15144            return;
15145        }
15146        if (!mProcessesToGc.contains(app)) {
15147            addProcessToGcListLocked(app);
15148            scheduleAppGcsLocked();
15149        }
15150    }
15151
15152    final void checkExcessivePowerUsageLocked(boolean doKills) {
15153        updateCpuStatsNow();
15154
15155        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15156        boolean doWakeKills = doKills;
15157        boolean doCpuKills = doKills;
15158        if (mLastPowerCheckRealtime == 0) {
15159            doWakeKills = false;
15160        }
15161        if (mLastPowerCheckUptime == 0) {
15162            doCpuKills = false;
15163        }
15164        if (stats.isScreenOn()) {
15165            doWakeKills = false;
15166        }
15167        final long curRealtime = SystemClock.elapsedRealtime();
15168        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15169        final long curUptime = SystemClock.uptimeMillis();
15170        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15171        mLastPowerCheckRealtime = curRealtime;
15172        mLastPowerCheckUptime = curUptime;
15173        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15174            doWakeKills = false;
15175        }
15176        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15177            doCpuKills = false;
15178        }
15179        int i = mLruProcesses.size();
15180        while (i > 0) {
15181            i--;
15182            ProcessRecord app = mLruProcesses.get(i);
15183            if (!app.keeping) {
15184                long wtime;
15185                synchronized (stats) {
15186                    wtime = stats.getProcessWakeTime(app.info.uid,
15187                            app.pid, curRealtime);
15188                }
15189                long wtimeUsed = wtime - app.lastWakeTime;
15190                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15191                if (DEBUG_POWER) {
15192                    StringBuilder sb = new StringBuilder(128);
15193                    sb.append("Wake for ");
15194                    app.toShortString(sb);
15195                    sb.append(": over ");
15196                    TimeUtils.formatDuration(realtimeSince, sb);
15197                    sb.append(" used ");
15198                    TimeUtils.formatDuration(wtimeUsed, sb);
15199                    sb.append(" (");
15200                    sb.append((wtimeUsed*100)/realtimeSince);
15201                    sb.append("%)");
15202                    Slog.i(TAG, sb.toString());
15203                    sb.setLength(0);
15204                    sb.append("CPU for ");
15205                    app.toShortString(sb);
15206                    sb.append(": over ");
15207                    TimeUtils.formatDuration(uptimeSince, sb);
15208                    sb.append(" used ");
15209                    TimeUtils.formatDuration(cputimeUsed, sb);
15210                    sb.append(" (");
15211                    sb.append((cputimeUsed*100)/uptimeSince);
15212                    sb.append("%)");
15213                    Slog.i(TAG, sb.toString());
15214                }
15215                // If a process has held a wake lock for more
15216                // than 50% of the time during this period,
15217                // that sounds bad.  Kill!
15218                if (doWakeKills && realtimeSince > 0
15219                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15220                    synchronized (stats) {
15221                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15222                                realtimeSince, wtimeUsed);
15223                    }
15224                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15225                            + " during " + realtimeSince);
15226                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15227                } else if (doCpuKills && uptimeSince > 0
15228                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15229                    synchronized (stats) {
15230                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15231                                uptimeSince, cputimeUsed);
15232                    }
15233                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15234                            + " during " + uptimeSince);
15235                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15236                } else {
15237                    app.lastWakeTime = wtime;
15238                    app.lastCpuTime = app.curCpuTime;
15239                }
15240            }
15241        }
15242    }
15243
15244    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15245            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15246        boolean success = true;
15247
15248        if (app.curRawAdj != app.setRawAdj) {
15249            if (wasKeeping && !app.keeping) {
15250                // This app is no longer something we want to keep.  Note
15251                // its current wake lock time to later know to kill it if
15252                // it is not behaving well.
15253                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15254                synchronized (stats) {
15255                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15256                            app.pid, SystemClock.elapsedRealtime());
15257                }
15258                app.lastCpuTime = app.curCpuTime;
15259            }
15260
15261            app.setRawAdj = app.curRawAdj;
15262        }
15263
15264        if (app.curAdj != app.setAdj) {
15265            ProcessList.setOomAdj(app.pid, app.curAdj);
15266            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15267                TAG, "Set " + app.pid + " " + app.processName +
15268                " adj " + app.curAdj + ": " + app.adjType);
15269            app.setAdj = app.curAdj;
15270        }
15271
15272        if (app.setSchedGroup != app.curSchedGroup) {
15273            app.setSchedGroup = app.curSchedGroup;
15274            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15275                    "Setting process group of " + app.processName
15276                    + " to " + app.curSchedGroup);
15277            if (app.waitingToKill != null &&
15278                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15279                killUnneededProcessLocked(app, app.waitingToKill);
15280                success = false;
15281            } else {
15282                if (true) {
15283                    long oldId = Binder.clearCallingIdentity();
15284                    try {
15285                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15286                    } catch (Exception e) {
15287                        Slog.w(TAG, "Failed setting process group of " + app.pid
15288                                + " to " + app.curSchedGroup);
15289                        e.printStackTrace();
15290                    } finally {
15291                        Binder.restoreCallingIdentity(oldId);
15292                    }
15293                } else {
15294                    if (app.thread != null) {
15295                        try {
15296                            app.thread.setSchedulingGroup(app.curSchedGroup);
15297                        } catch (RemoteException e) {
15298                        }
15299                    }
15300                }
15301                Process.setSwappiness(app.pid,
15302                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15303            }
15304        }
15305        if (app.repProcState != app.curProcState) {
15306            app.repProcState = app.curProcState;
15307            if (!reportingProcessState && app.thread != null) {
15308                try {
15309                    if (false) {
15310                        //RuntimeException h = new RuntimeException("here");
15311                        Slog.i(TAG, "Sending new process state " + app.repProcState
15312                                + " to " + app /*, h*/);
15313                    }
15314                    app.thread.setProcessState(app.repProcState);
15315                } catch (RemoteException e) {
15316                }
15317            }
15318        }
15319        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15320                app.setProcState)) {
15321            app.lastStateTime = now;
15322            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15323                    mSleeping, now);
15324            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15325                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15326                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15327                    + (app.nextPssTime-now) + ": " + app);
15328        } else {
15329            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15330                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15331                requestPssLocked(app, app.setProcState);
15332                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15333                        mSleeping, now);
15334            } else if (false && DEBUG_PSS) {
15335                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15336            }
15337        }
15338        if (app.setProcState != app.curProcState) {
15339            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15340                    "Proc state change of " + app.processName
15341                    + " to " + app.curProcState);
15342            app.setProcState = app.curProcState;
15343            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15344                app.notCachedSinceIdle = false;
15345            }
15346            if (!doingAll) {
15347                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15348            } else {
15349                app.procStateChanged = true;
15350            }
15351        }
15352        return success;
15353    }
15354
15355    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15356        if (proc.thread != null && proc.baseProcessTracker != null) {
15357            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15358        }
15359    }
15360
15361    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15362            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15363        if (app.thread == null) {
15364            return false;
15365        }
15366
15367        final boolean wasKeeping = app.keeping;
15368
15369        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15370
15371        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll,
15372                reportingProcessState, now);
15373    }
15374
15375    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15376            boolean oomAdj) {
15377        if (isForeground != proc.foregroundServices) {
15378            proc.foregroundServices = isForeground;
15379            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15380                    proc.info.uid);
15381            if (isForeground) {
15382                if (curProcs == null) {
15383                    curProcs = new ArrayList<ProcessRecord>();
15384                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15385                }
15386                if (!curProcs.contains(proc)) {
15387                    curProcs.add(proc);
15388                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15389                            proc.info.packageName, proc.info.uid);
15390                }
15391            } else {
15392                if (curProcs != null) {
15393                    if (curProcs.remove(proc)) {
15394                        mBatteryStatsService.noteEvent(
15395                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15396                                proc.info.packageName, proc.info.uid);
15397                        if (curProcs.size() <= 0) {
15398                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15399                        }
15400                    }
15401                }
15402            }
15403            if (oomAdj) {
15404                updateOomAdjLocked();
15405            }
15406        }
15407    }
15408
15409    private final ActivityRecord resumedAppLocked() {
15410        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15411        String pkg;
15412        int uid;
15413        if (act != null) {
15414            pkg = act.packageName;
15415            uid = act.info.applicationInfo.uid;
15416        } else {
15417            pkg = null;
15418            uid = -1;
15419        }
15420        // Has the UID or resumed package name changed?
15421        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15422                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15423            if (mCurResumedPackage != null) {
15424                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15425                        mCurResumedPackage, mCurResumedUid);
15426            }
15427            mCurResumedPackage = pkg;
15428            mCurResumedUid = uid;
15429            if (mCurResumedPackage != null) {
15430                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15431                        mCurResumedPackage, mCurResumedUid);
15432            }
15433        }
15434        return act;
15435    }
15436
15437    final boolean updateOomAdjLocked(ProcessRecord app) {
15438        return updateOomAdjLocked(app, false);
15439    }
15440
15441    final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) {
15442        final ActivityRecord TOP_ACT = resumedAppLocked();
15443        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15444        final boolean wasCached = app.cached;
15445
15446        mAdjSeq++;
15447
15448        // This is the desired cached adjusment we want to tell it to use.
15449        // If our app is currently cached, we know it, and that is it.  Otherwise,
15450        // we don't know it yet, and it needs to now be cached we will then
15451        // need to do a complete oom adj.
15452        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15453                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15454        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState,
15455                SystemClock.uptimeMillis());
15456        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15457            // Changed to/from cached state, so apps after it in the LRU
15458            // list may also be changed.
15459            updateOomAdjLocked();
15460        }
15461        return success;
15462    }
15463
15464    final void updateOomAdjLocked() {
15465        final ActivityRecord TOP_ACT = resumedAppLocked();
15466        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15467        final long now = SystemClock.uptimeMillis();
15468        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15469        final int N = mLruProcesses.size();
15470
15471        if (false) {
15472            RuntimeException e = new RuntimeException();
15473            e.fillInStackTrace();
15474            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15475        }
15476
15477        mAdjSeq++;
15478        mNewNumServiceProcs = 0;
15479        mNewNumAServiceProcs = 0;
15480
15481        final int emptyProcessLimit;
15482        final int cachedProcessLimit;
15483        if (mProcessLimit <= 0) {
15484            emptyProcessLimit = cachedProcessLimit = 0;
15485        } else if (mProcessLimit == 1) {
15486            emptyProcessLimit = 1;
15487            cachedProcessLimit = 0;
15488        } else {
15489            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15490            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15491        }
15492
15493        // Let's determine how many processes we have running vs.
15494        // how many slots we have for background processes; we may want
15495        // to put multiple processes in a slot of there are enough of
15496        // them.
15497        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15498                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15499        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15500        if (numEmptyProcs > cachedProcessLimit) {
15501            // If there are more empty processes than our limit on cached
15502            // processes, then use the cached process limit for the factor.
15503            // This ensures that the really old empty processes get pushed
15504            // down to the bottom, so if we are running low on memory we will
15505            // have a better chance at keeping around more cached processes
15506            // instead of a gazillion empty processes.
15507            numEmptyProcs = cachedProcessLimit;
15508        }
15509        int emptyFactor = numEmptyProcs/numSlots;
15510        if (emptyFactor < 1) emptyFactor = 1;
15511        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15512        if (cachedFactor < 1) cachedFactor = 1;
15513        int stepCached = 0;
15514        int stepEmpty = 0;
15515        int numCached = 0;
15516        int numEmpty = 0;
15517        int numTrimming = 0;
15518
15519        mNumNonCachedProcs = 0;
15520        mNumCachedHiddenProcs = 0;
15521
15522        // First update the OOM adjustment for each of the
15523        // application processes based on their current state.
15524        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15525        int nextCachedAdj = curCachedAdj+1;
15526        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15527        int nextEmptyAdj = curEmptyAdj+2;
15528        for (int i=N-1; i>=0; i--) {
15529            ProcessRecord app = mLruProcesses.get(i);
15530            if (!app.killedByAm && app.thread != null) {
15531                app.procStateChanged = false;
15532                final boolean wasKeeping = app.keeping;
15533                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15534
15535                // If we haven't yet assigned the final cached adj
15536                // to the process, do that now.
15537                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15538                    switch (app.curProcState) {
15539                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15540                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15541                            // This process is a cached process holding activities...
15542                            // assign it the next cached value for that type, and then
15543                            // step that cached level.
15544                            app.curRawAdj = curCachedAdj;
15545                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15546                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15547                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15548                                    + ")");
15549                            if (curCachedAdj != nextCachedAdj) {
15550                                stepCached++;
15551                                if (stepCached >= cachedFactor) {
15552                                    stepCached = 0;
15553                                    curCachedAdj = nextCachedAdj;
15554                                    nextCachedAdj += 2;
15555                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15556                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15557                                    }
15558                                }
15559                            }
15560                            break;
15561                        default:
15562                            // For everything else, assign next empty cached process
15563                            // level and bump that up.  Note that this means that
15564                            // long-running services that have dropped down to the
15565                            // cached level will be treated as empty (since their process
15566                            // state is still as a service), which is what we want.
15567                            app.curRawAdj = curEmptyAdj;
15568                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15569                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15570                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15571                                    + ")");
15572                            if (curEmptyAdj != nextEmptyAdj) {
15573                                stepEmpty++;
15574                                if (stepEmpty >= emptyFactor) {
15575                                    stepEmpty = 0;
15576                                    curEmptyAdj = nextEmptyAdj;
15577                                    nextEmptyAdj += 2;
15578                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15579                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15580                                    }
15581                                }
15582                            }
15583                            break;
15584                    }
15585                }
15586
15587                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now);
15588
15589                // Count the number of process types.
15590                switch (app.curProcState) {
15591                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15592                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15593                        mNumCachedHiddenProcs++;
15594                        numCached++;
15595                        if (numCached > cachedProcessLimit) {
15596                            killUnneededProcessLocked(app, "cached #" + numCached);
15597                        }
15598                        break;
15599                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15600                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15601                                && app.lastActivityTime < oldTime) {
15602                            killUnneededProcessLocked(app, "empty for "
15603                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15604                                    / 1000) + "s");
15605                        } else {
15606                            numEmpty++;
15607                            if (numEmpty > emptyProcessLimit) {
15608                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15609                            }
15610                        }
15611                        break;
15612                    default:
15613                        mNumNonCachedProcs++;
15614                        break;
15615                }
15616
15617                if (app.isolated && app.services.size() <= 0) {
15618                    // If this is an isolated process, and there are no
15619                    // services running in it, then the process is no longer
15620                    // needed.  We agressively kill these because we can by
15621                    // definition not re-use the same process again, and it is
15622                    // good to avoid having whatever code was running in them
15623                    // left sitting around after no longer needed.
15624                    killUnneededProcessLocked(app, "isolated not needed");
15625                }
15626
15627                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15628                        && !app.killedByAm) {
15629                    numTrimming++;
15630                }
15631            }
15632        }
15633
15634        mNumServiceProcs = mNewNumServiceProcs;
15635
15636        // Now determine the memory trimming level of background processes.
15637        // Unfortunately we need to start at the back of the list to do this
15638        // properly.  We only do this if the number of background apps we
15639        // are managing to keep around is less than half the maximum we desire;
15640        // if we are keeping a good number around, we'll let them use whatever
15641        // memory they want.
15642        final int numCachedAndEmpty = numCached + numEmpty;
15643        int memFactor;
15644        if (numCached <= ProcessList.TRIM_CACHED_APPS
15645                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
15646            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
15647                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
15648            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
15649                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
15650            } else {
15651                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
15652            }
15653        } else {
15654            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
15655        }
15656        // We always allow the memory level to go up (better).  We only allow it to go
15657        // down if we are in a state where that is allowed, *and* the total number of processes
15658        // has gone down since last time.
15659        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
15660                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
15661                + " last=" + mLastNumProcesses);
15662        if (memFactor > mLastMemoryLevel) {
15663            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
15664                memFactor = mLastMemoryLevel;
15665                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
15666            }
15667        }
15668        mLastMemoryLevel = memFactor;
15669        mLastNumProcesses = mLruProcesses.size();
15670        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now);
15671        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
15672        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
15673            if (mLowRamStartTime == 0) {
15674                mLowRamStartTime = now;
15675            }
15676            int step = 0;
15677            int fgTrimLevel;
15678            switch (memFactor) {
15679                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15680                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
15681                    break;
15682                case ProcessStats.ADJ_MEM_FACTOR_LOW:
15683                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
15684                    break;
15685                default:
15686                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
15687                    break;
15688            }
15689            int factor = numTrimming/3;
15690            int minFactor = 2;
15691            if (mHomeProcess != null) minFactor++;
15692            if (mPreviousProcess != null) minFactor++;
15693            if (factor < minFactor) factor = minFactor;
15694            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
15695            for (int i=N-1; i>=0; i--) {
15696                ProcessRecord app = mLruProcesses.get(i);
15697                if (allChanged || app.procStateChanged) {
15698                    setProcessTrackerState(app, trackerMemFactor, now);
15699                    app.procStateChanged = false;
15700                }
15701                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15702                        && !app.killedByAm) {
15703                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
15704                        try {
15705                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15706                                    "Trimming memory of " + app.processName
15707                                    + " to " + curLevel);
15708                            app.thread.scheduleTrimMemory(curLevel);
15709                        } catch (RemoteException e) {
15710                        }
15711                        if (false) {
15712                            // For now we won't do this; our memory trimming seems
15713                            // to be good enough at this point that destroying
15714                            // activities causes more harm than good.
15715                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
15716                                    && app != mHomeProcess && app != mPreviousProcess) {
15717                                // Need to do this on its own message because the stack may not
15718                                // be in a consistent state at this point.
15719                                // For these apps we will also finish their activities
15720                                // to help them free memory.
15721                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
15722                            }
15723                        }
15724                    }
15725                    app.trimMemoryLevel = curLevel;
15726                    step++;
15727                    if (step >= factor) {
15728                        step = 0;
15729                        switch (curLevel) {
15730                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
15731                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
15732                                break;
15733                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
15734                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15735                                break;
15736                        }
15737                    }
15738                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15739                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
15740                            && app.thread != null) {
15741                        try {
15742                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15743                                    "Trimming memory of heavy-weight " + app.processName
15744                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15745                            app.thread.scheduleTrimMemory(
15746                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15747                        } catch (RemoteException e) {
15748                        }
15749                    }
15750                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15751                } else {
15752                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15753                            || app.systemNoUi) && app.pendingUiClean) {
15754                        // If this application is now in the background and it
15755                        // had done UI, then give it the special trim level to
15756                        // have it free UI resources.
15757                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
15758                        if (app.trimMemoryLevel < level && app.thread != null) {
15759                            try {
15760                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15761                                        "Trimming memory of bg-ui " + app.processName
15762                                        + " to " + level);
15763                                app.thread.scheduleTrimMemory(level);
15764                            } catch (RemoteException e) {
15765                            }
15766                        }
15767                        app.pendingUiClean = false;
15768                    }
15769                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
15770                        try {
15771                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15772                                    "Trimming memory of fg " + app.processName
15773                                    + " to " + fgTrimLevel);
15774                            app.thread.scheduleTrimMemory(fgTrimLevel);
15775                        } catch (RemoteException e) {
15776                        }
15777                    }
15778                    app.trimMemoryLevel = fgTrimLevel;
15779                }
15780            }
15781        } else {
15782            if (mLowRamStartTime != 0) {
15783                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
15784                mLowRamStartTime = 0;
15785            }
15786            for (int i=N-1; i>=0; i--) {
15787                ProcessRecord app = mLruProcesses.get(i);
15788                if (allChanged || app.procStateChanged) {
15789                    setProcessTrackerState(app, trackerMemFactor, now);
15790                    app.procStateChanged = false;
15791                }
15792                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15793                        || app.systemNoUi) && app.pendingUiClean) {
15794                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
15795                            && app.thread != null) {
15796                        try {
15797                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15798                                    "Trimming memory of ui hidden " + app.processName
15799                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15800                            app.thread.scheduleTrimMemory(
15801                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15802                        } catch (RemoteException e) {
15803                        }
15804                    }
15805                    app.pendingUiClean = false;
15806                }
15807                app.trimMemoryLevel = 0;
15808            }
15809        }
15810
15811        if (mAlwaysFinishActivities) {
15812            // Need to do this on its own message because the stack may not
15813            // be in a consistent state at this point.
15814            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
15815        }
15816
15817        if (allChanged) {
15818            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
15819        }
15820
15821        if (mProcessStats.shouldWriteNowLocked(now)) {
15822            mHandler.post(new Runnable() {
15823                @Override public void run() {
15824                    synchronized (ActivityManagerService.this) {
15825                        mProcessStats.writeStateAsyncLocked();
15826                    }
15827                }
15828            });
15829        }
15830
15831        if (DEBUG_OOM_ADJ) {
15832            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
15833        }
15834    }
15835
15836    final void trimApplications() {
15837        synchronized (this) {
15838            int i;
15839
15840            // First remove any unused application processes whose package
15841            // has been removed.
15842            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
15843                final ProcessRecord app = mRemovedProcesses.get(i);
15844                if (app.activities.size() == 0
15845                        && app.curReceiver == null && app.services.size() == 0) {
15846                    Slog.i(
15847                        TAG, "Exiting empty application process "
15848                        + app.processName + " ("
15849                        + (app.thread != null ? app.thread.asBinder() : null)
15850                        + ")\n");
15851                    if (app.pid > 0 && app.pid != MY_PID) {
15852                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
15853                                app.processName, app.setAdj, "empty");
15854                        app.killedByAm = true;
15855                        Process.killProcessQuiet(app.pid);
15856                    } else {
15857                        try {
15858                            app.thread.scheduleExit();
15859                        } catch (Exception e) {
15860                            // Ignore exceptions.
15861                        }
15862                    }
15863                    cleanUpApplicationRecordLocked(app, false, true, -1);
15864                    mRemovedProcesses.remove(i);
15865
15866                    if (app.persistent) {
15867                        if (app.persistent) {
15868                            addAppLocked(app.info, false);
15869                        }
15870                    }
15871                }
15872            }
15873
15874            // Now update the oom adj for all processes.
15875            updateOomAdjLocked();
15876        }
15877    }
15878
15879    /** This method sends the specified signal to each of the persistent apps */
15880    public void signalPersistentProcesses(int sig) throws RemoteException {
15881        if (sig != Process.SIGNAL_USR1) {
15882            throw new SecurityException("Only SIGNAL_USR1 is allowed");
15883        }
15884
15885        synchronized (this) {
15886            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
15887                    != PackageManager.PERMISSION_GRANTED) {
15888                throw new SecurityException("Requires permission "
15889                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
15890            }
15891
15892            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15893                ProcessRecord r = mLruProcesses.get(i);
15894                if (r.thread != null && r.persistent) {
15895                    Process.sendSignal(r.pid, sig);
15896                }
15897            }
15898        }
15899    }
15900
15901    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
15902        if (proc == null || proc == mProfileProc) {
15903            proc = mProfileProc;
15904            path = mProfileFile;
15905            profileType = mProfileType;
15906            clearProfilerLocked();
15907        }
15908        if (proc == null) {
15909            return;
15910        }
15911        try {
15912            proc.thread.profilerControl(false, path, null, profileType);
15913        } catch (RemoteException e) {
15914            throw new IllegalStateException("Process disappeared");
15915        }
15916    }
15917
15918    private void clearProfilerLocked() {
15919        if (mProfileFd != null) {
15920            try {
15921                mProfileFd.close();
15922            } catch (IOException e) {
15923            }
15924        }
15925        mProfileApp = null;
15926        mProfileProc = null;
15927        mProfileFile = null;
15928        mProfileType = 0;
15929        mAutoStopProfiler = false;
15930    }
15931
15932    public boolean profileControl(String process, int userId, boolean start,
15933            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
15934
15935        try {
15936            synchronized (this) {
15937                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15938                // its own permission.
15939                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15940                        != PackageManager.PERMISSION_GRANTED) {
15941                    throw new SecurityException("Requires permission "
15942                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15943                }
15944
15945                if (start && fd == null) {
15946                    throw new IllegalArgumentException("null fd");
15947                }
15948
15949                ProcessRecord proc = null;
15950                if (process != null) {
15951                    proc = findProcessLocked(process, userId, "profileControl");
15952                }
15953
15954                if (start && (proc == null || proc.thread == null)) {
15955                    throw new IllegalArgumentException("Unknown process: " + process);
15956                }
15957
15958                if (start) {
15959                    stopProfilerLocked(null, null, 0);
15960                    setProfileApp(proc.info, proc.processName, path, fd, false);
15961                    mProfileProc = proc;
15962                    mProfileType = profileType;
15963                    try {
15964                        fd = fd.dup();
15965                    } catch (IOException e) {
15966                        fd = null;
15967                    }
15968                    proc.thread.profilerControl(start, path, fd, profileType);
15969                    fd = null;
15970                    mProfileFd = null;
15971                } else {
15972                    stopProfilerLocked(proc, path, profileType);
15973                    if (fd != null) {
15974                        try {
15975                            fd.close();
15976                        } catch (IOException e) {
15977                        }
15978                    }
15979                }
15980
15981                return true;
15982            }
15983        } catch (RemoteException e) {
15984            throw new IllegalStateException("Process disappeared");
15985        } finally {
15986            if (fd != null) {
15987                try {
15988                    fd.close();
15989                } catch (IOException e) {
15990                }
15991            }
15992        }
15993    }
15994
15995    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
15996        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15997                userId, true, true, callName, null);
15998        ProcessRecord proc = null;
15999        try {
16000            int pid = Integer.parseInt(process);
16001            synchronized (mPidsSelfLocked) {
16002                proc = mPidsSelfLocked.get(pid);
16003            }
16004        } catch (NumberFormatException e) {
16005        }
16006
16007        if (proc == null) {
16008            ArrayMap<String, SparseArray<ProcessRecord>> all
16009                    = mProcessNames.getMap();
16010            SparseArray<ProcessRecord> procs = all.get(process);
16011            if (procs != null && procs.size() > 0) {
16012                proc = procs.valueAt(0);
16013                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16014                    for (int i=1; i<procs.size(); i++) {
16015                        ProcessRecord thisProc = procs.valueAt(i);
16016                        if (thisProc.userId == userId) {
16017                            proc = thisProc;
16018                            break;
16019                        }
16020                    }
16021                }
16022            }
16023        }
16024
16025        return proc;
16026    }
16027
16028    public boolean dumpHeap(String process, int userId, boolean managed,
16029            String path, ParcelFileDescriptor fd) throws RemoteException {
16030
16031        try {
16032            synchronized (this) {
16033                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16034                // its own permission (same as profileControl).
16035                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16036                        != PackageManager.PERMISSION_GRANTED) {
16037                    throw new SecurityException("Requires permission "
16038                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16039                }
16040
16041                if (fd == null) {
16042                    throw new IllegalArgumentException("null fd");
16043                }
16044
16045                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16046                if (proc == null || proc.thread == null) {
16047                    throw new IllegalArgumentException("Unknown process: " + process);
16048                }
16049
16050                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16051                if (!isDebuggable) {
16052                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16053                        throw new SecurityException("Process not debuggable: " + proc);
16054                    }
16055                }
16056
16057                proc.thread.dumpHeap(managed, path, fd);
16058                fd = null;
16059                return true;
16060            }
16061        } catch (RemoteException e) {
16062            throw new IllegalStateException("Process disappeared");
16063        } finally {
16064            if (fd != null) {
16065                try {
16066                    fd.close();
16067                } catch (IOException e) {
16068                }
16069            }
16070        }
16071    }
16072
16073    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16074    public void monitor() {
16075        synchronized (this) { }
16076    }
16077
16078    void onCoreSettingsChange(Bundle settings) {
16079        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16080            ProcessRecord processRecord = mLruProcesses.get(i);
16081            try {
16082                if (processRecord.thread != null) {
16083                    processRecord.thread.setCoreSettings(settings);
16084                }
16085            } catch (RemoteException re) {
16086                /* ignore */
16087            }
16088        }
16089    }
16090
16091    // Multi-user methods
16092
16093    /**
16094     * Start user, if its not already running, but don't bring it to foreground.
16095     */
16096    @Override
16097    public boolean startUserInBackground(final int userId) {
16098        return startUser(userId, /* foreground */ false);
16099    }
16100
16101    /**
16102     * Refreshes the list of users related to the current user when either a
16103     * user switch happens or when a new related user is started in the
16104     * background.
16105     */
16106    private void updateRelatedUserIdsLocked() {
16107        final List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(mCurrentUserId);
16108        int[] relatedUserIds = new int[relatedUsers.size()]; // relatedUsers will not be null
16109        for (int i = 0; i < relatedUserIds.length; i++) {
16110            relatedUserIds[i] = relatedUsers.get(i).id;
16111        }
16112        mRelatedUserIds = relatedUserIds;
16113    }
16114
16115    @Override
16116    public boolean switchUser(final int userId) {
16117        return startUser(userId, /* foregound */ true);
16118    }
16119
16120    private boolean startUser(final int userId, boolean foreground) {
16121        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16122                != PackageManager.PERMISSION_GRANTED) {
16123            String msg = "Permission Denial: switchUser() from pid="
16124                    + Binder.getCallingPid()
16125                    + ", uid=" + Binder.getCallingUid()
16126                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16127            Slog.w(TAG, msg);
16128            throw new SecurityException(msg);
16129        }
16130
16131        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16132
16133        final long ident = Binder.clearCallingIdentity();
16134        try {
16135            synchronized (this) {
16136                final int oldUserId = mCurrentUserId;
16137                if (oldUserId == userId) {
16138                    return true;
16139                }
16140
16141                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16142                if (userInfo == null) {
16143                    Slog.w(TAG, "No user info for user #" + userId);
16144                    return false;
16145                }
16146
16147                if (foreground) {
16148                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16149                            R.anim.screen_user_enter);
16150                }
16151
16152                boolean needStart = false;
16153
16154                // If the user we are switching to is not currently started, then
16155                // we need to start it now.
16156                if (mStartedUsers.get(userId) == null) {
16157                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16158                    updateStartedUserArrayLocked();
16159                    needStart = true;
16160                }
16161
16162                final Integer userIdInt = Integer.valueOf(userId);
16163                mUserLru.remove(userIdInt);
16164                mUserLru.add(userIdInt);
16165
16166                if (foreground) {
16167                    mCurrentUserId = userId;
16168                    updateRelatedUserIdsLocked();
16169                    mWindowManager.setCurrentUser(userId, mRelatedUserIds);
16170                    // Once the internal notion of the active user has switched, we lock the device
16171                    // with the option to show the user switcher on the keyguard.
16172                    mWindowManager.lockNow(null);
16173                } else {
16174                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16175                    updateRelatedUserIdsLocked();
16176                    mWindowManager.updateRelatedUserIds(mRelatedUserIds);
16177                    mUserLru.remove(currentUserIdInt);
16178                    mUserLru.add(currentUserIdInt);
16179                }
16180
16181                final UserStartedState uss = mStartedUsers.get(userId);
16182
16183                // Make sure user is in the started state.  If it is currently
16184                // stopping, we need to knock that off.
16185                if (uss.mState == UserStartedState.STATE_STOPPING) {
16186                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16187                    // so we can just fairly silently bring the user back from
16188                    // the almost-dead.
16189                    uss.mState = UserStartedState.STATE_RUNNING;
16190                    updateStartedUserArrayLocked();
16191                    needStart = true;
16192                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16193                    // This means ACTION_SHUTDOWN has been sent, so we will
16194                    // need to treat this as a new boot of the user.
16195                    uss.mState = UserStartedState.STATE_BOOTING;
16196                    updateStartedUserArrayLocked();
16197                    needStart = true;
16198                }
16199
16200                if (foreground) {
16201                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16202                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16203                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16204                            oldUserId, userId, uss));
16205                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16206                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16207                }
16208
16209                if (needStart) {
16210                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16211                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16212                            | Intent.FLAG_RECEIVER_FOREGROUND);
16213                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16214                    broadcastIntentLocked(null, null, intent,
16215                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16216                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16217                }
16218
16219                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16220                    if (userId != 0) {
16221                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16222                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16223                        broadcastIntentLocked(null, null, intent, null,
16224                                new IIntentReceiver.Stub() {
16225                                    public void performReceive(Intent intent, int resultCode,
16226                                            String data, Bundle extras, boolean ordered,
16227                                            boolean sticky, int sendingUser) {
16228                                        userInitialized(uss, userId);
16229                                    }
16230                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16231                                true, false, MY_PID, Process.SYSTEM_UID,
16232                                userId);
16233                        uss.initializing = true;
16234                    } else {
16235                        getUserManagerLocked().makeInitialized(userInfo.id);
16236                    }
16237                }
16238
16239                if (foreground) {
16240                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16241                    if (homeInFront) {
16242                        startHomeActivityLocked(userId);
16243                    } else {
16244                        mStackSupervisor.resumeTopActivitiesLocked();
16245                    }
16246                    EventLogTags.writeAmSwitchUser(userId);
16247                    getUserManagerLocked().userForeground(userId);
16248                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16249                }
16250
16251                if (needStart) {
16252                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16253                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16254                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16255                    broadcastIntentLocked(null, null, intent,
16256                            null, new IIntentReceiver.Stub() {
16257                                @Override
16258                                public void performReceive(Intent intent, int resultCode, String data,
16259                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16260                                        throws RemoteException {
16261                                }
16262                            }, 0, null, null,
16263                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16264                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16265                }
16266            }
16267        } finally {
16268            Binder.restoreCallingIdentity(ident);
16269        }
16270
16271        return true;
16272    }
16273
16274    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16275        long ident = Binder.clearCallingIdentity();
16276        try {
16277            Intent intent;
16278            if (oldUserId >= 0) {
16279                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16280                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16281                        | Intent.FLAG_RECEIVER_FOREGROUND);
16282                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16283                broadcastIntentLocked(null, null, intent,
16284                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16285                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16286            }
16287            if (newUserId >= 0) {
16288                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16289                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16290                        | Intent.FLAG_RECEIVER_FOREGROUND);
16291                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16292                broadcastIntentLocked(null, null, intent,
16293                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16294                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16295                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16296                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16297                        | Intent.FLAG_RECEIVER_FOREGROUND);
16298                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16299                broadcastIntentLocked(null, null, intent,
16300                        null, null, 0, null, null,
16301                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16302                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16303            }
16304        } finally {
16305            Binder.restoreCallingIdentity(ident);
16306        }
16307    }
16308
16309    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16310            final int newUserId) {
16311        final int N = mUserSwitchObservers.beginBroadcast();
16312        if (N > 0) {
16313            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16314                int mCount = 0;
16315                @Override
16316                public void sendResult(Bundle data) throws RemoteException {
16317                    synchronized (ActivityManagerService.this) {
16318                        if (mCurUserSwitchCallback == this) {
16319                            mCount++;
16320                            if (mCount == N) {
16321                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16322                            }
16323                        }
16324                    }
16325                }
16326            };
16327            synchronized (this) {
16328                uss.switching = true;
16329                mCurUserSwitchCallback = callback;
16330            }
16331            for (int i=0; i<N; i++) {
16332                try {
16333                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16334                            newUserId, callback);
16335                } catch (RemoteException e) {
16336                }
16337            }
16338        } else {
16339            synchronized (this) {
16340                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16341            }
16342        }
16343        mUserSwitchObservers.finishBroadcast();
16344    }
16345
16346    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16347        synchronized (this) {
16348            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16349            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16350        }
16351    }
16352
16353    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16354        mCurUserSwitchCallback = null;
16355        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16356        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16357                oldUserId, newUserId, uss));
16358    }
16359
16360    void userInitialized(UserStartedState uss, int newUserId) {
16361        completeSwitchAndInitalize(uss, newUserId, true, false);
16362    }
16363
16364    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16365        completeSwitchAndInitalize(uss, newUserId, false, true);
16366    }
16367
16368    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16369            boolean clearInitializing, boolean clearSwitching) {
16370        boolean unfrozen = false;
16371        synchronized (this) {
16372            if (clearInitializing) {
16373                uss.initializing = false;
16374                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16375            }
16376            if (clearSwitching) {
16377                uss.switching = false;
16378            }
16379            if (!uss.switching && !uss.initializing) {
16380                mWindowManager.stopFreezingScreen();
16381                unfrozen = true;
16382            }
16383        }
16384        if (unfrozen) {
16385            final int N = mUserSwitchObservers.beginBroadcast();
16386            for (int i=0; i<N; i++) {
16387                try {
16388                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16389                } catch (RemoteException e) {
16390                }
16391            }
16392            mUserSwitchObservers.finishBroadcast();
16393        }
16394    }
16395
16396    void scheduleStartRelatedUsersLocked() {
16397        if (!mHandler.hasMessages(START_RELATED_USERS_MSG)) {
16398            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_RELATED_USERS_MSG),
16399                    DateUtils.SECOND_IN_MILLIS);
16400        }
16401    }
16402
16403    void startRelatedUsersLocked() {
16404        if (DEBUG_MU) Slog.i(TAG_MU, "startRelatedUsersLocked");
16405        List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(mCurrentUserId);
16406        List<UserInfo> toStart = new ArrayList<UserInfo>(relatedUsers.size());
16407        for (UserInfo relatedUser : relatedUsers) {
16408            if ((relatedUser.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED) {
16409                toStart.add(relatedUser);
16410            }
16411        }
16412        final int n = toStart.size();
16413        int i = 0;
16414        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
16415            startUserInBackground(toStart.get(i).id);
16416        }
16417        if (i < n) {
16418            Slog.w(TAG_MU, "More related users than MAX_RUNNING_USERS");
16419        }
16420    }
16421
16422    void finishUserSwitch(UserStartedState uss) {
16423        synchronized (this) {
16424            if (uss.mState == UserStartedState.STATE_BOOTING
16425                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16426                uss.mState = UserStartedState.STATE_RUNNING;
16427                final int userId = uss.mHandle.getIdentifier();
16428                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16429                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16430                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16431                broadcastIntentLocked(null, null, intent,
16432                        null, null, 0, null, null,
16433                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16434                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16435            }
16436
16437            startRelatedUsersLocked();
16438
16439            int num = mUserLru.size();
16440            int i = 0;
16441            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16442                Integer oldUserId = mUserLru.get(i);
16443                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16444                if (oldUss == null) {
16445                    // Shouldn't happen, but be sane if it does.
16446                    mUserLru.remove(i);
16447                    num--;
16448                    continue;
16449                }
16450                if (oldUss.mState == UserStartedState.STATE_STOPPING
16451                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16452                    // This user is already stopping, doesn't count.
16453                    num--;
16454                    i++;
16455                    continue;
16456                }
16457                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16458                    // Owner and current can't be stopped, but count as running.
16459                    i++;
16460                    continue;
16461                }
16462                // This is a user to be stopped.
16463                stopUserLocked(oldUserId, null);
16464                num--;
16465                i++;
16466            }
16467        }
16468    }
16469
16470    @Override
16471    public int stopUser(final int userId, final IStopUserCallback callback) {
16472        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16473                != PackageManager.PERMISSION_GRANTED) {
16474            String msg = "Permission Denial: switchUser() from pid="
16475                    + Binder.getCallingPid()
16476                    + ", uid=" + Binder.getCallingUid()
16477                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16478            Slog.w(TAG, msg);
16479            throw new SecurityException(msg);
16480        }
16481        if (userId <= 0) {
16482            throw new IllegalArgumentException("Can't stop primary user " + userId);
16483        }
16484        synchronized (this) {
16485            return stopUserLocked(userId, callback);
16486        }
16487    }
16488
16489    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16490        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
16491        if (mCurrentUserId == userId) {
16492            return ActivityManager.USER_OP_IS_CURRENT;
16493        }
16494
16495        final UserStartedState uss = mStartedUsers.get(userId);
16496        if (uss == null) {
16497            // User is not started, nothing to do...  but we do need to
16498            // callback if requested.
16499            if (callback != null) {
16500                mHandler.post(new Runnable() {
16501                    @Override
16502                    public void run() {
16503                        try {
16504                            callback.userStopped(userId);
16505                        } catch (RemoteException e) {
16506                        }
16507                    }
16508                });
16509            }
16510            return ActivityManager.USER_OP_SUCCESS;
16511        }
16512
16513        if (callback != null) {
16514            uss.mStopCallbacks.add(callback);
16515        }
16516
16517        if (uss.mState != UserStartedState.STATE_STOPPING
16518                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16519            uss.mState = UserStartedState.STATE_STOPPING;
16520            updateStartedUserArrayLocked();
16521
16522            long ident = Binder.clearCallingIdentity();
16523            try {
16524                // We are going to broadcast ACTION_USER_STOPPING and then
16525                // once that is done send a final ACTION_SHUTDOWN and then
16526                // stop the user.
16527                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16528                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16529                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16530                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16531                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16532                // This is the result receiver for the final shutdown broadcast.
16533                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16534                    @Override
16535                    public void performReceive(Intent intent, int resultCode, String data,
16536                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16537                        finishUserStop(uss);
16538                    }
16539                };
16540                // This is the result receiver for the initial stopping broadcast.
16541                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16542                    @Override
16543                    public void performReceive(Intent intent, int resultCode, String data,
16544                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16545                        // On to the next.
16546                        synchronized (ActivityManagerService.this) {
16547                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16548                                // Whoops, we are being started back up.  Abort, abort!
16549                                return;
16550                            }
16551                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16552                        }
16553                        broadcastIntentLocked(null, null, shutdownIntent,
16554                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16555                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16556                    }
16557                };
16558                // Kick things off.
16559                broadcastIntentLocked(null, null, stoppingIntent,
16560                        null, stoppingReceiver, 0, null, null,
16561                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16562                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16563            } finally {
16564                Binder.restoreCallingIdentity(ident);
16565            }
16566        }
16567
16568        return ActivityManager.USER_OP_SUCCESS;
16569    }
16570
16571    void finishUserStop(UserStartedState uss) {
16572        final int userId = uss.mHandle.getIdentifier();
16573        boolean stopped;
16574        ArrayList<IStopUserCallback> callbacks;
16575        synchronized (this) {
16576            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16577            if (mStartedUsers.get(userId) != uss) {
16578                stopped = false;
16579            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16580                stopped = false;
16581            } else {
16582                stopped = true;
16583                // User can no longer run.
16584                mStartedUsers.remove(userId);
16585                mUserLru.remove(Integer.valueOf(userId));
16586                updateStartedUserArrayLocked();
16587
16588                // Clean up all state and processes associated with the user.
16589                // Kill all the processes for the user.
16590                forceStopUserLocked(userId, "finish user");
16591            }
16592        }
16593
16594        for (int i=0; i<callbacks.size(); i++) {
16595            try {
16596                if (stopped) callbacks.get(i).userStopped(userId);
16597                else callbacks.get(i).userStopAborted(userId);
16598            } catch (RemoteException e) {
16599            }
16600        }
16601
16602        mStackSupervisor.removeUserLocked(userId);
16603    }
16604
16605    @Override
16606    public UserInfo getCurrentUser() {
16607        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16608                != PackageManager.PERMISSION_GRANTED) && (
16609                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16610                != PackageManager.PERMISSION_GRANTED)) {
16611            String msg = "Permission Denial: getCurrentUser() from pid="
16612                    + Binder.getCallingPid()
16613                    + ", uid=" + Binder.getCallingUid()
16614                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16615            Slog.w(TAG, msg);
16616            throw new SecurityException(msg);
16617        }
16618        synchronized (this) {
16619            return getUserManagerLocked().getUserInfo(mCurrentUserId);
16620        }
16621    }
16622
16623    int getCurrentUserIdLocked() {
16624        return mCurrentUserId;
16625    }
16626
16627    @Override
16628    public boolean isUserRunning(int userId, boolean orStopped) {
16629        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16630                != PackageManager.PERMISSION_GRANTED) {
16631            String msg = "Permission Denial: isUserRunning() from pid="
16632                    + Binder.getCallingPid()
16633                    + ", uid=" + Binder.getCallingUid()
16634                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16635            Slog.w(TAG, msg);
16636            throw new SecurityException(msg);
16637        }
16638        synchronized (this) {
16639            return isUserRunningLocked(userId, orStopped);
16640        }
16641    }
16642
16643    boolean isUserRunningLocked(int userId, boolean orStopped) {
16644        UserStartedState state = mStartedUsers.get(userId);
16645        if (state == null) {
16646            return false;
16647        }
16648        if (orStopped) {
16649            return true;
16650        }
16651        return state.mState != UserStartedState.STATE_STOPPING
16652                && state.mState != UserStartedState.STATE_SHUTDOWN;
16653    }
16654
16655    @Override
16656    public int[] getRunningUserIds() {
16657        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16658                != PackageManager.PERMISSION_GRANTED) {
16659            String msg = "Permission Denial: isUserRunning() from pid="
16660                    + Binder.getCallingPid()
16661                    + ", uid=" + Binder.getCallingUid()
16662                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16663            Slog.w(TAG, msg);
16664            throw new SecurityException(msg);
16665        }
16666        synchronized (this) {
16667            return mStartedUserArray;
16668        }
16669    }
16670
16671    private void updateStartedUserArrayLocked() {
16672        int num = 0;
16673        for (int i=0; i<mStartedUsers.size();  i++) {
16674            UserStartedState uss = mStartedUsers.valueAt(i);
16675            // This list does not include stopping users.
16676            if (uss.mState != UserStartedState.STATE_STOPPING
16677                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16678                num++;
16679            }
16680        }
16681        mStartedUserArray = new int[num];
16682        num = 0;
16683        for (int i=0; i<mStartedUsers.size();  i++) {
16684            UserStartedState uss = mStartedUsers.valueAt(i);
16685            if (uss.mState != UserStartedState.STATE_STOPPING
16686                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16687                mStartedUserArray[num] = mStartedUsers.keyAt(i);
16688                num++;
16689            }
16690        }
16691    }
16692
16693    @Override
16694    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
16695        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16696                != PackageManager.PERMISSION_GRANTED) {
16697            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
16698                    + Binder.getCallingPid()
16699                    + ", uid=" + Binder.getCallingUid()
16700                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16701            Slog.w(TAG, msg);
16702            throw new SecurityException(msg);
16703        }
16704
16705        mUserSwitchObservers.register(observer);
16706    }
16707
16708    @Override
16709    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
16710        mUserSwitchObservers.unregister(observer);
16711    }
16712
16713    private boolean userExists(int userId) {
16714        if (userId == 0) {
16715            return true;
16716        }
16717        UserManagerService ums = getUserManagerLocked();
16718        return ums != null ? (ums.getUserInfo(userId) != null) : false;
16719    }
16720
16721    int[] getUsersLocked() {
16722        UserManagerService ums = getUserManagerLocked();
16723        return ums != null ? ums.getUserIds() : new int[] { 0 };
16724    }
16725
16726    UserManagerService getUserManagerLocked() {
16727        if (mUserManager == null) {
16728            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
16729            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
16730        }
16731        return mUserManager;
16732    }
16733
16734    private int applyUserId(int uid, int userId) {
16735        return UserHandle.getUid(userId, uid);
16736    }
16737
16738    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
16739        if (info == null) return null;
16740        ApplicationInfo newInfo = new ApplicationInfo(info);
16741        newInfo.uid = applyUserId(info.uid, userId);
16742        newInfo.dataDir = USER_DATA_DIR + userId + "/"
16743                + info.packageName;
16744        return newInfo;
16745    }
16746
16747    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
16748        if (aInfo == null
16749                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
16750            return aInfo;
16751        }
16752
16753        ActivityInfo info = new ActivityInfo(aInfo);
16754        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
16755        return info;
16756    }
16757}
16758