ActivityManagerService.java revision f0f94d129b6eb3c48624e915898d86d4f2de59ff
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    static final int UPDATE_TIME = 41;
1079
1080    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1081    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1082    static final int FIRST_COMPAT_MODE_MSG = 300;
1083    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1084
1085    AlertDialog mUidAlert;
1086    CompatModeDialog mCompatModeDialog;
1087    long mLastMemUsageReportTime = 0;
1088
1089    /**
1090     * Flag whether the current user is a "monkey", i.e. whether
1091     * the UI is driven by a UI automation tool.
1092     */
1093    private boolean mUserIsMonkey;
1094
1095    final ServiceThread mHandlerThread;
1096    final MainHandler mHandler;
1097
1098    final class MainHandler extends Handler {
1099        public MainHandler(Looper looper) {
1100            super(looper, null, true);
1101        }
1102
1103        @Override
1104        public void handleMessage(Message msg) {
1105            switch (msg.what) {
1106            case SHOW_ERROR_MSG: {
1107                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1108                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1109                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1110                synchronized (ActivityManagerService.this) {
1111                    ProcessRecord proc = (ProcessRecord)data.get("app");
1112                    AppErrorResult res = (AppErrorResult) data.get("result");
1113                    if (proc != null && proc.crashDialog != null) {
1114                        Slog.e(TAG, "App already has crash dialog: " + proc);
1115                        if (res != null) {
1116                            res.set(0);
1117                        }
1118                        return;
1119                    }
1120                    if (!showBackground && UserHandle.getAppId(proc.uid)
1121                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1122                            && proc.pid != MY_PID) {
1123                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1124                        if (res != null) {
1125                            res.set(0);
1126                        }
1127                        return;
1128                    }
1129                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1130                        Dialog d = new AppErrorDialog(mContext,
1131                                ActivityManagerService.this, res, proc);
1132                        d.show();
1133                        proc.crashDialog = d;
1134                    } else {
1135                        // The device is asleep, so just pretend that the user
1136                        // saw a crash dialog and hit "force quit".
1137                        if (res != null) {
1138                            res.set(0);
1139                        }
1140                    }
1141                }
1142
1143                ensureBootCompleted();
1144            } break;
1145            case SHOW_NOT_RESPONDING_MSG: {
1146                synchronized (ActivityManagerService.this) {
1147                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1148                    ProcessRecord proc = (ProcessRecord)data.get("app");
1149                    if (proc != null && proc.anrDialog != null) {
1150                        Slog.e(TAG, "App already has anr dialog: " + proc);
1151                        return;
1152                    }
1153
1154                    Intent intent = new Intent("android.intent.action.ANR");
1155                    if (!mProcessesReady) {
1156                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1157                                | Intent.FLAG_RECEIVER_FOREGROUND);
1158                    }
1159                    broadcastIntentLocked(null, null, intent,
1160                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1161                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1162
1163                    if (mShowDialogs) {
1164                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1165                                mContext, proc, (ActivityRecord)data.get("activity"),
1166                                msg.arg1 != 0);
1167                        d.show();
1168                        proc.anrDialog = d;
1169                    } else {
1170                        // Just kill the app if there is no dialog to be shown.
1171                        killAppAtUsersRequest(proc, null);
1172                    }
1173                }
1174
1175                ensureBootCompleted();
1176            } break;
1177            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1178                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1179                synchronized (ActivityManagerService.this) {
1180                    ProcessRecord proc = (ProcessRecord) data.get("app");
1181                    if (proc == null) {
1182                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1183                        break;
1184                    }
1185                    if (proc.crashDialog != null) {
1186                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1187                        return;
1188                    }
1189                    AppErrorResult res = (AppErrorResult) data.get("result");
1190                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1191                        Dialog d = new StrictModeViolationDialog(mContext,
1192                                ActivityManagerService.this, res, proc);
1193                        d.show();
1194                        proc.crashDialog = d;
1195                    } else {
1196                        // The device is asleep, so just pretend that the user
1197                        // saw a crash dialog and hit "force quit".
1198                        res.set(0);
1199                    }
1200                }
1201                ensureBootCompleted();
1202            } break;
1203            case SHOW_FACTORY_ERROR_MSG: {
1204                Dialog d = new FactoryErrorDialog(
1205                    mContext, msg.getData().getCharSequence("msg"));
1206                d.show();
1207                ensureBootCompleted();
1208            } break;
1209            case UPDATE_CONFIGURATION_MSG: {
1210                final ContentResolver resolver = mContext.getContentResolver();
1211                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1212            } break;
1213            case GC_BACKGROUND_PROCESSES_MSG: {
1214                synchronized (ActivityManagerService.this) {
1215                    performAppGcsIfAppropriateLocked();
1216                }
1217            } break;
1218            case WAIT_FOR_DEBUGGER_MSG: {
1219                synchronized (ActivityManagerService.this) {
1220                    ProcessRecord app = (ProcessRecord)msg.obj;
1221                    if (msg.arg1 != 0) {
1222                        if (!app.waitedForDebugger) {
1223                            Dialog d = new AppWaitingForDebuggerDialog(
1224                                    ActivityManagerService.this,
1225                                    mContext, app);
1226                            app.waitDialog = d;
1227                            app.waitedForDebugger = true;
1228                            d.show();
1229                        }
1230                    } else {
1231                        if (app.waitDialog != null) {
1232                            app.waitDialog.dismiss();
1233                            app.waitDialog = null;
1234                        }
1235                    }
1236                }
1237            } break;
1238            case SERVICE_TIMEOUT_MSG: {
1239                if (mDidDexOpt) {
1240                    mDidDexOpt = false;
1241                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1242                    nmsg.obj = msg.obj;
1243                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1244                    return;
1245                }
1246                mServices.serviceTimeout((ProcessRecord)msg.obj);
1247            } break;
1248            case UPDATE_TIME_ZONE: {
1249                synchronized (ActivityManagerService.this) {
1250                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1251                        ProcessRecord r = mLruProcesses.get(i);
1252                        if (r.thread != null) {
1253                            try {
1254                                r.thread.updateTimeZone();
1255                            } catch (RemoteException ex) {
1256                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1257                            }
1258                        }
1259                    }
1260                }
1261            } break;
1262            case CLEAR_DNS_CACHE_MSG: {
1263                synchronized (ActivityManagerService.this) {
1264                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1265                        ProcessRecord r = mLruProcesses.get(i);
1266                        if (r.thread != null) {
1267                            try {
1268                                r.thread.clearDnsCache();
1269                            } catch (RemoteException ex) {
1270                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1271                            }
1272                        }
1273                    }
1274                }
1275            } break;
1276            case UPDATE_HTTP_PROXY_MSG: {
1277                ProxyProperties proxy = (ProxyProperties)msg.obj;
1278                String host = "";
1279                String port = "";
1280                String exclList = "";
1281                String pacFileUrl = null;
1282                if (proxy != null) {
1283                    host = proxy.getHost();
1284                    port = Integer.toString(proxy.getPort());
1285                    exclList = proxy.getExclusionList();
1286                    pacFileUrl = proxy.getPacFileUrl();
1287                }
1288                synchronized (ActivityManagerService.this) {
1289                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1290                        ProcessRecord r = mLruProcesses.get(i);
1291                        if (r.thread != null) {
1292                            try {
1293                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1294                            } catch (RemoteException ex) {
1295                                Slog.w(TAG, "Failed to update http proxy for: " +
1296                                        r.info.processName);
1297                            }
1298                        }
1299                    }
1300                }
1301            } break;
1302            case SHOW_UID_ERROR_MSG: {
1303                String title = "System UIDs Inconsistent";
1304                String text = "UIDs on the system are inconsistent, you need to wipe your"
1305                        + " data partition or your device will be unstable.";
1306                Log.e(TAG, title + ": " + text);
1307                if (mShowDialogs) {
1308                    // XXX This is a temporary dialog, no need to localize.
1309                    AlertDialog d = new BaseErrorDialog(mContext);
1310                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1311                    d.setCancelable(false);
1312                    d.setTitle(title);
1313                    d.setMessage(text);
1314                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1315                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1316                    mUidAlert = d;
1317                    d.show();
1318                }
1319            } break;
1320            case IM_FEELING_LUCKY_MSG: {
1321                if (mUidAlert != null) {
1322                    mUidAlert.dismiss();
1323                    mUidAlert = null;
1324                }
1325            } break;
1326            case PROC_START_TIMEOUT_MSG: {
1327                if (mDidDexOpt) {
1328                    mDidDexOpt = false;
1329                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1330                    nmsg.obj = msg.obj;
1331                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1332                    return;
1333                }
1334                ProcessRecord app = (ProcessRecord)msg.obj;
1335                synchronized (ActivityManagerService.this) {
1336                    processStartTimedOutLocked(app);
1337                }
1338            } break;
1339            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1340                synchronized (ActivityManagerService.this) {
1341                    doPendingActivityLaunchesLocked(true);
1342                }
1343            } break;
1344            case KILL_APPLICATION_MSG: {
1345                synchronized (ActivityManagerService.this) {
1346                    int appid = msg.arg1;
1347                    boolean restart = (msg.arg2 == 1);
1348                    Bundle bundle = (Bundle)msg.obj;
1349                    String pkg = bundle.getString("pkg");
1350                    String reason = bundle.getString("reason");
1351                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1352                            false, UserHandle.USER_ALL, reason);
1353                }
1354            } break;
1355            case FINALIZE_PENDING_INTENT_MSG: {
1356                ((PendingIntentRecord)msg.obj).completeFinalize();
1357            } break;
1358            case POST_HEAVY_NOTIFICATION_MSG: {
1359                INotificationManager inm = NotificationManager.getService();
1360                if (inm == null) {
1361                    return;
1362                }
1363
1364                ActivityRecord root = (ActivityRecord)msg.obj;
1365                ProcessRecord process = root.app;
1366                if (process == null) {
1367                    return;
1368                }
1369
1370                try {
1371                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1372                    String text = mContext.getString(R.string.heavy_weight_notification,
1373                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1374                    Notification notification = new Notification();
1375                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1376                    notification.when = 0;
1377                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1378                    notification.tickerText = text;
1379                    notification.defaults = 0; // please be quiet
1380                    notification.sound = null;
1381                    notification.vibrate = null;
1382                    notification.setLatestEventInfo(context, text,
1383                            mContext.getText(R.string.heavy_weight_notification_detail),
1384                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1385                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1386                                    new UserHandle(root.userId)));
1387
1388                    try {
1389                        int[] outId = new int[1];
1390                        inm.enqueueNotificationWithTag("android", "android", null,
1391                                R.string.heavy_weight_notification,
1392                                notification, outId, root.userId);
1393                    } catch (RuntimeException e) {
1394                        Slog.w(ActivityManagerService.TAG,
1395                                "Error showing notification for heavy-weight app", e);
1396                    } catch (RemoteException e) {
1397                    }
1398                } catch (NameNotFoundException e) {
1399                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1400                }
1401            } break;
1402            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1403                INotificationManager inm = NotificationManager.getService();
1404                if (inm == null) {
1405                    return;
1406                }
1407                try {
1408                    inm.cancelNotificationWithTag("android", null,
1409                            R.string.heavy_weight_notification,  msg.arg1);
1410                } catch (RuntimeException e) {
1411                    Slog.w(ActivityManagerService.TAG,
1412                            "Error canceling notification for service", e);
1413                } catch (RemoteException e) {
1414                }
1415            } break;
1416            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1417                synchronized (ActivityManagerService.this) {
1418                    checkExcessivePowerUsageLocked(true);
1419                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1420                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1421                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1422                }
1423            } break;
1424            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1425                synchronized (ActivityManagerService.this) {
1426                    ActivityRecord ar = (ActivityRecord)msg.obj;
1427                    if (mCompatModeDialog != null) {
1428                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1429                                ar.info.applicationInfo.packageName)) {
1430                            return;
1431                        }
1432                        mCompatModeDialog.dismiss();
1433                        mCompatModeDialog = null;
1434                    }
1435                    if (ar != null && false) {
1436                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1437                                ar.packageName)) {
1438                            int mode = mCompatModePackages.computeCompatModeLocked(
1439                                    ar.info.applicationInfo);
1440                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1441                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1442                                mCompatModeDialog = new CompatModeDialog(
1443                                        ActivityManagerService.this, mContext,
1444                                        ar.info.applicationInfo);
1445                                mCompatModeDialog.show();
1446                            }
1447                        }
1448                    }
1449                }
1450                break;
1451            }
1452            case DISPATCH_PROCESSES_CHANGED: {
1453                dispatchProcessesChanged();
1454                break;
1455            }
1456            case DISPATCH_PROCESS_DIED: {
1457                final int pid = msg.arg1;
1458                final int uid = msg.arg2;
1459                dispatchProcessDied(pid, uid);
1460                break;
1461            }
1462            case REPORT_MEM_USAGE_MSG: {
1463                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1464                Thread thread = new Thread() {
1465                    @Override public void run() {
1466                        final SparseArray<ProcessMemInfo> infoMap
1467                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1468                        for (int i=0, N=memInfos.size(); i<N; i++) {
1469                            ProcessMemInfo mi = memInfos.get(i);
1470                            infoMap.put(mi.pid, mi);
1471                        }
1472                        updateCpuStatsNow();
1473                        synchronized (mProcessCpuThread) {
1474                            final int N = mProcessCpuTracker.countStats();
1475                            for (int i=0; i<N; i++) {
1476                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1477                                if (st.vsize > 0) {
1478                                    long pss = Debug.getPss(st.pid, null);
1479                                    if (pss > 0) {
1480                                        if (infoMap.indexOfKey(st.pid) < 0) {
1481                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1482                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1483                                            mi.pss = pss;
1484                                            memInfos.add(mi);
1485                                        }
1486                                    }
1487                                }
1488                            }
1489                        }
1490
1491                        long totalPss = 0;
1492                        for (int i=0, N=memInfos.size(); i<N; i++) {
1493                            ProcessMemInfo mi = memInfos.get(i);
1494                            if (mi.pss == 0) {
1495                                mi.pss = Debug.getPss(mi.pid, null);
1496                            }
1497                            totalPss += mi.pss;
1498                        }
1499                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1500                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1501                                if (lhs.oomAdj != rhs.oomAdj) {
1502                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1503                                }
1504                                if (lhs.pss != rhs.pss) {
1505                                    return lhs.pss < rhs.pss ? 1 : -1;
1506                                }
1507                                return 0;
1508                            }
1509                        });
1510
1511                        StringBuilder tag = new StringBuilder(128);
1512                        StringBuilder stack = new StringBuilder(128);
1513                        tag.append("Low on memory -- ");
1514                        appendMemBucket(tag, totalPss, "total", false);
1515                        appendMemBucket(stack, totalPss, "total", true);
1516
1517                        StringBuilder logBuilder = new StringBuilder(1024);
1518                        logBuilder.append("Low on memory:\n");
1519
1520                        boolean firstLine = true;
1521                        int lastOomAdj = Integer.MIN_VALUE;
1522                        for (int i=0, N=memInfos.size(); i<N; i++) {
1523                            ProcessMemInfo mi = memInfos.get(i);
1524
1525                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1526                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1527                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1528                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1529                                if (lastOomAdj != mi.oomAdj) {
1530                                    lastOomAdj = mi.oomAdj;
1531                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1532                                        tag.append(" / ");
1533                                    }
1534                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1535                                        if (firstLine) {
1536                                            stack.append(":");
1537                                            firstLine = false;
1538                                        }
1539                                        stack.append("\n\t at ");
1540                                    } else {
1541                                        stack.append("$");
1542                                    }
1543                                } else {
1544                                    tag.append(" ");
1545                                    stack.append("$");
1546                                }
1547                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1548                                    appendMemBucket(tag, mi.pss, mi.name, false);
1549                                }
1550                                appendMemBucket(stack, mi.pss, mi.name, true);
1551                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1552                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1553                                    stack.append("(");
1554                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1555                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1556                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1557                                            stack.append(":");
1558                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1559                                        }
1560                                    }
1561                                    stack.append(")");
1562                                }
1563                            }
1564
1565                            logBuilder.append("  ");
1566                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1567                            logBuilder.append(' ');
1568                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1569                            logBuilder.append(' ');
1570                            ProcessList.appendRamKb(logBuilder, mi.pss);
1571                            logBuilder.append(" kB: ");
1572                            logBuilder.append(mi.name);
1573                            logBuilder.append(" (");
1574                            logBuilder.append(mi.pid);
1575                            logBuilder.append(") ");
1576                            logBuilder.append(mi.adjType);
1577                            logBuilder.append('\n');
1578                            if (mi.adjReason != null) {
1579                                logBuilder.append("                      ");
1580                                logBuilder.append(mi.adjReason);
1581                                logBuilder.append('\n');
1582                            }
1583                        }
1584
1585                        logBuilder.append("           ");
1586                        ProcessList.appendRamKb(logBuilder, totalPss);
1587                        logBuilder.append(" kB: TOTAL\n");
1588
1589                        long[] infos = new long[Debug.MEMINFO_COUNT];
1590                        Debug.getMemInfo(infos);
1591                        logBuilder.append("  MemInfo: ");
1592                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1593                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1594                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1595                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1596                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1597                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1598                            logBuilder.append("  ZRAM: ");
1599                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1600                            logBuilder.append(" kB RAM, ");
1601                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1602                            logBuilder.append(" kB swap total, ");
1603                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1604                            logBuilder.append(" kB swap free\n");
1605                        }
1606                        Slog.i(TAG, logBuilder.toString());
1607
1608                        StringBuilder dropBuilder = new StringBuilder(1024);
1609                        /*
1610                        StringWriter oomSw = new StringWriter();
1611                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1612                        StringWriter catSw = new StringWriter();
1613                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1614                        String[] emptyArgs = new String[] { };
1615                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1616                        oomPw.flush();
1617                        String oomString = oomSw.toString();
1618                        */
1619                        dropBuilder.append(stack);
1620                        dropBuilder.append('\n');
1621                        dropBuilder.append('\n');
1622                        dropBuilder.append(logBuilder);
1623                        dropBuilder.append('\n');
1624                        /*
1625                        dropBuilder.append(oomString);
1626                        dropBuilder.append('\n');
1627                        */
1628                        StringWriter catSw = new StringWriter();
1629                        synchronized (ActivityManagerService.this) {
1630                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1631                            String[] emptyArgs = new String[] { };
1632                            catPw.println();
1633                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1634                            catPw.println();
1635                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1636                                    false, false, null);
1637                            catPw.println();
1638                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1639                            catPw.flush();
1640                        }
1641                        dropBuilder.append(catSw.toString());
1642                        addErrorToDropBox("lowmem", null, "system_server", null,
1643                                null, tag.toString(), dropBuilder.toString(), null, null);
1644                        //Slog.i(TAG, "Sent to dropbox:");
1645                        //Slog.i(TAG, dropBuilder.toString());
1646                        synchronized (ActivityManagerService.this) {
1647                            long now = SystemClock.uptimeMillis();
1648                            if (mLastMemUsageReportTime < now) {
1649                                mLastMemUsageReportTime = now;
1650                            }
1651                        }
1652                    }
1653                };
1654                thread.start();
1655                break;
1656            }
1657            case REPORT_USER_SWITCH_MSG: {
1658                dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1659                break;
1660            }
1661            case CONTINUE_USER_SWITCH_MSG: {
1662                continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1663                break;
1664            }
1665            case USER_SWITCH_TIMEOUT_MSG: {
1666                timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1667                break;
1668            }
1669            case IMMERSIVE_MODE_LOCK_MSG: {
1670                final boolean nextState = (msg.arg1 != 0);
1671                if (mUpdateLock.isHeld() != nextState) {
1672                    if (DEBUG_IMMERSIVE) {
1673                        final ActivityRecord r = (ActivityRecord) msg.obj;
1674                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1675                    }
1676                    if (nextState) {
1677                        mUpdateLock.acquire();
1678                    } else {
1679                        mUpdateLock.release();
1680                    }
1681                }
1682                break;
1683            }
1684            case PERSIST_URI_GRANTS_MSG: {
1685                writeGrantedUriPermissions();
1686                break;
1687            }
1688            case REQUEST_ALL_PSS_MSG: {
1689                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1690                break;
1691            }
1692            case START_RELATED_USERS_MSG: {
1693                synchronized (ActivityManagerService.this) {
1694                    startRelatedUsersLocked();
1695                }
1696                break;
1697            }
1698            case UPDATE_TIME: {
1699                synchronized (ActivityManagerService.this) {
1700                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1701                        ProcessRecord r = mLruProcesses.get(i);
1702                        if (r.thread != null) {
1703                            try {
1704                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1705                            } catch (RemoteException ex) {
1706                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1707                            }
1708                        }
1709                    }
1710                }
1711                break;
1712            }
1713            }
1714        }
1715    };
1716
1717    static final int COLLECT_PSS_BG_MSG = 1;
1718
1719    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1720        @Override
1721        public void handleMessage(Message msg) {
1722            switch (msg.what) {
1723            case COLLECT_PSS_BG_MSG: {
1724                int i=0, num=0;
1725                long start = SystemClock.uptimeMillis();
1726                long[] tmp = new long[1];
1727                do {
1728                    ProcessRecord proc;
1729                    int procState;
1730                    int pid;
1731                    synchronized (ActivityManagerService.this) {
1732                        if (i >= mPendingPssProcesses.size()) {
1733                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1734                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1735                            mPendingPssProcesses.clear();
1736                            return;
1737                        }
1738                        proc = mPendingPssProcesses.get(i);
1739                        procState = proc.pssProcState;
1740                        if (proc.thread != null && procState == proc.setProcState) {
1741                            pid = proc.pid;
1742                        } else {
1743                            proc = null;
1744                            pid = 0;
1745                        }
1746                        i++;
1747                    }
1748                    if (proc != null) {
1749                        long pss = Debug.getPss(pid, tmp);
1750                        synchronized (ActivityManagerService.this) {
1751                            if (proc.thread != null && proc.setProcState == procState
1752                                    && proc.pid == pid) {
1753                                num++;
1754                                proc.lastPssTime = SystemClock.uptimeMillis();
1755                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1756                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1757                                        + ": " + pss + " lastPss=" + proc.lastPss
1758                                        + " state=" + ProcessList.makeProcStateString(procState));
1759                                if (proc.initialIdlePss == 0) {
1760                                    proc.initialIdlePss = pss;
1761                                }
1762                                proc.lastPss = pss;
1763                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1764                                    proc.lastCachedPss = pss;
1765                                }
1766                            }
1767                        }
1768                    }
1769                } while (true);
1770            }
1771            }
1772        }
1773    };
1774
1775    public void setSystemProcess() {
1776        try {
1777            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1778            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1779            ServiceManager.addService("meminfo", new MemBinder(this));
1780            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1781            ServiceManager.addService("dbinfo", new DbBinder(this));
1782            if (MONITOR_CPU_USAGE) {
1783                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1784            }
1785            ServiceManager.addService("permission", new PermissionController(this));
1786
1787            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1788                    "android", STOCK_PM_FLAGS);
1789            mSystemThread.installSystemApplicationInfo(info);
1790
1791            synchronized (this) {
1792                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
1793                app.persistent = true;
1794                app.pid = MY_PID;
1795                app.maxAdj = ProcessList.SYSTEM_ADJ;
1796                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1797                mProcessNames.put(app.processName, app.uid, app);
1798                synchronized (mPidsSelfLocked) {
1799                    mPidsSelfLocked.put(app.pid, app);
1800                }
1801                updateLruProcessLocked(app, false, null);
1802                updateOomAdjLocked();
1803            }
1804        } catch (PackageManager.NameNotFoundException e) {
1805            throw new RuntimeException(
1806                    "Unable to find android system package", e);
1807        }
1808    }
1809
1810    public void setWindowManager(WindowManagerService wm) {
1811        mWindowManager = wm;
1812        mStackSupervisor.setWindowManager(wm);
1813    }
1814
1815    public void startObservingNativeCrashes() {
1816        final NativeCrashListener ncl = new NativeCrashListener(this);
1817        ncl.start();
1818    }
1819
1820    public IAppOpsService getAppOpsService() {
1821        return mAppOpsService;
1822    }
1823
1824    static class MemBinder extends Binder {
1825        ActivityManagerService mActivityManagerService;
1826        MemBinder(ActivityManagerService activityManagerService) {
1827            mActivityManagerService = activityManagerService;
1828        }
1829
1830        @Override
1831        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1832            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1833                    != PackageManager.PERMISSION_GRANTED) {
1834                pw.println("Permission Denial: can't dump meminfo from from pid="
1835                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1836                        + " without permission " + android.Manifest.permission.DUMP);
1837                return;
1838            }
1839
1840            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1841        }
1842    }
1843
1844    static class GraphicsBinder extends Binder {
1845        ActivityManagerService mActivityManagerService;
1846        GraphicsBinder(ActivityManagerService activityManagerService) {
1847            mActivityManagerService = activityManagerService;
1848        }
1849
1850        @Override
1851        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1852            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1853                    != PackageManager.PERMISSION_GRANTED) {
1854                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1855                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1856                        + " without permission " + android.Manifest.permission.DUMP);
1857                return;
1858            }
1859
1860            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1861        }
1862    }
1863
1864    static class DbBinder extends Binder {
1865        ActivityManagerService mActivityManagerService;
1866        DbBinder(ActivityManagerService activityManagerService) {
1867            mActivityManagerService = activityManagerService;
1868        }
1869
1870        @Override
1871        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1872            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1873                    != PackageManager.PERMISSION_GRANTED) {
1874                pw.println("Permission Denial: can't dump dbinfo from from pid="
1875                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1876                        + " without permission " + android.Manifest.permission.DUMP);
1877                return;
1878            }
1879
1880            mActivityManagerService.dumpDbInfo(fd, pw, args);
1881        }
1882    }
1883
1884    static class CpuBinder extends Binder {
1885        ActivityManagerService mActivityManagerService;
1886        CpuBinder(ActivityManagerService activityManagerService) {
1887            mActivityManagerService = activityManagerService;
1888        }
1889
1890        @Override
1891        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1892            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1893                    != PackageManager.PERMISSION_GRANTED) {
1894                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1895                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1896                        + " without permission " + android.Manifest.permission.DUMP);
1897                return;
1898            }
1899
1900            synchronized (mActivityManagerService.mProcessCpuThread) {
1901                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
1902                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
1903                        SystemClock.uptimeMillis()));
1904            }
1905        }
1906    }
1907
1908    public static final class Lifecycle extends SystemService {
1909        private final ActivityManagerService mService;
1910
1911        public Lifecycle(Context context) {
1912            super(context);
1913            mService = new ActivityManagerService(context);
1914        }
1915
1916        @Override
1917        public void onStart() {
1918            mService.start();
1919        }
1920
1921        public ActivityManagerService getService() {
1922            return mService;
1923        }
1924    }
1925
1926    // Note: This method is invoked on the main thread but may need to attach various
1927    // handlers to other threads.  So take care to be explicit about the looper.
1928    public ActivityManagerService(Context systemContext) {
1929        mContext = systemContext;
1930        mFactoryTest = FactoryTest.getMode();
1931        mSystemThread = ActivityThread.currentActivityThread();
1932
1933        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1934
1935        mHandlerThread = new ServiceThread(TAG,
1936                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
1937        mHandlerThread.start();
1938        mHandler = new MainHandler(mHandlerThread.getLooper());
1939
1940        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
1941                "foreground", BROADCAST_FG_TIMEOUT, false);
1942        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
1943                "background", BROADCAST_BG_TIMEOUT, true);
1944        mBroadcastQueues[0] = mFgBroadcastQueue;
1945        mBroadcastQueues[1] = mBgBroadcastQueue;
1946
1947        mServices = new ActiveServices(this);
1948        mProviderMap = new ProviderMap(this);
1949
1950        // TODO: Move creation of battery stats service outside of activity manager service.
1951        File dataDir = Environment.getDataDirectory();
1952        File systemDir = new File(dataDir, "system");
1953        systemDir.mkdirs();
1954        mBatteryStatsService = new BatteryStatsService(new File(
1955                systemDir, "batterystats.bin").toString(), mHandler);
1956        mBatteryStatsService.getActiveStatistics().readLocked();
1957        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1958        mOnBattery = DEBUG_POWER ? true
1959                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1960        mBatteryStatsService.getActiveStatistics().setCallback(this);
1961
1962        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
1963
1964        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
1965        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
1966
1967        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
1968
1969        // User 0 is the first and only user that runs at boot.
1970        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
1971        mUserLru.add(Integer.valueOf(0));
1972        updateStartedUserArrayLocked();
1973
1974        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1975            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1976
1977        mConfiguration.setToDefaults();
1978        mConfiguration.setLocale(Locale.getDefault());
1979
1980        mConfigurationSeq = mConfiguration.seq = 1;
1981        mProcessCpuTracker.init();
1982
1983        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
1984        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
1985        mStackSupervisor = new ActivityStackSupervisor(this);
1986
1987        mProcessCpuThread = new Thread("CpuTracker") {
1988            @Override
1989            public void run() {
1990                while (true) {
1991                    try {
1992                        try {
1993                            synchronized(this) {
1994                                final long now = SystemClock.uptimeMillis();
1995                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1996                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1997                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1998                                //        + ", write delay=" + nextWriteDelay);
1999                                if (nextWriteDelay < nextCpuDelay) {
2000                                    nextCpuDelay = nextWriteDelay;
2001                                }
2002                                if (nextCpuDelay > 0) {
2003                                    mProcessCpuMutexFree.set(true);
2004                                    this.wait(nextCpuDelay);
2005                                }
2006                            }
2007                        } catch (InterruptedException e) {
2008                        }
2009                        updateCpuStatsNow();
2010                    } catch (Exception e) {
2011                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2012                    }
2013                }
2014            }
2015        };
2016
2017        Watchdog.getInstance().addMonitor(this);
2018        Watchdog.getInstance().addThread(mHandler);
2019    }
2020
2021    private void start() {
2022        mProcessCpuThread.start();
2023
2024        mBatteryStatsService.publish(mContext);
2025        mUsageStatsService.publish(mContext);
2026        mAppOpsService.publish(mContext);
2027        startRunning(null, null, null, null);
2028    }
2029
2030    @Override
2031    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2032            throws RemoteException {
2033        if (code == SYSPROPS_TRANSACTION) {
2034            // We need to tell all apps about the system property change.
2035            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2036            synchronized(this) {
2037                final int NP = mProcessNames.getMap().size();
2038                for (int ip=0; ip<NP; ip++) {
2039                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2040                    final int NA = apps.size();
2041                    for (int ia=0; ia<NA; ia++) {
2042                        ProcessRecord app = apps.valueAt(ia);
2043                        if (app.thread != null) {
2044                            procs.add(app.thread.asBinder());
2045                        }
2046                    }
2047                }
2048            }
2049
2050            int N = procs.size();
2051            for (int i=0; i<N; i++) {
2052                Parcel data2 = Parcel.obtain();
2053                try {
2054                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2055                } catch (RemoteException e) {
2056                }
2057                data2.recycle();
2058            }
2059        }
2060        try {
2061            return super.onTransact(code, data, reply, flags);
2062        } catch (RuntimeException e) {
2063            // The activity manager only throws security exceptions, so let's
2064            // log all others.
2065            if (!(e instanceof SecurityException)) {
2066                Slog.wtf(TAG, "Activity Manager Crash", e);
2067            }
2068            throw e;
2069        }
2070    }
2071
2072    void updateCpuStats() {
2073        final long now = SystemClock.uptimeMillis();
2074        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2075            return;
2076        }
2077        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2078            synchronized (mProcessCpuThread) {
2079                mProcessCpuThread.notify();
2080            }
2081        }
2082    }
2083
2084    void updateCpuStatsNow() {
2085        synchronized (mProcessCpuThread) {
2086            mProcessCpuMutexFree.set(false);
2087            final long now = SystemClock.uptimeMillis();
2088            boolean haveNewCpuStats = false;
2089
2090            if (MONITOR_CPU_USAGE &&
2091                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2092                mLastCpuTime.set(now);
2093                haveNewCpuStats = true;
2094                mProcessCpuTracker.update();
2095                //Slog.i(TAG, mProcessCpu.printCurrentState());
2096                //Slog.i(TAG, "Total CPU usage: "
2097                //        + mProcessCpu.getTotalCpuPercent() + "%");
2098
2099                // Slog the cpu usage if the property is set.
2100                if ("true".equals(SystemProperties.get("events.cpu"))) {
2101                    int user = mProcessCpuTracker.getLastUserTime();
2102                    int system = mProcessCpuTracker.getLastSystemTime();
2103                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2104                    int irq = mProcessCpuTracker.getLastIrqTime();
2105                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2106                    int idle = mProcessCpuTracker.getLastIdleTime();
2107
2108                    int total = user + system + iowait + irq + softIrq + idle;
2109                    if (total == 0) total = 1;
2110
2111                    EventLog.writeEvent(EventLogTags.CPU,
2112                            ((user+system+iowait+irq+softIrq) * 100) / total,
2113                            (user * 100) / total,
2114                            (system * 100) / total,
2115                            (iowait * 100) / total,
2116                            (irq * 100) / total,
2117                            (softIrq * 100) / total);
2118                }
2119            }
2120
2121            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2122            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2123            synchronized(bstats) {
2124                synchronized(mPidsSelfLocked) {
2125                    if (haveNewCpuStats) {
2126                        if (mOnBattery) {
2127                            int perc = bstats.startAddingCpuLocked();
2128                            int totalUTime = 0;
2129                            int totalSTime = 0;
2130                            final int N = mProcessCpuTracker.countStats();
2131                            for (int i=0; i<N; i++) {
2132                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2133                                if (!st.working) {
2134                                    continue;
2135                                }
2136                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2137                                int otherUTime = (st.rel_utime*perc)/100;
2138                                int otherSTime = (st.rel_stime*perc)/100;
2139                                totalUTime += otherUTime;
2140                                totalSTime += otherSTime;
2141                                if (pr != null) {
2142                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2143                                    if (ps == null || !ps.isActive()) {
2144                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2145                                                pr.info.uid, pr.processName);
2146                                    }
2147                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2148                                            st.rel_stime-otherSTime);
2149                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2150                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2151                                } else {
2152                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2153                                    if (ps == null || !ps.isActive()) {
2154                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2155                                                bstats.mapUid(st.uid), st.name);
2156                                    }
2157                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2158                                            st.rel_stime-otherSTime);
2159                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2160                                }
2161                            }
2162                            bstats.finishAddingCpuLocked(perc, totalUTime,
2163                                    totalSTime, cpuSpeedTimes);
2164                        }
2165                    }
2166                }
2167
2168                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2169                    mLastWriteTime = now;
2170                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2171                }
2172            }
2173        }
2174    }
2175
2176    @Override
2177    public void batteryNeedsCpuUpdate() {
2178        updateCpuStatsNow();
2179    }
2180
2181    @Override
2182    public void batteryPowerChanged(boolean onBattery) {
2183        // When plugging in, update the CPU stats first before changing
2184        // the plug state.
2185        updateCpuStatsNow();
2186        synchronized (this) {
2187            synchronized(mPidsSelfLocked) {
2188                mOnBattery = DEBUG_POWER ? true : onBattery;
2189            }
2190        }
2191    }
2192
2193    /**
2194     * Initialize the application bind args. These are passed to each
2195     * process when the bindApplication() IPC is sent to the process. They're
2196     * lazily setup to make sure the services are running when they're asked for.
2197     */
2198    private HashMap<String, IBinder> getCommonServicesLocked() {
2199        if (mAppBindArgs == null) {
2200            mAppBindArgs = new HashMap<String, IBinder>();
2201
2202            // Setup the application init args
2203            mAppBindArgs.put("package", ServiceManager.getService("package"));
2204            mAppBindArgs.put("window", ServiceManager.getService("window"));
2205            mAppBindArgs.put(Context.ALARM_SERVICE,
2206                    ServiceManager.getService(Context.ALARM_SERVICE));
2207        }
2208        return mAppBindArgs;
2209    }
2210
2211    final void setFocusedActivityLocked(ActivityRecord r) {
2212        if (mFocusedActivity != r) {
2213            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2214            mFocusedActivity = r;
2215            mStackSupervisor.setFocusedStack(r);
2216            if (r != null) {
2217                mWindowManager.setFocusedApp(r.appToken, true);
2218            }
2219            applyUpdateLockStateLocked(r);
2220        }
2221    }
2222
2223    @Override
2224    public void setFocusedStack(int stackId) {
2225        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2226        synchronized (ActivityManagerService.this) {
2227            ActivityStack stack = mStackSupervisor.getStack(stackId);
2228            if (stack != null) {
2229                ActivityRecord r = stack.topRunningActivityLocked(null);
2230                if (r != null) {
2231                    setFocusedActivityLocked(r);
2232                }
2233            }
2234        }
2235    }
2236
2237    @Override
2238    public void notifyActivityDrawn(IBinder token) {
2239        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2240        synchronized (this) {
2241            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2242            if (r != null) {
2243                r.task.stack.notifyActivityDrawnLocked(r);
2244            }
2245        }
2246    }
2247
2248    final void applyUpdateLockStateLocked(ActivityRecord r) {
2249        // Modifications to the UpdateLock state are done on our handler, outside
2250        // the activity manager's locks.  The new state is determined based on the
2251        // state *now* of the relevant activity record.  The object is passed to
2252        // the handler solely for logging detail, not to be consulted/modified.
2253        final boolean nextState = r != null && r.immersive;
2254        mHandler.sendMessage(
2255                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2256    }
2257
2258    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2259        Message msg = Message.obtain();
2260        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2261        msg.obj = r.task.askedCompatMode ? null : r;
2262        mHandler.sendMessage(msg);
2263    }
2264
2265    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2266            String what, Object obj, ProcessRecord srcApp) {
2267        app.lastActivityTime = now;
2268
2269        if (app.activities.size() > 0) {
2270            // Don't want to touch dependent processes that are hosting activities.
2271            return index;
2272        }
2273
2274        int lrui = mLruProcesses.lastIndexOf(app);
2275        if (lrui < 0) {
2276            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2277                    + what + " " + obj + " from " + srcApp);
2278            return index;
2279        }
2280
2281        if (lrui >= index) {
2282            // Don't want to cause this to move dependent processes *back* in the
2283            // list as if they were less frequently used.
2284            return index;
2285        }
2286
2287        if (lrui >= mLruProcessActivityStart) {
2288            // Don't want to touch dependent processes that are hosting activities.
2289            return index;
2290        }
2291
2292        mLruProcesses.remove(lrui);
2293        if (index > 0) {
2294            index--;
2295        }
2296        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2297                + " in LRU list: " + app);
2298        mLruProcesses.add(index, app);
2299        return index;
2300    }
2301
2302    final void removeLruProcessLocked(ProcessRecord app) {
2303        int lrui = mLruProcesses.lastIndexOf(app);
2304        if (lrui >= 0) {
2305            if (lrui <= mLruProcessActivityStart) {
2306                mLruProcessActivityStart--;
2307            }
2308            if (lrui <= mLruProcessServiceStart) {
2309                mLruProcessServiceStart--;
2310            }
2311            mLruProcesses.remove(lrui);
2312        }
2313    }
2314
2315    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2316            ProcessRecord client) {
2317        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2318                || app.treatLikeActivity;
2319        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2320        if (!activityChange && hasActivity) {
2321            // The process has activities, so we are only allowing activity-based adjustments
2322            // to move it.  It should be kept in the front of the list with other
2323            // processes that have activities, and we don't want those to change their
2324            // order except due to activity operations.
2325            return;
2326        }
2327
2328        mLruSeq++;
2329        final long now = SystemClock.uptimeMillis();
2330        app.lastActivityTime = now;
2331
2332        // First a quick reject: if the app is already at the position we will
2333        // put it, then there is nothing to do.
2334        if (hasActivity) {
2335            final int N = mLruProcesses.size();
2336            if (N > 0 && mLruProcesses.get(N-1) == app) {
2337                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2338                return;
2339            }
2340        } else {
2341            if (mLruProcessServiceStart > 0
2342                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2343                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2344                return;
2345            }
2346        }
2347
2348        int lrui = mLruProcesses.lastIndexOf(app);
2349
2350        if (app.persistent && lrui >= 0) {
2351            // We don't care about the position of persistent processes, as long as
2352            // they are in the list.
2353            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2354            return;
2355        }
2356
2357        /* In progress: compute new position first, so we can avoid doing work
2358           if the process is not actually going to move.  Not yet working.
2359        int addIndex;
2360        int nextIndex;
2361        boolean inActivity = false, inService = false;
2362        if (hasActivity) {
2363            // Process has activities, put it at the very tipsy-top.
2364            addIndex = mLruProcesses.size();
2365            nextIndex = mLruProcessServiceStart;
2366            inActivity = true;
2367        } else if (hasService) {
2368            // Process has services, put it at the top of the service list.
2369            addIndex = mLruProcessActivityStart;
2370            nextIndex = mLruProcessServiceStart;
2371            inActivity = true;
2372            inService = true;
2373        } else  {
2374            // Process not otherwise of interest, it goes to the top of the non-service area.
2375            addIndex = mLruProcessServiceStart;
2376            if (client != null) {
2377                int clientIndex = mLruProcesses.lastIndexOf(client);
2378                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2379                        + app);
2380                if (clientIndex >= 0 && addIndex > clientIndex) {
2381                    addIndex = clientIndex;
2382                }
2383            }
2384            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2385        }
2386
2387        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2388                + mLruProcessActivityStart + "): " + app);
2389        */
2390
2391        if (lrui >= 0) {
2392            if (lrui < mLruProcessActivityStart) {
2393                mLruProcessActivityStart--;
2394            }
2395            if (lrui < mLruProcessServiceStart) {
2396                mLruProcessServiceStart--;
2397            }
2398            /*
2399            if (addIndex > lrui) {
2400                addIndex--;
2401            }
2402            if (nextIndex > lrui) {
2403                nextIndex--;
2404            }
2405            */
2406            mLruProcesses.remove(lrui);
2407        }
2408
2409        /*
2410        mLruProcesses.add(addIndex, app);
2411        if (inActivity) {
2412            mLruProcessActivityStart++;
2413        }
2414        if (inService) {
2415            mLruProcessActivityStart++;
2416        }
2417        */
2418
2419        int nextIndex;
2420        if (hasActivity) {
2421            final int N = mLruProcesses.size();
2422            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2423                // Process doesn't have activities, but has clients with
2424                // activities...  move it up, but one below the top (the top
2425                // should always have a real activity).
2426                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2427                mLruProcesses.add(N-1, app);
2428                // To keep it from spamming the LRU list (by making a bunch of clients),
2429                // we will push down any other entries owned by the app.
2430                final int uid = app.info.uid;
2431                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2432                    ProcessRecord subProc = mLruProcesses.get(i);
2433                    if (subProc.info.uid == uid) {
2434                        // We want to push this one down the list.  If the process after
2435                        // it is for the same uid, however, don't do so, because we don't
2436                        // want them internally to be re-ordered.
2437                        if (mLruProcesses.get(i-1).info.uid != uid) {
2438                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2439                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2440                            ProcessRecord tmp = mLruProcesses.get(i);
2441                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2442                            mLruProcesses.set(i-1, tmp);
2443                            i--;
2444                        }
2445                    } else {
2446                        // A gap, we can stop here.
2447                        break;
2448                    }
2449                }
2450            } else {
2451                // Process has activities, put it at the very tipsy-top.
2452                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2453                mLruProcesses.add(app);
2454            }
2455            nextIndex = mLruProcessServiceStart;
2456        } else if (hasService) {
2457            // Process has services, put it at the top of the service list.
2458            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2459            mLruProcesses.add(mLruProcessActivityStart, app);
2460            nextIndex = mLruProcessServiceStart;
2461            mLruProcessActivityStart++;
2462        } else  {
2463            // Process not otherwise of interest, it goes to the top of the non-service area.
2464            int index = mLruProcessServiceStart;
2465            if (client != null) {
2466                // If there is a client, don't allow the process to be moved up higher
2467                // in the list than that client.
2468                int clientIndex = mLruProcesses.lastIndexOf(client);
2469                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2470                        + " when updating " + app);
2471                if (clientIndex <= lrui) {
2472                    // Don't allow the client index restriction to push it down farther in the
2473                    // list than it already is.
2474                    clientIndex = lrui;
2475                }
2476                if (clientIndex >= 0 && index > clientIndex) {
2477                    index = clientIndex;
2478                }
2479            }
2480            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2481            mLruProcesses.add(index, app);
2482            nextIndex = index-1;
2483            mLruProcessActivityStart++;
2484            mLruProcessServiceStart++;
2485        }
2486
2487        // If the app is currently using a content provider or service,
2488        // bump those processes as well.
2489        for (int j=app.connections.size()-1; j>=0; j--) {
2490            ConnectionRecord cr = app.connections.valueAt(j);
2491            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2492                    && cr.binding.service.app != null
2493                    && cr.binding.service.app.lruSeq != mLruSeq
2494                    && !cr.binding.service.app.persistent) {
2495                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2496                        "service connection", cr, app);
2497            }
2498        }
2499        for (int j=app.conProviders.size()-1; j>=0; j--) {
2500            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2501            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2502                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2503                        "provider reference", cpr, app);
2504            }
2505        }
2506    }
2507
2508    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2509        if (uid == Process.SYSTEM_UID) {
2510            // The system gets to run in any process.  If there are multiple
2511            // processes with the same uid, just pick the first (this
2512            // should never happen).
2513            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2514            if (procs == null) return null;
2515            final int N = procs.size();
2516            for (int i = 0; i < N; i++) {
2517                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2518            }
2519        }
2520        ProcessRecord proc = mProcessNames.get(processName, uid);
2521        if (false && proc != null && !keepIfLarge
2522                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2523                && proc.lastCachedPss >= 4000) {
2524            // Turn this condition on to cause killing to happen regularly, for testing.
2525            if (proc.baseProcessTracker != null) {
2526                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2527            }
2528            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2529                    + "k from cached");
2530        } else if (proc != null && !keepIfLarge
2531                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2532                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2533            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2534            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2535                if (proc.baseProcessTracker != null) {
2536                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2537                }
2538                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2539                        + "k from cached");
2540            }
2541        }
2542        return proc;
2543    }
2544
2545    void ensurePackageDexOpt(String packageName) {
2546        IPackageManager pm = AppGlobals.getPackageManager();
2547        try {
2548            if (pm.performDexOpt(packageName)) {
2549                mDidDexOpt = true;
2550            }
2551        } catch (RemoteException e) {
2552        }
2553    }
2554
2555    boolean isNextTransitionForward() {
2556        int transit = mWindowManager.getPendingAppTransition();
2557        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2558                || transit == AppTransition.TRANSIT_TASK_OPEN
2559                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2560    }
2561
2562    final ProcessRecord startProcessLocked(String processName,
2563            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2564            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2565            boolean isolated, boolean keepIfLarge) {
2566        ProcessRecord app;
2567        if (!isolated) {
2568            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2569        } else {
2570            // If this is an isolated process, it can't re-use an existing process.
2571            app = null;
2572        }
2573        // We don't have to do anything more if:
2574        // (1) There is an existing application record; and
2575        // (2) The caller doesn't think it is dead, OR there is no thread
2576        //     object attached to it so we know it couldn't have crashed; and
2577        // (3) There is a pid assigned to it, so it is either starting or
2578        //     already running.
2579        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2580                + " app=" + app + " knownToBeDead=" + knownToBeDead
2581                + " thread=" + (app != null ? app.thread : null)
2582                + " pid=" + (app != null ? app.pid : -1));
2583        if (app != null && app.pid > 0) {
2584            if (!knownToBeDead || app.thread == null) {
2585                // We already have the app running, or are waiting for it to
2586                // come up (we have a pid but not yet its thread), so keep it.
2587                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2588                // If this is a new package in the process, add the package to the list
2589                app.addPackage(info.packageName, mProcessStats);
2590                return app;
2591            }
2592
2593            // An application record is attached to a previous process,
2594            // clean it up now.
2595            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2596            handleAppDiedLocked(app, true, true);
2597        }
2598
2599        String hostingNameStr = hostingName != null
2600                ? hostingName.flattenToShortString() : null;
2601
2602        if (!isolated) {
2603            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2604                // If we are in the background, then check to see if this process
2605                // is bad.  If so, we will just silently fail.
2606                if (mBadProcesses.get(info.processName, info.uid) != null) {
2607                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2608                            + "/" + info.processName);
2609                    return null;
2610                }
2611            } else {
2612                // When the user is explicitly starting a process, then clear its
2613                // crash count so that we won't make it bad until they see at
2614                // least one crash dialog again, and make the process good again
2615                // if it had been bad.
2616                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2617                        + "/" + info.processName);
2618                mProcessCrashTimes.remove(info.processName, info.uid);
2619                if (mBadProcesses.get(info.processName, info.uid) != null) {
2620                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2621                            UserHandle.getUserId(info.uid), info.uid,
2622                            info.processName);
2623                    mBadProcesses.remove(info.processName, info.uid);
2624                    if (app != null) {
2625                        app.bad = false;
2626                    }
2627                }
2628            }
2629        }
2630
2631        if (app == null) {
2632            app = newProcessRecordLocked(info, processName, isolated);
2633            if (app == null) {
2634                Slog.w(TAG, "Failed making new process record for "
2635                        + processName + "/" + info.uid + " isolated=" + isolated);
2636                return null;
2637            }
2638            mProcessNames.put(processName, app.uid, app);
2639            if (isolated) {
2640                mIsolatedProcesses.put(app.uid, app);
2641            }
2642        } else {
2643            // If this is a new package in the process, add the package to the list
2644            app.addPackage(info.packageName, mProcessStats);
2645        }
2646
2647        // If the system is not ready yet, then hold off on starting this
2648        // process until it is.
2649        if (!mProcessesReady
2650                && !isAllowedWhileBooting(info)
2651                && !allowWhileBooting) {
2652            if (!mProcessesOnHold.contains(app)) {
2653                mProcessesOnHold.add(app);
2654            }
2655            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2656            return app;
2657        }
2658
2659        startProcessLocked(app, hostingType, hostingNameStr);
2660        return (app.pid != 0) ? app : null;
2661    }
2662
2663    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2664        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2665    }
2666
2667    private final void startProcessLocked(ProcessRecord app,
2668            String hostingType, String hostingNameStr) {
2669        if (app.pid > 0 && app.pid != MY_PID) {
2670            synchronized (mPidsSelfLocked) {
2671                mPidsSelfLocked.remove(app.pid);
2672                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2673            }
2674            app.setPid(0);
2675        }
2676
2677        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2678                "startProcessLocked removing on hold: " + app);
2679        mProcessesOnHold.remove(app);
2680
2681        updateCpuStats();
2682
2683        try {
2684            int uid = app.uid;
2685
2686            int[] gids = null;
2687            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2688            if (!app.isolated) {
2689                int[] permGids = null;
2690                try {
2691                    final PackageManager pm = mContext.getPackageManager();
2692                    permGids = pm.getPackageGids(app.info.packageName);
2693
2694                    if (Environment.isExternalStorageEmulated()) {
2695                        if (pm.checkPermission(
2696                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2697                                app.info.packageName) == PERMISSION_GRANTED) {
2698                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2699                        } else {
2700                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2701                        }
2702                    }
2703                } catch (PackageManager.NameNotFoundException e) {
2704                    Slog.w(TAG, "Unable to retrieve gids", e);
2705                }
2706
2707                /*
2708                 * Add shared application GID so applications can share some
2709                 * resources like shared libraries
2710                 */
2711                if (permGids == null) {
2712                    gids = new int[1];
2713                } else {
2714                    gids = new int[permGids.length + 1];
2715                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2716                }
2717                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2718            }
2719            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2720                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2721                        && mTopComponent != null
2722                        && app.processName.equals(mTopComponent.getPackageName())) {
2723                    uid = 0;
2724                }
2725                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2726                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2727                    uid = 0;
2728                }
2729            }
2730            int debugFlags = 0;
2731            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2732                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2733                // Also turn on CheckJNI for debuggable apps. It's quite
2734                // awkward to turn on otherwise.
2735                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2736            }
2737            // Run the app in safe mode if its manifest requests so or the
2738            // system is booted in safe mode.
2739            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2740                Zygote.systemInSafeMode == true) {
2741                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2742            }
2743            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2744                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2745            }
2746            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2747                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2748            }
2749            if ("1".equals(SystemProperties.get("debug.assert"))) {
2750                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2751            }
2752
2753            // Start the process.  It will either succeed and return a result containing
2754            // the PID of the new process, or else throw a RuntimeException.
2755            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2756                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2757                    app.info.targetSdkVersion, app.info.seinfo, null);
2758
2759            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2760            synchronized (bs) {
2761                if (bs.isOnBattery()) {
2762                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2763                }
2764            }
2765
2766            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2767                    UserHandle.getUserId(uid), startResult.pid, uid,
2768                    app.processName, hostingType,
2769                    hostingNameStr != null ? hostingNameStr : "");
2770
2771            if (app.persistent) {
2772                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2773            }
2774
2775            StringBuilder buf = mStringBuilder;
2776            buf.setLength(0);
2777            buf.append("Start proc ");
2778            buf.append(app.processName);
2779            buf.append(" for ");
2780            buf.append(hostingType);
2781            if (hostingNameStr != null) {
2782                buf.append(" ");
2783                buf.append(hostingNameStr);
2784            }
2785            buf.append(": pid=");
2786            buf.append(startResult.pid);
2787            buf.append(" uid=");
2788            buf.append(uid);
2789            buf.append(" gids={");
2790            if (gids != null) {
2791                for (int gi=0; gi<gids.length; gi++) {
2792                    if (gi != 0) buf.append(", ");
2793                    buf.append(gids[gi]);
2794
2795                }
2796            }
2797            buf.append("}");
2798            Slog.i(TAG, buf.toString());
2799            app.setPid(startResult.pid);
2800            app.usingWrapper = startResult.usingWrapper;
2801            app.removed = false;
2802            synchronized (mPidsSelfLocked) {
2803                this.mPidsSelfLocked.put(startResult.pid, app);
2804                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2805                msg.obj = app;
2806                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2807                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2808            }
2809            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
2810                    app.processName, app.info.uid);
2811            if (app.isolated) {
2812                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2813            }
2814        } catch (RuntimeException e) {
2815            // XXX do better error recovery.
2816            app.setPid(0);
2817            Slog.e(TAG, "Failure starting process " + app.processName, e);
2818        }
2819    }
2820
2821    void updateUsageStats(ActivityRecord component, boolean resumed) {
2822        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
2823        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2824        if (resumed) {
2825            mUsageStatsService.noteResumeComponent(component.realActivity);
2826            synchronized (stats) {
2827                stats.noteActivityResumedLocked(component.app.uid);
2828            }
2829        } else {
2830            mUsageStatsService.notePauseComponent(component.realActivity);
2831            synchronized (stats) {
2832                stats.noteActivityPausedLocked(component.app.uid);
2833            }
2834        }
2835    }
2836
2837    Intent getHomeIntent() {
2838        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
2839        intent.setComponent(mTopComponent);
2840        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
2841            intent.addCategory(Intent.CATEGORY_HOME);
2842        }
2843        return intent;
2844    }
2845
2846    boolean startHomeActivityLocked(int userId) {
2847        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2848                && mTopAction == null) {
2849            // We are running in factory test mode, but unable to find
2850            // the factory test app, so just sit around displaying the
2851            // error message and don't try to start anything.
2852            return false;
2853        }
2854        Intent intent = getHomeIntent();
2855        ActivityInfo aInfo =
2856            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2857        if (aInfo != null) {
2858            intent.setComponent(new ComponentName(
2859                    aInfo.applicationInfo.packageName, aInfo.name));
2860            // Don't do this if the home app is currently being
2861            // instrumented.
2862            aInfo = new ActivityInfo(aInfo);
2863            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2864            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2865                    aInfo.applicationInfo.uid, true);
2866            if (app == null || app.instrumentationClass == null) {
2867                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2868                mStackSupervisor.startHomeActivity(intent, aInfo);
2869            }
2870        }
2871
2872        return true;
2873    }
2874
2875    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2876        ActivityInfo ai = null;
2877        ComponentName comp = intent.getComponent();
2878        try {
2879            if (comp != null) {
2880                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2881            } else {
2882                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2883                        intent,
2884                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2885                            flags, userId);
2886
2887                if (info != null) {
2888                    ai = info.activityInfo;
2889                }
2890            }
2891        } catch (RemoteException e) {
2892            // ignore
2893        }
2894
2895        return ai;
2896    }
2897
2898    /**
2899     * Starts the "new version setup screen" if appropriate.
2900     */
2901    void startSetupActivityLocked() {
2902        // Only do this once per boot.
2903        if (mCheckedForSetup) {
2904            return;
2905        }
2906
2907        // We will show this screen if the current one is a different
2908        // version than the last one shown, and we are not running in
2909        // low-level factory test mode.
2910        final ContentResolver resolver = mContext.getContentResolver();
2911        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
2912                Settings.Global.getInt(resolver,
2913                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
2914            mCheckedForSetup = true;
2915
2916            // See if we should be showing the platform update setup UI.
2917            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2918            List<ResolveInfo> ris = mContext.getPackageManager()
2919                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2920
2921            // We don't allow third party apps to replace this.
2922            ResolveInfo ri = null;
2923            for (int i=0; ris != null && i<ris.size(); i++) {
2924                if ((ris.get(i).activityInfo.applicationInfo.flags
2925                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2926                    ri = ris.get(i);
2927                    break;
2928                }
2929            }
2930
2931            if (ri != null) {
2932                String vers = ri.activityInfo.metaData != null
2933                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2934                        : null;
2935                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2936                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2937                            Intent.METADATA_SETUP_VERSION);
2938                }
2939                String lastVers = Settings.Secure.getString(
2940                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2941                if (vers != null && !vers.equals(lastVers)) {
2942                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2943                    intent.setComponent(new ComponentName(
2944                            ri.activityInfo.packageName, ri.activityInfo.name));
2945                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
2946                            null, null, 0, 0, 0, null, 0, null, false, null, null);
2947                }
2948            }
2949        }
2950    }
2951
2952    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2953        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2954    }
2955
2956    void enforceNotIsolatedCaller(String caller) {
2957        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2958            throw new SecurityException("Isolated process not allowed to call " + caller);
2959        }
2960    }
2961
2962    @Override
2963    public int getFrontActivityScreenCompatMode() {
2964        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2965        synchronized (this) {
2966            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2967        }
2968    }
2969
2970    @Override
2971    public void setFrontActivityScreenCompatMode(int mode) {
2972        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2973                "setFrontActivityScreenCompatMode");
2974        synchronized (this) {
2975            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2976        }
2977    }
2978
2979    @Override
2980    public int getPackageScreenCompatMode(String packageName) {
2981        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2982        synchronized (this) {
2983            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2984        }
2985    }
2986
2987    @Override
2988    public void setPackageScreenCompatMode(String packageName, int mode) {
2989        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2990                "setPackageScreenCompatMode");
2991        synchronized (this) {
2992            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2993        }
2994    }
2995
2996    @Override
2997    public boolean getPackageAskScreenCompat(String packageName) {
2998        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2999        synchronized (this) {
3000            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3001        }
3002    }
3003
3004    @Override
3005    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3006        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3007                "setPackageAskScreenCompat");
3008        synchronized (this) {
3009            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3010        }
3011    }
3012
3013    private void dispatchProcessesChanged() {
3014        int N;
3015        synchronized (this) {
3016            N = mPendingProcessChanges.size();
3017            if (mActiveProcessChanges.length < N) {
3018                mActiveProcessChanges = new ProcessChangeItem[N];
3019            }
3020            mPendingProcessChanges.toArray(mActiveProcessChanges);
3021            mAvailProcessChanges.addAll(mPendingProcessChanges);
3022            mPendingProcessChanges.clear();
3023            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3024        }
3025
3026        int i = mProcessObservers.beginBroadcast();
3027        while (i > 0) {
3028            i--;
3029            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3030            if (observer != null) {
3031                try {
3032                    for (int j=0; j<N; j++) {
3033                        ProcessChangeItem item = mActiveProcessChanges[j];
3034                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3035                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3036                                    + item.pid + " uid=" + item.uid + ": "
3037                                    + item.foregroundActivities);
3038                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3039                                    item.foregroundActivities);
3040                        }
3041                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
3042                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
3043                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
3044                            observer.onImportanceChanged(item.pid, item.uid,
3045                                    item.importance);
3046                        }
3047                    }
3048                } catch (RemoteException e) {
3049                }
3050            }
3051        }
3052        mProcessObservers.finishBroadcast();
3053    }
3054
3055    private void dispatchProcessDied(int pid, int uid) {
3056        int i = mProcessObservers.beginBroadcast();
3057        while (i > 0) {
3058            i--;
3059            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3060            if (observer != null) {
3061                try {
3062                    observer.onProcessDied(pid, uid);
3063                } catch (RemoteException e) {
3064                }
3065            }
3066        }
3067        mProcessObservers.finishBroadcast();
3068    }
3069
3070    final void doPendingActivityLaunchesLocked(boolean doResume) {
3071        final int N = mPendingActivityLaunches.size();
3072        if (N <= 0) {
3073            return;
3074        }
3075        for (int i=0; i<N; i++) {
3076            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3077            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags,
3078                    doResume && i == (N-1), null);
3079        }
3080        mPendingActivityLaunches.clear();
3081    }
3082
3083    @Override
3084    public final int startActivity(IApplicationThread caller, String callingPackage,
3085            Intent intent, String resolvedType, IBinder resultTo,
3086            String resultWho, int requestCode, int startFlags,
3087            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3088        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3089                resultWho, requestCode,
3090                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3091    }
3092
3093    @Override
3094    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3095            Intent intent, String resolvedType, IBinder resultTo,
3096            String resultWho, int requestCode, int startFlags,
3097            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3098        enforceNotIsolatedCaller("startActivity");
3099        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3100                false, true, "startActivity", null);
3101        // TODO: Switch to user app stacks here.
3102        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3103                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3104                null, null, options, userId, null);
3105    }
3106
3107    @Override
3108    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3109            Intent intent, String resolvedType, IBinder resultTo,
3110            String resultWho, int requestCode, int startFlags, String profileFile,
3111            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3112        enforceNotIsolatedCaller("startActivityAndWait");
3113        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3114                false, true, "startActivityAndWait", null);
3115        WaitResult res = new WaitResult();
3116        // TODO: Switch to user app stacks here.
3117        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3118                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3119                res, null, options, UserHandle.getCallingUserId(), null);
3120        return res;
3121    }
3122
3123    @Override
3124    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3125            Intent intent, String resolvedType, IBinder resultTo,
3126            String resultWho, int requestCode, int startFlags, Configuration config,
3127            Bundle options, int userId) {
3128        enforceNotIsolatedCaller("startActivityWithConfig");
3129        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3130                false, true, "startActivityWithConfig", null);
3131        // TODO: Switch to user app stacks here.
3132        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3133                resolvedType, resultTo, resultWho, requestCode, startFlags,
3134                null, null, null, config, options, userId, null);
3135        return ret;
3136    }
3137
3138    @Override
3139    public int startActivityIntentSender(IApplicationThread caller,
3140            IntentSender intent, Intent fillInIntent, String resolvedType,
3141            IBinder resultTo, String resultWho, int requestCode,
3142            int flagsMask, int flagsValues, Bundle options) {
3143        enforceNotIsolatedCaller("startActivityIntentSender");
3144        // Refuse possible leaked file descriptors
3145        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3146            throw new IllegalArgumentException("File descriptors passed in Intent");
3147        }
3148
3149        IIntentSender sender = intent.getTarget();
3150        if (!(sender instanceof PendingIntentRecord)) {
3151            throw new IllegalArgumentException("Bad PendingIntent object");
3152        }
3153
3154        PendingIntentRecord pir = (PendingIntentRecord)sender;
3155
3156        synchronized (this) {
3157            // If this is coming from the currently resumed activity, it is
3158            // effectively saying that app switches are allowed at this point.
3159            final ActivityStack stack = getFocusedStack();
3160            if (stack.mResumedActivity != null &&
3161                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3162                mAppSwitchesAllowedTime = 0;
3163            }
3164        }
3165        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3166                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3167        return ret;
3168    }
3169
3170    @Override
3171    public boolean startNextMatchingActivity(IBinder callingActivity,
3172            Intent intent, Bundle options) {
3173        // Refuse possible leaked file descriptors
3174        if (intent != null && intent.hasFileDescriptors() == true) {
3175            throw new IllegalArgumentException("File descriptors passed in Intent");
3176        }
3177
3178        synchronized (this) {
3179            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3180            if (r == null) {
3181                ActivityOptions.abort(options);
3182                return false;
3183            }
3184            if (r.app == null || r.app.thread == null) {
3185                // The caller is not running...  d'oh!
3186                ActivityOptions.abort(options);
3187                return false;
3188            }
3189            intent = new Intent(intent);
3190            // The caller is not allowed to change the data.
3191            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3192            // And we are resetting to find the next component...
3193            intent.setComponent(null);
3194
3195            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3196
3197            ActivityInfo aInfo = null;
3198            try {
3199                List<ResolveInfo> resolves =
3200                    AppGlobals.getPackageManager().queryIntentActivities(
3201                            intent, r.resolvedType,
3202                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3203                            UserHandle.getCallingUserId());
3204
3205                // Look for the original activity in the list...
3206                final int N = resolves != null ? resolves.size() : 0;
3207                for (int i=0; i<N; i++) {
3208                    ResolveInfo rInfo = resolves.get(i);
3209                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3210                            && rInfo.activityInfo.name.equals(r.info.name)) {
3211                        // We found the current one...  the next matching is
3212                        // after it.
3213                        i++;
3214                        if (i<N) {
3215                            aInfo = resolves.get(i).activityInfo;
3216                        }
3217                        if (debug) {
3218                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3219                                    + "/" + r.info.name);
3220                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3221                                    + "/" + aInfo.name);
3222                        }
3223                        break;
3224                    }
3225                }
3226            } catch (RemoteException e) {
3227            }
3228
3229            if (aInfo == null) {
3230                // Nobody who is next!
3231                ActivityOptions.abort(options);
3232                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3233                return false;
3234            }
3235
3236            intent.setComponent(new ComponentName(
3237                    aInfo.applicationInfo.packageName, aInfo.name));
3238            intent.setFlags(intent.getFlags()&~(
3239                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3240                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3241                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3242                    Intent.FLAG_ACTIVITY_NEW_TASK));
3243
3244            // Okay now we need to start the new activity, replacing the
3245            // currently running activity.  This is a little tricky because
3246            // we want to start the new one as if the current one is finished,
3247            // but not finish the current one first so that there is no flicker.
3248            // And thus...
3249            final boolean wasFinishing = r.finishing;
3250            r.finishing = true;
3251
3252            // Propagate reply information over to the new activity.
3253            final ActivityRecord resultTo = r.resultTo;
3254            final String resultWho = r.resultWho;
3255            final int requestCode = r.requestCode;
3256            r.resultTo = null;
3257            if (resultTo != null) {
3258                resultTo.removeResultsLocked(r, resultWho, requestCode);
3259            }
3260
3261            final long origId = Binder.clearCallingIdentity();
3262            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3263                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
3264                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3265                    options, false, null, null);
3266            Binder.restoreCallingIdentity(origId);
3267
3268            r.finishing = wasFinishing;
3269            if (res != ActivityManager.START_SUCCESS) {
3270                return false;
3271            }
3272            return true;
3273        }
3274    }
3275
3276    final int startActivityInPackage(int uid, String callingPackage,
3277            Intent intent, String resolvedType, IBinder resultTo,
3278            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3279                    IActivityContainer container) {
3280
3281        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3282                false, true, "startActivityInPackage", null);
3283
3284        // TODO: Switch to user app stacks here.
3285        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3286                resultTo, resultWho, requestCode, startFlags,
3287                null, null, null, null, options, userId, container);
3288        return ret;
3289    }
3290
3291    @Override
3292    public final int startActivities(IApplicationThread caller, String callingPackage,
3293            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3294            int userId) {
3295        enforceNotIsolatedCaller("startActivities");
3296        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3297                false, true, "startActivity", null);
3298        // TODO: Switch to user app stacks here.
3299        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3300                resolvedTypes, resultTo, options, userId);
3301        return ret;
3302    }
3303
3304    final int startActivitiesInPackage(int uid, String callingPackage,
3305            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3306            Bundle options, int userId) {
3307
3308        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3309                false, true, "startActivityInPackage", null);
3310        // TODO: Switch to user app stacks here.
3311        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3312                resultTo, options, userId);
3313        return ret;
3314    }
3315
3316    final void addRecentTaskLocked(TaskRecord task) {
3317        int N = mRecentTasks.size();
3318        // Quick case: check if the top-most recent task is the same.
3319        if (N > 0 && mRecentTasks.get(0) == task) {
3320            return;
3321        }
3322        // Remove any existing entries that are the same kind of task.
3323        final Intent intent = task.intent;
3324        final boolean document = intent != null && intent.isDocument();
3325        for (int i=0; i<N; i++) {
3326            TaskRecord tr = mRecentTasks.get(i);
3327            if (task != tr) {
3328                if (task.userId != tr.userId) {
3329                    continue;
3330                }
3331                final Intent trIntent = tr.intent;
3332                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3333                    (intent == null || !intent.filterEquals(trIntent))) {
3334                    continue;
3335                }
3336                if (document || trIntent != null && trIntent.isDocument()) {
3337                    // Document tasks do not match other tasks.
3338                    continue;
3339                }
3340            }
3341
3342            // Either task and tr are the same or, their affinities match or their intents match
3343            // and neither of them is a document.
3344            tr.disposeThumbnail();
3345            mRecentTasks.remove(i);
3346            i--;
3347            N--;
3348            if (task.intent == null) {
3349                // If the new recent task we are adding is not fully
3350                // specified, then replace it with the existing recent task.
3351                task = tr;
3352            }
3353        }
3354        if (N >= MAX_RECENT_TASKS) {
3355            mRecentTasks.remove(N-1).disposeThumbnail();
3356        }
3357        mRecentTasks.add(0, task);
3358    }
3359
3360    @Override
3361    public void reportActivityFullyDrawn(IBinder token) {
3362        synchronized (this) {
3363            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3364            if (r == null) {
3365                return;
3366            }
3367            r.reportFullyDrawnLocked();
3368        }
3369    }
3370
3371    @Override
3372    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3373        synchronized (this) {
3374            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3375            if (r == null) {
3376                return;
3377            }
3378            final long origId = Binder.clearCallingIdentity();
3379            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3380            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3381                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3382            if (config != null) {
3383                r.frozenBeforeDestroy = true;
3384                if (!updateConfigurationLocked(config, r, false, false)) {
3385                    mStackSupervisor.resumeTopActivitiesLocked();
3386                }
3387            }
3388            Binder.restoreCallingIdentity(origId);
3389        }
3390    }
3391
3392    @Override
3393    public int getRequestedOrientation(IBinder token) {
3394        synchronized (this) {
3395            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3396            if (r == null) {
3397                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3398            }
3399            return mWindowManager.getAppOrientation(r.appToken);
3400        }
3401    }
3402
3403    /**
3404     * This is the internal entry point for handling Activity.finish().
3405     *
3406     * @param token The Binder token referencing the Activity we want to finish.
3407     * @param resultCode Result code, if any, from this Activity.
3408     * @param resultData Result data (Intent), if any, from this Activity.
3409     *
3410     * @return Returns true if the activity successfully finished, or false if it is still running.
3411     */
3412    @Override
3413    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
3414        // Refuse possible leaked file descriptors
3415        if (resultData != null && resultData.hasFileDescriptors() == true) {
3416            throw new IllegalArgumentException("File descriptors passed in Intent");
3417        }
3418
3419        synchronized(this) {
3420            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3421            if (r == null) {
3422                return true;
3423            }
3424            if (mController != null) {
3425                // Find the first activity that is not finishing.
3426                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3427                if (next != null) {
3428                    // ask watcher if this is allowed
3429                    boolean resumeOK = true;
3430                    try {
3431                        resumeOK = mController.activityResuming(next.packageName);
3432                    } catch (RemoteException e) {
3433                        mController = null;
3434                        Watchdog.getInstance().setActivityController(null);
3435                    }
3436
3437                    if (!resumeOK) {
3438                        return false;
3439                    }
3440                }
3441            }
3442            final long origId = Binder.clearCallingIdentity();
3443            boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode,
3444                    resultData, "app-request", true);
3445            Binder.restoreCallingIdentity(origId);
3446            return res;
3447        }
3448    }
3449
3450    @Override
3451    public final void finishHeavyWeightApp() {
3452        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3453                != PackageManager.PERMISSION_GRANTED) {
3454            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3455                    + Binder.getCallingPid()
3456                    + ", uid=" + Binder.getCallingUid()
3457                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3458            Slog.w(TAG, msg);
3459            throw new SecurityException(msg);
3460        }
3461
3462        synchronized(this) {
3463            if (mHeavyWeightProcess == null) {
3464                return;
3465            }
3466
3467            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3468                    mHeavyWeightProcess.activities);
3469            for (int i=0; i<activities.size(); i++) {
3470                ActivityRecord r = activities.get(i);
3471                if (!r.finishing) {
3472                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3473                            null, "finish-heavy", true);
3474                }
3475            }
3476
3477            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3478                    mHeavyWeightProcess.userId, 0));
3479            mHeavyWeightProcess = null;
3480        }
3481    }
3482
3483    @Override
3484    public void crashApplication(int uid, int initialPid, String packageName,
3485            String message) {
3486        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3487                != PackageManager.PERMISSION_GRANTED) {
3488            String msg = "Permission Denial: crashApplication() from pid="
3489                    + Binder.getCallingPid()
3490                    + ", uid=" + Binder.getCallingUid()
3491                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3492            Slog.w(TAG, msg);
3493            throw new SecurityException(msg);
3494        }
3495
3496        synchronized(this) {
3497            ProcessRecord proc = null;
3498
3499            // Figure out which process to kill.  We don't trust that initialPid
3500            // still has any relation to current pids, so must scan through the
3501            // list.
3502            synchronized (mPidsSelfLocked) {
3503                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3504                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3505                    if (p.uid != uid) {
3506                        continue;
3507                    }
3508                    if (p.pid == initialPid) {
3509                        proc = p;
3510                        break;
3511                    }
3512                    if (p.pkgList.containsKey(packageName)) {
3513                        proc = p;
3514                    }
3515                }
3516            }
3517
3518            if (proc == null) {
3519                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3520                        + " initialPid=" + initialPid
3521                        + " packageName=" + packageName);
3522                return;
3523            }
3524
3525            if (proc.thread != null) {
3526                if (proc.pid == Process.myPid()) {
3527                    Log.w(TAG, "crashApplication: trying to crash self!");
3528                    return;
3529                }
3530                long ident = Binder.clearCallingIdentity();
3531                try {
3532                    proc.thread.scheduleCrash(message);
3533                } catch (RemoteException e) {
3534                }
3535                Binder.restoreCallingIdentity(ident);
3536            }
3537        }
3538    }
3539
3540    @Override
3541    public final void finishSubActivity(IBinder token, String resultWho,
3542            int requestCode) {
3543        synchronized(this) {
3544            final long origId = Binder.clearCallingIdentity();
3545            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3546            if (r != null) {
3547                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3548            }
3549            Binder.restoreCallingIdentity(origId);
3550        }
3551    }
3552
3553    @Override
3554    public boolean finishActivityAffinity(IBinder token) {
3555        synchronized(this) {
3556            final long origId = Binder.clearCallingIdentity();
3557            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3558            boolean res = false;
3559            if (r != null) {
3560                res = r.task.stack.finishActivityAffinityLocked(r);
3561            }
3562            Binder.restoreCallingIdentity(origId);
3563            return res;
3564        }
3565    }
3566
3567    @Override
3568    public boolean willActivityBeVisible(IBinder token) {
3569        synchronized(this) {
3570            ActivityStack stack = ActivityRecord.getStackLocked(token);
3571            if (stack != null) {
3572                return stack.willActivityBeVisibleLocked(token);
3573            }
3574            return false;
3575        }
3576    }
3577
3578    @Override
3579    public void overridePendingTransition(IBinder token, String packageName,
3580            int enterAnim, int exitAnim) {
3581        synchronized(this) {
3582            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3583            if (self == null) {
3584                return;
3585            }
3586
3587            final long origId = Binder.clearCallingIdentity();
3588
3589            if (self.state == ActivityState.RESUMED
3590                    || self.state == ActivityState.PAUSING) {
3591                mWindowManager.overridePendingAppTransition(packageName,
3592                        enterAnim, exitAnim, null);
3593            }
3594
3595            Binder.restoreCallingIdentity(origId);
3596        }
3597    }
3598
3599    /**
3600     * Main function for removing an existing process from the activity manager
3601     * as a result of that process going away.  Clears out all connections
3602     * to the process.
3603     */
3604    private final void handleAppDiedLocked(ProcessRecord app,
3605            boolean restarting, boolean allowRestart) {
3606        int pid = app.pid;
3607        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3608        if (!restarting) {
3609            removeLruProcessLocked(app);
3610            if (pid > 0) {
3611                ProcessList.remove(pid);
3612            }
3613        }
3614
3615        if (mProfileProc == app) {
3616            clearProfilerLocked();
3617        }
3618
3619        // Remove this application's activities from active lists.
3620        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3621
3622        app.activities.clear();
3623
3624        if (app.instrumentationClass != null) {
3625            Slog.w(TAG, "Crash of app " + app.processName
3626                  + " running instrumentation " + app.instrumentationClass);
3627            Bundle info = new Bundle();
3628            info.putString("shortMsg", "Process crashed.");
3629            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3630        }
3631
3632        if (!restarting) {
3633            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3634                // If there was nothing to resume, and we are not already
3635                // restarting this process, but there is a visible activity that
3636                // is hosted by the process...  then make sure all visible
3637                // activities are running, taking care of restarting this
3638                // process.
3639                if (hasVisibleActivities) {
3640                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3641                }
3642            }
3643        }
3644    }
3645
3646    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3647        IBinder threadBinder = thread.asBinder();
3648        // Find the application record.
3649        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3650            ProcessRecord rec = mLruProcesses.get(i);
3651            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3652                return i;
3653            }
3654        }
3655        return -1;
3656    }
3657
3658    final ProcessRecord getRecordForAppLocked(
3659            IApplicationThread thread) {
3660        if (thread == null) {
3661            return null;
3662        }
3663
3664        int appIndex = getLRURecordIndexForAppLocked(thread);
3665        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3666    }
3667
3668    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3669        // If there are no longer any background processes running,
3670        // and the app that died was not running instrumentation,
3671        // then tell everyone we are now low on memory.
3672        boolean haveBg = false;
3673        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3674            ProcessRecord rec = mLruProcesses.get(i);
3675            if (rec.thread != null
3676                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3677                haveBg = true;
3678                break;
3679            }
3680        }
3681
3682        if (!haveBg) {
3683            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3684            if (doReport) {
3685                long now = SystemClock.uptimeMillis();
3686                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3687                    doReport = false;
3688                } else {
3689                    mLastMemUsageReportTime = now;
3690                }
3691            }
3692            final ArrayList<ProcessMemInfo> memInfos
3693                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3694            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3695            long now = SystemClock.uptimeMillis();
3696            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3697                ProcessRecord rec = mLruProcesses.get(i);
3698                if (rec == dyingProc || rec.thread == null) {
3699                    continue;
3700                }
3701                if (doReport) {
3702                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3703                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3704                }
3705                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3706                    // The low memory report is overriding any current
3707                    // state for a GC request.  Make sure to do
3708                    // heavy/important/visible/foreground processes first.
3709                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3710                        rec.lastRequestedGc = 0;
3711                    } else {
3712                        rec.lastRequestedGc = rec.lastLowMemory;
3713                    }
3714                    rec.reportLowMemory = true;
3715                    rec.lastLowMemory = now;
3716                    mProcessesToGc.remove(rec);
3717                    addProcessToGcListLocked(rec);
3718                }
3719            }
3720            if (doReport) {
3721                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3722                mHandler.sendMessage(msg);
3723            }
3724            scheduleAppGcsLocked();
3725        }
3726    }
3727
3728    final void appDiedLocked(ProcessRecord app, int pid,
3729            IApplicationThread thread) {
3730
3731        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3732        synchronized (stats) {
3733            stats.noteProcessDiedLocked(app.info.uid, pid);
3734        }
3735
3736        // Clean up already done if the process has been re-started.
3737        if (app.pid == pid && app.thread != null &&
3738                app.thread.asBinder() == thread.asBinder()) {
3739            boolean doLowMem = app.instrumentationClass == null;
3740            boolean doOomAdj = doLowMem;
3741            if (!app.killedByAm) {
3742                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3743                        + ") has died.");
3744                mAllowLowerMemLevel = true;
3745            } else {
3746                // Note that we always want to do oom adj to update our state with the
3747                // new number of procs.
3748                mAllowLowerMemLevel = false;
3749                doLowMem = false;
3750            }
3751            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3752            if (DEBUG_CLEANUP) Slog.v(
3753                TAG, "Dying app: " + app + ", pid: " + pid
3754                + ", thread: " + thread.asBinder());
3755            handleAppDiedLocked(app, false, true);
3756
3757            if (doOomAdj) {
3758                updateOomAdjLocked();
3759            }
3760            if (doLowMem) {
3761                doLowMemReportIfNeededLocked(app);
3762            }
3763        } else if (app.pid != pid) {
3764            // A new process has already been started.
3765            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3766                    + ") has died and restarted (pid " + app.pid + ").");
3767            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3768        } else if (DEBUG_PROCESSES) {
3769            Slog.d(TAG, "Received spurious death notification for thread "
3770                    + thread.asBinder());
3771        }
3772    }
3773
3774    /**
3775     * If a stack trace dump file is configured, dump process stack traces.
3776     * @param clearTraces causes the dump file to be erased prior to the new
3777     *    traces being written, if true; when false, the new traces will be
3778     *    appended to any existing file content.
3779     * @param firstPids of dalvik VM processes to dump stack traces for first
3780     * @param lastPids of dalvik VM processes to dump stack traces for last
3781     * @param nativeProcs optional list of native process names to dump stack crawls
3782     * @return file containing stack traces, or null if no dump file is configured
3783     */
3784    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3785            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3786        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3787        if (tracesPath == null || tracesPath.length() == 0) {
3788            return null;
3789        }
3790
3791        File tracesFile = new File(tracesPath);
3792        try {
3793            File tracesDir = tracesFile.getParentFile();
3794            if (!tracesDir.exists()) {
3795                tracesFile.mkdirs();
3796                if (!SELinux.restorecon(tracesDir)) {
3797                    return null;
3798                }
3799            }
3800            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3801
3802            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3803            tracesFile.createNewFile();
3804            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3805        } catch (IOException e) {
3806            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3807            return null;
3808        }
3809
3810        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
3811        return tracesFile;
3812    }
3813
3814    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3815            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3816        // Use a FileObserver to detect when traces finish writing.
3817        // The order of traces is considered important to maintain for legibility.
3818        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3819            @Override
3820            public synchronized void onEvent(int event, String path) { notify(); }
3821        };
3822
3823        try {
3824            observer.startWatching();
3825
3826            // First collect all of the stacks of the most important pids.
3827            if (firstPids != null) {
3828                try {
3829                    int num = firstPids.size();
3830                    for (int i = 0; i < num; i++) {
3831                        synchronized (observer) {
3832                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3833                            observer.wait(200);  // Wait for write-close, give up after 200msec
3834                        }
3835                    }
3836                } catch (InterruptedException e) {
3837                    Log.wtf(TAG, e);
3838                }
3839            }
3840
3841            // Next collect the stacks of the native pids
3842            if (nativeProcs != null) {
3843                int[] pids = Process.getPidsForCommands(nativeProcs);
3844                if (pids != null) {
3845                    for (int pid : pids) {
3846                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3847                    }
3848                }
3849            }
3850
3851            // Lastly, measure CPU usage.
3852            if (processCpuTracker != null) {
3853                processCpuTracker.init();
3854                System.gc();
3855                processCpuTracker.update();
3856                try {
3857                    synchronized (processCpuTracker) {
3858                        processCpuTracker.wait(500); // measure over 1/2 second.
3859                    }
3860                } catch (InterruptedException e) {
3861                }
3862                processCpuTracker.update();
3863
3864                // We'll take the stack crawls of just the top apps using CPU.
3865                final int N = processCpuTracker.countWorkingStats();
3866                int numProcs = 0;
3867                for (int i=0; i<N && numProcs<5; i++) {
3868                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
3869                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3870                        numProcs++;
3871                        try {
3872                            synchronized (observer) {
3873                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3874                                observer.wait(200);  // Wait for write-close, give up after 200msec
3875                            }
3876                        } catch (InterruptedException e) {
3877                            Log.wtf(TAG, e);
3878                        }
3879
3880                    }
3881                }
3882            }
3883        } finally {
3884            observer.stopWatching();
3885        }
3886    }
3887
3888    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3889        if (true || IS_USER_BUILD) {
3890            return;
3891        }
3892        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3893        if (tracesPath == null || tracesPath.length() == 0) {
3894            return;
3895        }
3896
3897        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3898        StrictMode.allowThreadDiskWrites();
3899        try {
3900            final File tracesFile = new File(tracesPath);
3901            final File tracesDir = tracesFile.getParentFile();
3902            final File tracesTmp = new File(tracesDir, "__tmp__");
3903            try {
3904                if (!tracesDir.exists()) {
3905                    tracesFile.mkdirs();
3906                    if (!SELinux.restorecon(tracesDir.getPath())) {
3907                        return;
3908                    }
3909                }
3910                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3911
3912                if (tracesFile.exists()) {
3913                    tracesTmp.delete();
3914                    tracesFile.renameTo(tracesTmp);
3915                }
3916                StringBuilder sb = new StringBuilder();
3917                Time tobj = new Time();
3918                tobj.set(System.currentTimeMillis());
3919                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3920                sb.append(": ");
3921                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3922                sb.append(" since ");
3923                sb.append(msg);
3924                FileOutputStream fos = new FileOutputStream(tracesFile);
3925                fos.write(sb.toString().getBytes());
3926                if (app == null) {
3927                    fos.write("\n*** No application process!".getBytes());
3928                }
3929                fos.close();
3930                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3931            } catch (IOException e) {
3932                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3933                return;
3934            }
3935
3936            if (app != null) {
3937                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3938                firstPids.add(app.pid);
3939                dumpStackTraces(tracesPath, firstPids, null, null, null);
3940            }
3941
3942            File lastTracesFile = null;
3943            File curTracesFile = null;
3944            for (int i=9; i>=0; i--) {
3945                String name = String.format(Locale.US, "slow%02d.txt", i);
3946                curTracesFile = new File(tracesDir, name);
3947                if (curTracesFile.exists()) {
3948                    if (lastTracesFile != null) {
3949                        curTracesFile.renameTo(lastTracesFile);
3950                    } else {
3951                        curTracesFile.delete();
3952                    }
3953                }
3954                lastTracesFile = curTracesFile;
3955            }
3956            tracesFile.renameTo(curTracesFile);
3957            if (tracesTmp.exists()) {
3958                tracesTmp.renameTo(tracesFile);
3959            }
3960        } finally {
3961            StrictMode.setThreadPolicy(oldPolicy);
3962        }
3963    }
3964
3965    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3966            ActivityRecord parent, boolean aboveSystem, final String annotation) {
3967        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3968        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3969
3970        if (mController != null) {
3971            try {
3972                // 0 == continue, -1 = kill process immediately
3973                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3974                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3975            } catch (RemoteException e) {
3976                mController = null;
3977                Watchdog.getInstance().setActivityController(null);
3978            }
3979        }
3980
3981        long anrTime = SystemClock.uptimeMillis();
3982        if (MONITOR_CPU_USAGE) {
3983            updateCpuStatsNow();
3984        }
3985
3986        synchronized (this) {
3987            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3988            if (mShuttingDown) {
3989                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3990                return;
3991            } else if (app.notResponding) {
3992                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3993                return;
3994            } else if (app.crashing) {
3995                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3996                return;
3997            }
3998
3999            // In case we come through here for the same app before completing
4000            // this one, mark as anring now so we will bail out.
4001            app.notResponding = true;
4002
4003            // Log the ANR to the event log.
4004            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4005                    app.processName, app.info.flags, annotation);
4006
4007            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4008            firstPids.add(app.pid);
4009
4010            int parentPid = app.pid;
4011            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4012            if (parentPid != app.pid) firstPids.add(parentPid);
4013
4014            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4015
4016            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4017                ProcessRecord r = mLruProcesses.get(i);
4018                if (r != null && r.thread != null) {
4019                    int pid = r.pid;
4020                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4021                        if (r.persistent) {
4022                            firstPids.add(pid);
4023                        } else {
4024                            lastPids.put(pid, Boolean.TRUE);
4025                        }
4026                    }
4027                }
4028            }
4029        }
4030
4031        // Log the ANR to the main log.
4032        StringBuilder info = new StringBuilder();
4033        info.setLength(0);
4034        info.append("ANR in ").append(app.processName);
4035        if (activity != null && activity.shortComponentName != null) {
4036            info.append(" (").append(activity.shortComponentName).append(")");
4037        }
4038        info.append("\n");
4039        info.append("PID: ").append(app.pid).append("\n");
4040        if (annotation != null) {
4041            info.append("Reason: ").append(annotation).append("\n");
4042        }
4043        if (parent != null && parent != activity) {
4044            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4045        }
4046
4047        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4048
4049        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4050                NATIVE_STACKS_OF_INTEREST);
4051
4052        String cpuInfo = null;
4053        if (MONITOR_CPU_USAGE) {
4054            updateCpuStatsNow();
4055            synchronized (mProcessCpuThread) {
4056                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4057            }
4058            info.append(processCpuTracker.printCurrentLoad());
4059            info.append(cpuInfo);
4060        }
4061
4062        info.append(processCpuTracker.printCurrentState(anrTime));
4063
4064        Slog.e(TAG, info.toString());
4065        if (tracesFile == null) {
4066            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4067            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4068        }
4069
4070        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4071                cpuInfo, tracesFile, null);
4072
4073        if (mController != null) {
4074            try {
4075                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4076                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4077                if (res != 0) {
4078                    if (res < 0 && app.pid != MY_PID) {
4079                        Process.killProcess(app.pid);
4080                    } else {
4081                        synchronized (this) {
4082                            mServices.scheduleServiceTimeoutLocked(app);
4083                        }
4084                    }
4085                    return;
4086                }
4087            } catch (RemoteException e) {
4088                mController = null;
4089                Watchdog.getInstance().setActivityController(null);
4090            }
4091        }
4092
4093        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4094        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4095                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4096
4097        synchronized (this) {
4098            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4099                killUnneededProcessLocked(app, "background ANR");
4100                return;
4101            }
4102
4103            // Set the app's notResponding state, and look up the errorReportReceiver
4104            makeAppNotRespondingLocked(app,
4105                    activity != null ? activity.shortComponentName : null,
4106                    annotation != null ? "ANR " + annotation : "ANR",
4107                    info.toString());
4108
4109            // Bring up the infamous App Not Responding dialog
4110            Message msg = Message.obtain();
4111            HashMap<String, Object> map = new HashMap<String, Object>();
4112            msg.what = SHOW_NOT_RESPONDING_MSG;
4113            msg.obj = map;
4114            msg.arg1 = aboveSystem ? 1 : 0;
4115            map.put("app", app);
4116            if (activity != null) {
4117                map.put("activity", activity);
4118            }
4119
4120            mHandler.sendMessage(msg);
4121        }
4122    }
4123
4124    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4125        if (!mLaunchWarningShown) {
4126            mLaunchWarningShown = true;
4127            mHandler.post(new Runnable() {
4128                @Override
4129                public void run() {
4130                    synchronized (ActivityManagerService.this) {
4131                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4132                        d.show();
4133                        mHandler.postDelayed(new Runnable() {
4134                            @Override
4135                            public void run() {
4136                                synchronized (ActivityManagerService.this) {
4137                                    d.dismiss();
4138                                    mLaunchWarningShown = false;
4139                                }
4140                            }
4141                        }, 4000);
4142                    }
4143                }
4144            });
4145        }
4146    }
4147
4148    @Override
4149    public boolean clearApplicationUserData(final String packageName,
4150            final IPackageDataObserver observer, int userId) {
4151        enforceNotIsolatedCaller("clearApplicationUserData");
4152        int uid = Binder.getCallingUid();
4153        int pid = Binder.getCallingPid();
4154        userId = handleIncomingUser(pid, uid,
4155                userId, false, true, "clearApplicationUserData", null);
4156        long callingId = Binder.clearCallingIdentity();
4157        try {
4158            IPackageManager pm = AppGlobals.getPackageManager();
4159            int pkgUid = -1;
4160            synchronized(this) {
4161                try {
4162                    pkgUid = pm.getPackageUid(packageName, userId);
4163                } catch (RemoteException e) {
4164                }
4165                if (pkgUid == -1) {
4166                    Slog.w(TAG, "Invalid packageName: " + packageName);
4167                    if (observer != null) {
4168                        try {
4169                            observer.onRemoveCompleted(packageName, false);
4170                        } catch (RemoteException e) {
4171                            Slog.i(TAG, "Observer no longer exists.");
4172                        }
4173                    }
4174                    return false;
4175                }
4176                if (uid == pkgUid || checkComponentPermission(
4177                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4178                        pid, uid, -1, true)
4179                        == PackageManager.PERMISSION_GRANTED) {
4180                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4181                } else {
4182                    throw new SecurityException("PID " + pid + " does not have permission "
4183                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4184                                    + " of package " + packageName);
4185                }
4186            }
4187
4188            try {
4189                // Clear application user data
4190                pm.clearApplicationUserData(packageName, observer, userId);
4191
4192                // Remove all permissions granted from/to this package
4193                removeUriPermissionsForPackageLocked(packageName, userId, true);
4194
4195                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4196                        Uri.fromParts("package", packageName, null));
4197                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4198                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4199                        null, null, 0, null, null, null, false, false, userId);
4200            } catch (RemoteException e) {
4201            }
4202        } finally {
4203            Binder.restoreCallingIdentity(callingId);
4204        }
4205        return true;
4206    }
4207
4208    @Override
4209    public void killBackgroundProcesses(final String packageName, int userId) {
4210        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4211                != PackageManager.PERMISSION_GRANTED &&
4212                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4213                        != PackageManager.PERMISSION_GRANTED) {
4214            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4215                    + Binder.getCallingPid()
4216                    + ", uid=" + Binder.getCallingUid()
4217                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4218            Slog.w(TAG, msg);
4219            throw new SecurityException(msg);
4220        }
4221
4222        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4223                userId, true, true, "killBackgroundProcesses", null);
4224        long callingId = Binder.clearCallingIdentity();
4225        try {
4226            IPackageManager pm = AppGlobals.getPackageManager();
4227            synchronized(this) {
4228                int appId = -1;
4229                try {
4230                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4231                } catch (RemoteException e) {
4232                }
4233                if (appId == -1) {
4234                    Slog.w(TAG, "Invalid packageName: " + packageName);
4235                    return;
4236                }
4237                killPackageProcessesLocked(packageName, appId, userId,
4238                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4239            }
4240        } finally {
4241            Binder.restoreCallingIdentity(callingId);
4242        }
4243    }
4244
4245    @Override
4246    public void killAllBackgroundProcesses() {
4247        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4248                != PackageManager.PERMISSION_GRANTED) {
4249            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4250                    + Binder.getCallingPid()
4251                    + ", uid=" + Binder.getCallingUid()
4252                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4253            Slog.w(TAG, msg);
4254            throw new SecurityException(msg);
4255        }
4256
4257        long callingId = Binder.clearCallingIdentity();
4258        try {
4259            synchronized(this) {
4260                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4261                final int NP = mProcessNames.getMap().size();
4262                for (int ip=0; ip<NP; ip++) {
4263                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4264                    final int NA = apps.size();
4265                    for (int ia=0; ia<NA; ia++) {
4266                        ProcessRecord app = apps.valueAt(ia);
4267                        if (app.persistent) {
4268                            // we don't kill persistent processes
4269                            continue;
4270                        }
4271                        if (app.removed) {
4272                            procs.add(app);
4273                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4274                            app.removed = true;
4275                            procs.add(app);
4276                        }
4277                    }
4278                }
4279
4280                int N = procs.size();
4281                for (int i=0; i<N; i++) {
4282                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4283                }
4284                mAllowLowerMemLevel = true;
4285                updateOomAdjLocked();
4286                doLowMemReportIfNeededLocked(null);
4287            }
4288        } finally {
4289            Binder.restoreCallingIdentity(callingId);
4290        }
4291    }
4292
4293    @Override
4294    public void forceStopPackage(final String packageName, int userId) {
4295        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4296                != PackageManager.PERMISSION_GRANTED) {
4297            String msg = "Permission Denial: forceStopPackage() from pid="
4298                    + Binder.getCallingPid()
4299                    + ", uid=" + Binder.getCallingUid()
4300                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4301            Slog.w(TAG, msg);
4302            throw new SecurityException(msg);
4303        }
4304        final int callingPid = Binder.getCallingPid();
4305        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4306                userId, true, true, "forceStopPackage", null);
4307        long callingId = Binder.clearCallingIdentity();
4308        try {
4309            IPackageManager pm = AppGlobals.getPackageManager();
4310            synchronized(this) {
4311                int[] users = userId == UserHandle.USER_ALL
4312                        ? getUsersLocked() : new int[] { userId };
4313                for (int user : users) {
4314                    int pkgUid = -1;
4315                    try {
4316                        pkgUid = pm.getPackageUid(packageName, user);
4317                    } catch (RemoteException e) {
4318                    }
4319                    if (pkgUid == -1) {
4320                        Slog.w(TAG, "Invalid packageName: " + packageName);
4321                        continue;
4322                    }
4323                    try {
4324                        pm.setPackageStoppedState(packageName, true, user);
4325                    } catch (RemoteException e) {
4326                    } catch (IllegalArgumentException e) {
4327                        Slog.w(TAG, "Failed trying to unstop package "
4328                                + packageName + ": " + e);
4329                    }
4330                    if (isUserRunningLocked(user, false)) {
4331                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4332                    }
4333                }
4334            }
4335        } finally {
4336            Binder.restoreCallingIdentity(callingId);
4337        }
4338    }
4339
4340    /*
4341     * The pkg name and app id have to be specified.
4342     */
4343    @Override
4344    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4345        if (pkg == null) {
4346            return;
4347        }
4348        // Make sure the uid is valid.
4349        if (appid < 0) {
4350            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4351            return;
4352        }
4353        int callerUid = Binder.getCallingUid();
4354        // Only the system server can kill an application
4355        if (callerUid == Process.SYSTEM_UID) {
4356            // Post an aysnc message to kill the application
4357            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4358            msg.arg1 = appid;
4359            msg.arg2 = 0;
4360            Bundle bundle = new Bundle();
4361            bundle.putString("pkg", pkg);
4362            bundle.putString("reason", reason);
4363            msg.obj = bundle;
4364            mHandler.sendMessage(msg);
4365        } else {
4366            throw new SecurityException(callerUid + " cannot kill pkg: " +
4367                    pkg);
4368        }
4369    }
4370
4371    @Override
4372    public void closeSystemDialogs(String reason) {
4373        enforceNotIsolatedCaller("closeSystemDialogs");
4374
4375        final int pid = Binder.getCallingPid();
4376        final int uid = Binder.getCallingUid();
4377        final long origId = Binder.clearCallingIdentity();
4378        try {
4379            synchronized (this) {
4380                // Only allow this from foreground processes, so that background
4381                // applications can't abuse it to prevent system UI from being shown.
4382                if (uid >= Process.FIRST_APPLICATION_UID) {
4383                    ProcessRecord proc;
4384                    synchronized (mPidsSelfLocked) {
4385                        proc = mPidsSelfLocked.get(pid);
4386                    }
4387                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4388                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4389                                + " from background process " + proc);
4390                        return;
4391                    }
4392                }
4393                closeSystemDialogsLocked(reason);
4394            }
4395        } finally {
4396            Binder.restoreCallingIdentity(origId);
4397        }
4398    }
4399
4400    void closeSystemDialogsLocked(String reason) {
4401        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4402        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4403                | Intent.FLAG_RECEIVER_FOREGROUND);
4404        if (reason != null) {
4405            intent.putExtra("reason", reason);
4406        }
4407        mWindowManager.closeSystemDialogs(reason);
4408
4409        mStackSupervisor.closeSystemDialogsLocked();
4410
4411        broadcastIntentLocked(null, null, intent, null,
4412                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4413                Process.SYSTEM_UID, UserHandle.USER_ALL);
4414    }
4415
4416    @Override
4417    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4418        enforceNotIsolatedCaller("getProcessMemoryInfo");
4419        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4420        for (int i=pids.length-1; i>=0; i--) {
4421            ProcessRecord proc;
4422            int oomAdj;
4423            synchronized (this) {
4424                synchronized (mPidsSelfLocked) {
4425                    proc = mPidsSelfLocked.get(pids[i]);
4426                    oomAdj = proc != null ? proc.setAdj : 0;
4427                }
4428            }
4429            infos[i] = new Debug.MemoryInfo();
4430            Debug.getMemoryInfo(pids[i], infos[i]);
4431            if (proc != null) {
4432                synchronized (this) {
4433                    if (proc.thread != null && proc.setAdj == oomAdj) {
4434                        // Record this for posterity if the process has been stable.
4435                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4436                                infos[i].getTotalUss(), false, proc.pkgList);
4437                    }
4438                }
4439            }
4440        }
4441        return infos;
4442    }
4443
4444    @Override
4445    public long[] getProcessPss(int[] pids) {
4446        enforceNotIsolatedCaller("getProcessPss");
4447        long[] pss = new long[pids.length];
4448        for (int i=pids.length-1; i>=0; i--) {
4449            ProcessRecord proc;
4450            int oomAdj;
4451            synchronized (this) {
4452                synchronized (mPidsSelfLocked) {
4453                    proc = mPidsSelfLocked.get(pids[i]);
4454                    oomAdj = proc != null ? proc.setAdj : 0;
4455                }
4456            }
4457            long[] tmpUss = new long[1];
4458            pss[i] = Debug.getPss(pids[i], tmpUss);
4459            if (proc != null) {
4460                synchronized (this) {
4461                    if (proc.thread != null && proc.setAdj == oomAdj) {
4462                        // Record this for posterity if the process has been stable.
4463                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4464                    }
4465                }
4466            }
4467        }
4468        return pss;
4469    }
4470
4471    @Override
4472    public void killApplicationProcess(String processName, int uid) {
4473        if (processName == null) {
4474            return;
4475        }
4476
4477        int callerUid = Binder.getCallingUid();
4478        // Only the system server can kill an application
4479        if (callerUid == Process.SYSTEM_UID) {
4480            synchronized (this) {
4481                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4482                if (app != null && app.thread != null) {
4483                    try {
4484                        app.thread.scheduleSuicide();
4485                    } catch (RemoteException e) {
4486                        // If the other end already died, then our work here is done.
4487                    }
4488                } else {
4489                    Slog.w(TAG, "Process/uid not found attempting kill of "
4490                            + processName + " / " + uid);
4491                }
4492            }
4493        } else {
4494            throw new SecurityException(callerUid + " cannot kill app process: " +
4495                    processName);
4496        }
4497    }
4498
4499    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4500        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4501                false, true, false, false, UserHandle.getUserId(uid), reason);
4502        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4503                Uri.fromParts("package", packageName, null));
4504        if (!mProcessesReady) {
4505            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4506                    | Intent.FLAG_RECEIVER_FOREGROUND);
4507        }
4508        intent.putExtra(Intent.EXTRA_UID, uid);
4509        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4510        broadcastIntentLocked(null, null, intent,
4511                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4512                false, false,
4513                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4514    }
4515
4516    private void forceStopUserLocked(int userId, String reason) {
4517        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4518        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4519        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4520                | Intent.FLAG_RECEIVER_FOREGROUND);
4521        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4522        broadcastIntentLocked(null, null, intent,
4523                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4524                false, false,
4525                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4526    }
4527
4528    private final boolean killPackageProcessesLocked(String packageName, int appId,
4529            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4530            boolean doit, boolean evenPersistent, String reason) {
4531        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4532
4533        // Remove all processes this package may have touched: all with the
4534        // same UID (except for the system or root user), and all whose name
4535        // matches the package name.
4536        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4537        final int NP = mProcessNames.getMap().size();
4538        for (int ip=0; ip<NP; ip++) {
4539            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4540            final int NA = apps.size();
4541            for (int ia=0; ia<NA; ia++) {
4542                ProcessRecord app = apps.valueAt(ia);
4543                if (app.persistent && !evenPersistent) {
4544                    // we don't kill persistent processes
4545                    continue;
4546                }
4547                if (app.removed) {
4548                    if (doit) {
4549                        procs.add(app);
4550                    }
4551                    continue;
4552                }
4553
4554                // Skip process if it doesn't meet our oom adj requirement.
4555                if (app.setAdj < minOomAdj) {
4556                    continue;
4557                }
4558
4559                // If no package is specified, we call all processes under the
4560                // give user id.
4561                if (packageName == null) {
4562                    if (app.userId != userId) {
4563                        continue;
4564                    }
4565                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4566                        continue;
4567                    }
4568                // Package has been specified, we want to hit all processes
4569                // that match it.  We need to qualify this by the processes
4570                // that are running under the specified app and user ID.
4571                } else {
4572                    if (UserHandle.getAppId(app.uid) != appId) {
4573                        continue;
4574                    }
4575                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4576                        continue;
4577                    }
4578                    if (!app.pkgList.containsKey(packageName)) {
4579                        continue;
4580                    }
4581                }
4582
4583                // Process has passed all conditions, kill it!
4584                if (!doit) {
4585                    return true;
4586                }
4587                app.removed = true;
4588                procs.add(app);
4589            }
4590        }
4591
4592        int N = procs.size();
4593        for (int i=0; i<N; i++) {
4594            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4595        }
4596        updateOomAdjLocked();
4597        return N > 0;
4598    }
4599
4600    private final boolean forceStopPackageLocked(String name, int appId,
4601            boolean callerWillRestart, boolean purgeCache, boolean doit,
4602            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4603        int i;
4604        int N;
4605
4606        if (userId == UserHandle.USER_ALL && name == null) {
4607            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4608        }
4609
4610        if (appId < 0 && name != null) {
4611            try {
4612                appId = UserHandle.getAppId(
4613                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4614            } catch (RemoteException e) {
4615            }
4616        }
4617
4618        if (doit) {
4619            if (name != null) {
4620                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4621                        + " user=" + userId + ": " + reason);
4622            } else {
4623                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4624            }
4625
4626            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4627            for (int ip=pmap.size()-1; ip>=0; ip--) {
4628                SparseArray<Long> ba = pmap.valueAt(ip);
4629                for (i=ba.size()-1; i>=0; i--) {
4630                    boolean remove = false;
4631                    final int entUid = ba.keyAt(i);
4632                    if (name != null) {
4633                        if (userId == UserHandle.USER_ALL) {
4634                            if (UserHandle.getAppId(entUid) == appId) {
4635                                remove = true;
4636                            }
4637                        } else {
4638                            if (entUid == UserHandle.getUid(userId, appId)) {
4639                                remove = true;
4640                            }
4641                        }
4642                    } else if (UserHandle.getUserId(entUid) == userId) {
4643                        remove = true;
4644                    }
4645                    if (remove) {
4646                        ba.removeAt(i);
4647                    }
4648                }
4649                if (ba.size() == 0) {
4650                    pmap.removeAt(ip);
4651                }
4652            }
4653        }
4654
4655        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4656                -100, callerWillRestart, true, doit, evenPersistent,
4657                name == null ? ("stop user " + userId) : ("stop " + name));
4658
4659        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4660            if (!doit) {
4661                return true;
4662            }
4663            didSomething = true;
4664        }
4665
4666        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4667            if (!doit) {
4668                return true;
4669            }
4670            didSomething = true;
4671        }
4672
4673        if (name == null) {
4674            // Remove all sticky broadcasts from this user.
4675            mStickyBroadcasts.remove(userId);
4676        }
4677
4678        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4679        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4680                userId, providers)) {
4681            if (!doit) {
4682                return true;
4683            }
4684            didSomething = true;
4685        }
4686        N = providers.size();
4687        for (i=0; i<N; i++) {
4688            removeDyingProviderLocked(null, providers.get(i), true);
4689        }
4690
4691        // Remove transient permissions granted from/to this package/user
4692        removeUriPermissionsForPackageLocked(name, userId, false);
4693
4694        if (name == null || uninstalling) {
4695            // Remove pending intents.  For now we only do this when force
4696            // stopping users, because we have some problems when doing this
4697            // for packages -- app widgets are not currently cleaned up for
4698            // such packages, so they can be left with bad pending intents.
4699            if (mIntentSenderRecords.size() > 0) {
4700                Iterator<WeakReference<PendingIntentRecord>> it
4701                        = mIntentSenderRecords.values().iterator();
4702                while (it.hasNext()) {
4703                    WeakReference<PendingIntentRecord> wpir = it.next();
4704                    if (wpir == null) {
4705                        it.remove();
4706                        continue;
4707                    }
4708                    PendingIntentRecord pir = wpir.get();
4709                    if (pir == null) {
4710                        it.remove();
4711                        continue;
4712                    }
4713                    if (name == null) {
4714                        // Stopping user, remove all objects for the user.
4715                        if (pir.key.userId != userId) {
4716                            // Not the same user, skip it.
4717                            continue;
4718                        }
4719                    } else {
4720                        if (UserHandle.getAppId(pir.uid) != appId) {
4721                            // Different app id, skip it.
4722                            continue;
4723                        }
4724                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4725                            // Different user, skip it.
4726                            continue;
4727                        }
4728                        if (!pir.key.packageName.equals(name)) {
4729                            // Different package, skip it.
4730                            continue;
4731                        }
4732                    }
4733                    if (!doit) {
4734                        return true;
4735                    }
4736                    didSomething = true;
4737                    it.remove();
4738                    pir.canceled = true;
4739                    if (pir.key.activity != null) {
4740                        pir.key.activity.pendingResults.remove(pir.ref);
4741                    }
4742                }
4743            }
4744        }
4745
4746        if (doit) {
4747            if (purgeCache && name != null) {
4748                AttributeCache ac = AttributeCache.instance();
4749                if (ac != null) {
4750                    ac.removePackage(name);
4751                }
4752            }
4753            if (mBooted) {
4754                mStackSupervisor.resumeTopActivitiesLocked();
4755                mStackSupervisor.scheduleIdleLocked();
4756            }
4757        }
4758
4759        return didSomething;
4760    }
4761
4762    private final boolean removeProcessLocked(ProcessRecord app,
4763            boolean callerWillRestart, boolean allowRestart, String reason) {
4764        final String name = app.processName;
4765        final int uid = app.uid;
4766        if (DEBUG_PROCESSES) Slog.d(
4767            TAG, "Force removing proc " + app.toShortString() + " (" + name
4768            + "/" + uid + ")");
4769
4770        mProcessNames.remove(name, uid);
4771        mIsolatedProcesses.remove(app.uid);
4772        if (mHeavyWeightProcess == app) {
4773            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4774                    mHeavyWeightProcess.userId, 0));
4775            mHeavyWeightProcess = null;
4776        }
4777        boolean needRestart = false;
4778        if (app.pid > 0 && app.pid != MY_PID) {
4779            int pid = app.pid;
4780            synchronized (mPidsSelfLocked) {
4781                mPidsSelfLocked.remove(pid);
4782                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4783            }
4784            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
4785                    app.processName, app.info.uid);
4786            if (app.isolated) {
4787                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
4788            }
4789            killUnneededProcessLocked(app, reason);
4790            handleAppDiedLocked(app, true, allowRestart);
4791            removeLruProcessLocked(app);
4792
4793            if (app.persistent && !app.isolated) {
4794                if (!callerWillRestart) {
4795                    addAppLocked(app.info, false);
4796                } else {
4797                    needRestart = true;
4798                }
4799            }
4800        } else {
4801            mRemovedProcesses.add(app);
4802        }
4803
4804        return needRestart;
4805    }
4806
4807    private final void processStartTimedOutLocked(ProcessRecord app) {
4808        final int pid = app.pid;
4809        boolean gone = false;
4810        synchronized (mPidsSelfLocked) {
4811            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4812            if (knownApp != null && knownApp.thread == null) {
4813                mPidsSelfLocked.remove(pid);
4814                gone = true;
4815            }
4816        }
4817
4818        if (gone) {
4819            Slog.w(TAG, "Process " + app + " failed to attach");
4820            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
4821                    pid, app.uid, app.processName);
4822            mProcessNames.remove(app.processName, app.uid);
4823            mIsolatedProcesses.remove(app.uid);
4824            if (mHeavyWeightProcess == app) {
4825                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4826                        mHeavyWeightProcess.userId, 0));
4827                mHeavyWeightProcess = null;
4828            }
4829            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
4830                    app.processName, app.info.uid);
4831            if (app.isolated) {
4832                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
4833            }
4834            // Take care of any launching providers waiting for this process.
4835            checkAppInLaunchingProvidersLocked(app, true);
4836            // Take care of any services that are waiting for the process.
4837            mServices.processStartTimedOutLocked(app);
4838            killUnneededProcessLocked(app, "start timeout");
4839            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4840                Slog.w(TAG, "Unattached app died before backup, skipping");
4841                try {
4842                    IBackupManager bm = IBackupManager.Stub.asInterface(
4843                            ServiceManager.getService(Context.BACKUP_SERVICE));
4844                    bm.agentDisconnected(app.info.packageName);
4845                } catch (RemoteException e) {
4846                    // Can't happen; the backup manager is local
4847                }
4848            }
4849            if (isPendingBroadcastProcessLocked(pid)) {
4850                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4851                skipPendingBroadcastLocked(pid);
4852            }
4853        } else {
4854            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4855        }
4856    }
4857
4858    private final boolean attachApplicationLocked(IApplicationThread thread,
4859            int pid) {
4860
4861        // Find the application record that is being attached...  either via
4862        // the pid if we are running in multiple processes, or just pull the
4863        // next app record if we are emulating process with anonymous threads.
4864        ProcessRecord app;
4865        if (pid != MY_PID && pid >= 0) {
4866            synchronized (mPidsSelfLocked) {
4867                app = mPidsSelfLocked.get(pid);
4868            }
4869        } else {
4870            app = null;
4871        }
4872
4873        if (app == null) {
4874            Slog.w(TAG, "No pending application record for pid " + pid
4875                    + " (IApplicationThread " + thread + "); dropping process");
4876            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4877            if (pid > 0 && pid != MY_PID) {
4878                Process.killProcessQuiet(pid);
4879            } else {
4880                try {
4881                    thread.scheduleExit();
4882                } catch (Exception e) {
4883                    // Ignore exceptions.
4884                }
4885            }
4886            return false;
4887        }
4888
4889        // If this application record is still attached to a previous
4890        // process, clean it up now.
4891        if (app.thread != null) {
4892            handleAppDiedLocked(app, true, true);
4893        }
4894
4895        // Tell the process all about itself.
4896
4897        if (localLOGV) Slog.v(
4898                TAG, "Binding process pid " + pid + " to record " + app);
4899
4900        final String processName = app.processName;
4901        try {
4902            AppDeathRecipient adr = new AppDeathRecipient(
4903                    app, pid, thread);
4904            thread.asBinder().linkToDeath(adr, 0);
4905            app.deathRecipient = adr;
4906        } catch (RemoteException e) {
4907            app.resetPackageList(mProcessStats);
4908            startProcessLocked(app, "link fail", processName);
4909            return false;
4910        }
4911
4912        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
4913
4914        app.makeActive(thread, mProcessStats);
4915        app.curAdj = app.setAdj = -100;
4916        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
4917        app.forcingToForeground = null;
4918        updateProcessForegroundLocked(app, false, false);
4919        app.hasShownUi = false;
4920        app.debugging = false;
4921        app.cached = false;
4922
4923        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4924
4925        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4926        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4927
4928        if (!normalMode) {
4929            Slog.i(TAG, "Launching preboot mode app: " + app);
4930        }
4931
4932        if (localLOGV) Slog.v(
4933            TAG, "New app record " + app
4934            + " thread=" + thread.asBinder() + " pid=" + pid);
4935        try {
4936            int testMode = IApplicationThread.DEBUG_OFF;
4937            if (mDebugApp != null && mDebugApp.equals(processName)) {
4938                testMode = mWaitForDebugger
4939                    ? IApplicationThread.DEBUG_WAIT
4940                    : IApplicationThread.DEBUG_ON;
4941                app.debugging = true;
4942                if (mDebugTransient) {
4943                    mDebugApp = mOrigDebugApp;
4944                    mWaitForDebugger = mOrigWaitForDebugger;
4945                }
4946            }
4947            String profileFile = app.instrumentationProfileFile;
4948            ParcelFileDescriptor profileFd = null;
4949            boolean profileAutoStop = false;
4950            if (mProfileApp != null && mProfileApp.equals(processName)) {
4951                mProfileProc = app;
4952                profileFile = mProfileFile;
4953                profileFd = mProfileFd;
4954                profileAutoStop = mAutoStopProfiler;
4955            }
4956            boolean enableOpenGlTrace = false;
4957            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4958                enableOpenGlTrace = true;
4959                mOpenGlTraceApp = null;
4960            }
4961
4962            // If the app is being launched for restore or full backup, set it up specially
4963            boolean isRestrictedBackupMode = false;
4964            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4965                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4966                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4967                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4968            }
4969
4970            ensurePackageDexOpt(app.instrumentationInfo != null
4971                    ? app.instrumentationInfo.packageName
4972                    : app.info.packageName);
4973            if (app.instrumentationClass != null) {
4974                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4975            }
4976            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4977                    + processName + " with config " + mConfiguration);
4978            ApplicationInfo appInfo = app.instrumentationInfo != null
4979                    ? app.instrumentationInfo : app.info;
4980            app.compat = compatibilityInfoForPackageLocked(appInfo);
4981            if (profileFd != null) {
4982                profileFd = profileFd.dup();
4983            }
4984            thread.bindApplication(processName, appInfo, providers,
4985                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4986                    app.instrumentationArguments, app.instrumentationWatcher,
4987                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
4988                    isRestrictedBackupMode || !normalMode, app.persistent,
4989                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4990                    mCoreSettingsObserver.getCoreSettingsLocked());
4991            updateLruProcessLocked(app, false, null);
4992            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4993        } catch (Exception e) {
4994            // todo: Yikes!  What should we do?  For now we will try to
4995            // start another process, but that could easily get us in
4996            // an infinite loop of restarting processes...
4997            Slog.w(TAG, "Exception thrown during bind!", e);
4998
4999            app.resetPackageList(mProcessStats);
5000            app.unlinkDeathRecipient();
5001            startProcessLocked(app, "bind fail", processName);
5002            return false;
5003        }
5004
5005        // Remove this record from the list of starting applications.
5006        mPersistentStartingProcesses.remove(app);
5007        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5008                "Attach application locked removing on hold: " + app);
5009        mProcessesOnHold.remove(app);
5010
5011        boolean badApp = false;
5012        boolean didSomething = false;
5013
5014        // See if the top visible activity is waiting to run in this process...
5015        if (normalMode) {
5016            try {
5017                if (mStackSupervisor.attachApplicationLocked(app)) {
5018                    didSomething = true;
5019                }
5020            } catch (Exception e) {
5021                badApp = true;
5022            }
5023        }
5024
5025        // Find any services that should be running in this process...
5026        if (!badApp) {
5027            try {
5028                didSomething |= mServices.attachApplicationLocked(app, processName);
5029            } catch (Exception e) {
5030                badApp = true;
5031            }
5032        }
5033
5034        // Check if a next-broadcast receiver is in this process...
5035        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5036            try {
5037                didSomething |= sendPendingBroadcastsLocked(app);
5038            } catch (Exception e) {
5039                // If the app died trying to launch the receiver we declare it 'bad'
5040                badApp = true;
5041            }
5042        }
5043
5044        // Check whether the next backup agent is in this process...
5045        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5046            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5047            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5048            try {
5049                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5050                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5051                        mBackupTarget.backupMode);
5052            } catch (Exception e) {
5053                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5054                e.printStackTrace();
5055            }
5056        }
5057
5058        if (badApp) {
5059            // todo: Also need to kill application to deal with all
5060            // kinds of exceptions.
5061            handleAppDiedLocked(app, false, true);
5062            return false;
5063        }
5064
5065        if (!didSomething) {
5066            updateOomAdjLocked();
5067        }
5068
5069        return true;
5070    }
5071
5072    @Override
5073    public final void attachApplication(IApplicationThread thread) {
5074        synchronized (this) {
5075            int callingPid = Binder.getCallingPid();
5076            final long origId = Binder.clearCallingIdentity();
5077            attachApplicationLocked(thread, callingPid);
5078            Binder.restoreCallingIdentity(origId);
5079        }
5080    }
5081
5082    @Override
5083    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5084        final long origId = Binder.clearCallingIdentity();
5085        synchronized (this) {
5086            ActivityStack stack = ActivityRecord.getStackLocked(token);
5087            if (stack != null) {
5088                ActivityRecord r =
5089                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5090                if (stopProfiling) {
5091                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5092                        try {
5093                            mProfileFd.close();
5094                        } catch (IOException e) {
5095                        }
5096                        clearProfilerLocked();
5097                    }
5098                }
5099            }
5100        }
5101        Binder.restoreCallingIdentity(origId);
5102    }
5103
5104    void enableScreenAfterBoot() {
5105        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5106                SystemClock.uptimeMillis());
5107        mWindowManager.enableScreenAfterBoot();
5108
5109        synchronized (this) {
5110            updateEventDispatchingLocked();
5111        }
5112    }
5113
5114    @Override
5115    public void showBootMessage(final CharSequence msg, final boolean always) {
5116        enforceNotIsolatedCaller("showBootMessage");
5117        mWindowManager.showBootMessage(msg, always);
5118    }
5119
5120    @Override
5121    public void dismissKeyguardOnNextActivity() {
5122        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5123        final long token = Binder.clearCallingIdentity();
5124        try {
5125            synchronized (this) {
5126                if (DEBUG_LOCKSCREEN) logLockScreen("");
5127                if (mLockScreenShown) {
5128                    mLockScreenShown = false;
5129                    comeOutOfSleepIfNeededLocked();
5130                }
5131                mStackSupervisor.setDismissKeyguard(true);
5132            }
5133        } finally {
5134            Binder.restoreCallingIdentity(token);
5135        }
5136    }
5137
5138    final void finishBooting() {
5139        IntentFilter pkgFilter = new IntentFilter();
5140        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
5141        pkgFilter.addDataScheme("package");
5142        mContext.registerReceiver(new BroadcastReceiver() {
5143            @Override
5144            public void onReceive(Context context, Intent intent) {
5145                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
5146                if (pkgs != null) {
5147                    for (String pkg : pkgs) {
5148                        synchronized (ActivityManagerService.this) {
5149                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
5150                                    "finished booting")) {
5151                                setResultCode(Activity.RESULT_OK);
5152                                return;
5153                            }
5154                        }
5155                    }
5156                }
5157            }
5158        }, pkgFilter);
5159
5160        synchronized (this) {
5161            // Ensure that any processes we had put on hold are now started
5162            // up.
5163            final int NP = mProcessesOnHold.size();
5164            if (NP > 0) {
5165                ArrayList<ProcessRecord> procs =
5166                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5167                for (int ip=0; ip<NP; ip++) {
5168                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5169                            + procs.get(ip));
5170                    startProcessLocked(procs.get(ip), "on-hold", null);
5171                }
5172            }
5173
5174            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5175                // Start looking for apps that are abusing wake locks.
5176                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5177                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5178                // Tell anyone interested that we are done booting!
5179                SystemProperties.set("sys.boot_completed", "1");
5180                SystemProperties.set("dev.bootcomplete", "1");
5181                for (int i=0; i<mStartedUsers.size(); i++) {
5182                    UserStartedState uss = mStartedUsers.valueAt(i);
5183                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5184                        uss.mState = UserStartedState.STATE_RUNNING;
5185                        final int userId = mStartedUsers.keyAt(i);
5186                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5187                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5188                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5189                        broadcastIntentLocked(null, null, intent, null,
5190                                new IIntentReceiver.Stub() {
5191                                    @Override
5192                                    public void performReceive(Intent intent, int resultCode,
5193                                            String data, Bundle extras, boolean ordered,
5194                                            boolean sticky, int sendingUser) {
5195                                        synchronized (ActivityManagerService.this) {
5196                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5197                                                    true, false);
5198                                        }
5199                                    }
5200                                },
5201                                0, null, null,
5202                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5203                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5204                                userId);
5205                    }
5206                }
5207                scheduleStartRelatedUsersLocked();
5208            }
5209        }
5210    }
5211
5212    final void ensureBootCompleted() {
5213        boolean booting;
5214        boolean enableScreen;
5215        synchronized (this) {
5216            booting = mBooting;
5217            mBooting = false;
5218            enableScreen = !mBooted;
5219            mBooted = true;
5220        }
5221
5222        if (booting) {
5223            finishBooting();
5224        }
5225
5226        if (enableScreen) {
5227            enableScreenAfterBoot();
5228        }
5229    }
5230
5231    @Override
5232    public final void activityResumed(IBinder token) {
5233        final long origId = Binder.clearCallingIdentity();
5234        synchronized(this) {
5235            ActivityStack stack = ActivityRecord.getStackLocked(token);
5236            if (stack != null) {
5237                ActivityRecord.activityResumedLocked(token);
5238            }
5239        }
5240        Binder.restoreCallingIdentity(origId);
5241    }
5242
5243    @Override
5244    public final void activityPaused(IBinder token) {
5245        final long origId = Binder.clearCallingIdentity();
5246        synchronized(this) {
5247            ActivityStack stack = ActivityRecord.getStackLocked(token);
5248            if (stack != null) {
5249                stack.activityPausedLocked(token, false);
5250            }
5251        }
5252        Binder.restoreCallingIdentity(origId);
5253    }
5254
5255    @Override
5256    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
5257            CharSequence description) {
5258        if (localLOGV) Slog.v(
5259            TAG, "Activity stopped: token=" + token);
5260
5261        // Refuse possible leaked file descriptors
5262        if (icicle != null && icicle.hasFileDescriptors()) {
5263            throw new IllegalArgumentException("File descriptors passed in Bundle");
5264        }
5265
5266        ActivityRecord r = null;
5267
5268        final long origId = Binder.clearCallingIdentity();
5269
5270        synchronized (this) {
5271            r = ActivityRecord.isInStackLocked(token);
5272            if (r != null) {
5273                r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description);
5274            }
5275        }
5276
5277        if (r != null) {
5278            sendPendingThumbnail(r, null, null, null, false);
5279        }
5280
5281        trimApplications();
5282
5283        Binder.restoreCallingIdentity(origId);
5284    }
5285
5286    @Override
5287    public final void activityDestroyed(IBinder token) {
5288        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5289        synchronized (this) {
5290            ActivityStack stack = ActivityRecord.getStackLocked(token);
5291            if (stack != null) {
5292                stack.activityDestroyedLocked(token);
5293            }
5294        }
5295    }
5296
5297    @Override
5298    public String getCallingPackage(IBinder token) {
5299        synchronized (this) {
5300            ActivityRecord r = getCallingRecordLocked(token);
5301            return r != null ? r.info.packageName : null;
5302        }
5303    }
5304
5305    @Override
5306    public ComponentName getCallingActivity(IBinder token) {
5307        synchronized (this) {
5308            ActivityRecord r = getCallingRecordLocked(token);
5309            return r != null ? r.intent.getComponent() : null;
5310        }
5311    }
5312
5313    private ActivityRecord getCallingRecordLocked(IBinder token) {
5314        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5315        if (r == null) {
5316            return null;
5317        }
5318        return r.resultTo;
5319    }
5320
5321    @Override
5322    public ComponentName getActivityClassForToken(IBinder token) {
5323        synchronized(this) {
5324            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5325            if (r == null) {
5326                return null;
5327            }
5328            return r.intent.getComponent();
5329        }
5330    }
5331
5332    @Override
5333    public String getPackageForToken(IBinder token) {
5334        synchronized(this) {
5335            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5336            if (r == null) {
5337                return null;
5338            }
5339            return r.packageName;
5340        }
5341    }
5342
5343    @Override
5344    public IIntentSender getIntentSender(int type,
5345            String packageName, IBinder token, String resultWho,
5346            int requestCode, Intent[] intents, String[] resolvedTypes,
5347            int flags, Bundle options, int userId) {
5348        enforceNotIsolatedCaller("getIntentSender");
5349        // Refuse possible leaked file descriptors
5350        if (intents != null) {
5351            if (intents.length < 1) {
5352                throw new IllegalArgumentException("Intents array length must be >= 1");
5353            }
5354            for (int i=0; i<intents.length; i++) {
5355                Intent intent = intents[i];
5356                if (intent != null) {
5357                    if (intent.hasFileDescriptors()) {
5358                        throw new IllegalArgumentException("File descriptors passed in Intent");
5359                    }
5360                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5361                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5362                        throw new IllegalArgumentException(
5363                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5364                    }
5365                    intents[i] = new Intent(intent);
5366                }
5367            }
5368            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5369                throw new IllegalArgumentException(
5370                        "Intent array length does not match resolvedTypes length");
5371            }
5372        }
5373        if (options != null) {
5374            if (options.hasFileDescriptors()) {
5375                throw new IllegalArgumentException("File descriptors passed in options");
5376            }
5377        }
5378
5379        synchronized(this) {
5380            int callingUid = Binder.getCallingUid();
5381            int origUserId = userId;
5382            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5383                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5384                    "getIntentSender", null);
5385            if (origUserId == UserHandle.USER_CURRENT) {
5386                // We don't want to evaluate this until the pending intent is
5387                // actually executed.  However, we do want to always do the
5388                // security checking for it above.
5389                userId = UserHandle.USER_CURRENT;
5390            }
5391            try {
5392                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5393                    int uid = AppGlobals.getPackageManager()
5394                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5395                    if (!UserHandle.isSameApp(callingUid, uid)) {
5396                        String msg = "Permission Denial: getIntentSender() from pid="
5397                            + Binder.getCallingPid()
5398                            + ", uid=" + Binder.getCallingUid()
5399                            + ", (need uid=" + uid + ")"
5400                            + " is not allowed to send as package " + packageName;
5401                        Slog.w(TAG, msg);
5402                        throw new SecurityException(msg);
5403                    }
5404                }
5405
5406                return getIntentSenderLocked(type, packageName, callingUid, userId,
5407                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5408
5409            } catch (RemoteException e) {
5410                throw new SecurityException(e);
5411            }
5412        }
5413    }
5414
5415    IIntentSender getIntentSenderLocked(int type, String packageName,
5416            int callingUid, int userId, IBinder token, String resultWho,
5417            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5418            Bundle options) {
5419        if (DEBUG_MU)
5420            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5421        ActivityRecord activity = null;
5422        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5423            activity = ActivityRecord.isInStackLocked(token);
5424            if (activity == null) {
5425                return null;
5426            }
5427            if (activity.finishing) {
5428                return null;
5429            }
5430        }
5431
5432        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5433        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5434        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5435        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5436                |PendingIntent.FLAG_UPDATE_CURRENT);
5437
5438        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5439                type, packageName, activity, resultWho,
5440                requestCode, intents, resolvedTypes, flags, options, userId);
5441        WeakReference<PendingIntentRecord> ref;
5442        ref = mIntentSenderRecords.get(key);
5443        PendingIntentRecord rec = ref != null ? ref.get() : null;
5444        if (rec != null) {
5445            if (!cancelCurrent) {
5446                if (updateCurrent) {
5447                    if (rec.key.requestIntent != null) {
5448                        rec.key.requestIntent.replaceExtras(intents != null ?
5449                                intents[intents.length - 1] : null);
5450                    }
5451                    if (intents != null) {
5452                        intents[intents.length-1] = rec.key.requestIntent;
5453                        rec.key.allIntents = intents;
5454                        rec.key.allResolvedTypes = resolvedTypes;
5455                    } else {
5456                        rec.key.allIntents = null;
5457                        rec.key.allResolvedTypes = null;
5458                    }
5459                }
5460                return rec;
5461            }
5462            rec.canceled = true;
5463            mIntentSenderRecords.remove(key);
5464        }
5465        if (noCreate) {
5466            return rec;
5467        }
5468        rec = new PendingIntentRecord(this, key, callingUid);
5469        mIntentSenderRecords.put(key, rec.ref);
5470        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5471            if (activity.pendingResults == null) {
5472                activity.pendingResults
5473                        = new HashSet<WeakReference<PendingIntentRecord>>();
5474            }
5475            activity.pendingResults.add(rec.ref);
5476        }
5477        return rec;
5478    }
5479
5480    @Override
5481    public void cancelIntentSender(IIntentSender sender) {
5482        if (!(sender instanceof PendingIntentRecord)) {
5483            return;
5484        }
5485        synchronized(this) {
5486            PendingIntentRecord rec = (PendingIntentRecord)sender;
5487            try {
5488                int uid = AppGlobals.getPackageManager()
5489                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5490                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5491                    String msg = "Permission Denial: cancelIntentSender() from pid="
5492                        + Binder.getCallingPid()
5493                        + ", uid=" + Binder.getCallingUid()
5494                        + " is not allowed to cancel packges "
5495                        + rec.key.packageName;
5496                    Slog.w(TAG, msg);
5497                    throw new SecurityException(msg);
5498                }
5499            } catch (RemoteException e) {
5500                throw new SecurityException(e);
5501            }
5502            cancelIntentSenderLocked(rec, true);
5503        }
5504    }
5505
5506    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5507        rec.canceled = true;
5508        mIntentSenderRecords.remove(rec.key);
5509        if (cleanActivity && rec.key.activity != null) {
5510            rec.key.activity.pendingResults.remove(rec.ref);
5511        }
5512    }
5513
5514    @Override
5515    public String getPackageForIntentSender(IIntentSender pendingResult) {
5516        if (!(pendingResult instanceof PendingIntentRecord)) {
5517            return null;
5518        }
5519        try {
5520            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5521            return res.key.packageName;
5522        } catch (ClassCastException e) {
5523        }
5524        return null;
5525    }
5526
5527    @Override
5528    public int getUidForIntentSender(IIntentSender sender) {
5529        if (sender instanceof PendingIntentRecord) {
5530            try {
5531                PendingIntentRecord res = (PendingIntentRecord)sender;
5532                return res.uid;
5533            } catch (ClassCastException e) {
5534            }
5535        }
5536        return -1;
5537    }
5538
5539    @Override
5540    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5541        if (!(pendingResult instanceof PendingIntentRecord)) {
5542            return false;
5543        }
5544        try {
5545            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5546            if (res.key.allIntents == null) {
5547                return false;
5548            }
5549            for (int i=0; i<res.key.allIntents.length; i++) {
5550                Intent intent = res.key.allIntents[i];
5551                if (intent.getPackage() != null && intent.getComponent() != null) {
5552                    return false;
5553                }
5554            }
5555            return true;
5556        } catch (ClassCastException e) {
5557        }
5558        return false;
5559    }
5560
5561    @Override
5562    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5563        if (!(pendingResult instanceof PendingIntentRecord)) {
5564            return false;
5565        }
5566        try {
5567            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5568            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5569                return true;
5570            }
5571            return false;
5572        } catch (ClassCastException e) {
5573        }
5574        return false;
5575    }
5576
5577    @Override
5578    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5579        if (!(pendingResult instanceof PendingIntentRecord)) {
5580            return null;
5581        }
5582        try {
5583            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5584            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5585        } catch (ClassCastException e) {
5586        }
5587        return null;
5588    }
5589
5590    @Override
5591    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5592        if (!(pendingResult instanceof PendingIntentRecord)) {
5593            return null;
5594        }
5595        try {
5596            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5597            Intent intent = res.key.requestIntent;
5598            if (intent != null) {
5599                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5600                        || res.lastTagPrefix.equals(prefix))) {
5601                    return res.lastTag;
5602                }
5603                res.lastTagPrefix = prefix;
5604                StringBuilder sb = new StringBuilder(128);
5605                if (prefix != null) {
5606                    sb.append(prefix);
5607                }
5608                if (intent.getAction() != null) {
5609                    sb.append(intent.getAction());
5610                } else if (intent.getComponent() != null) {
5611                    intent.getComponent().appendShortString(sb);
5612                } else {
5613                    sb.append("?");
5614                }
5615                return res.lastTag = sb.toString();
5616            }
5617        } catch (ClassCastException e) {
5618        }
5619        return null;
5620    }
5621
5622    @Override
5623    public void setProcessLimit(int max) {
5624        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5625                "setProcessLimit()");
5626        synchronized (this) {
5627            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5628            mProcessLimitOverride = max;
5629        }
5630        trimApplications();
5631    }
5632
5633    @Override
5634    public int getProcessLimit() {
5635        synchronized (this) {
5636            return mProcessLimitOverride;
5637        }
5638    }
5639
5640    void foregroundTokenDied(ForegroundToken token) {
5641        synchronized (ActivityManagerService.this) {
5642            synchronized (mPidsSelfLocked) {
5643                ForegroundToken cur
5644                    = mForegroundProcesses.get(token.pid);
5645                if (cur != token) {
5646                    return;
5647                }
5648                mForegroundProcesses.remove(token.pid);
5649                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5650                if (pr == null) {
5651                    return;
5652                }
5653                pr.forcingToForeground = null;
5654                updateProcessForegroundLocked(pr, false, false);
5655            }
5656            updateOomAdjLocked();
5657        }
5658    }
5659
5660    @Override
5661    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5662        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5663                "setProcessForeground()");
5664        synchronized(this) {
5665            boolean changed = false;
5666
5667            synchronized (mPidsSelfLocked) {
5668                ProcessRecord pr = mPidsSelfLocked.get(pid);
5669                if (pr == null && isForeground) {
5670                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5671                    return;
5672                }
5673                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5674                if (oldToken != null) {
5675                    oldToken.token.unlinkToDeath(oldToken, 0);
5676                    mForegroundProcesses.remove(pid);
5677                    if (pr != null) {
5678                        pr.forcingToForeground = null;
5679                    }
5680                    changed = true;
5681                }
5682                if (isForeground && token != null) {
5683                    ForegroundToken newToken = new ForegroundToken() {
5684                        @Override
5685                        public void binderDied() {
5686                            foregroundTokenDied(this);
5687                        }
5688                    };
5689                    newToken.pid = pid;
5690                    newToken.token = token;
5691                    try {
5692                        token.linkToDeath(newToken, 0);
5693                        mForegroundProcesses.put(pid, newToken);
5694                        pr.forcingToForeground = token;
5695                        changed = true;
5696                    } catch (RemoteException e) {
5697                        // If the process died while doing this, we will later
5698                        // do the cleanup with the process death link.
5699                    }
5700                }
5701            }
5702
5703            if (changed) {
5704                updateOomAdjLocked();
5705            }
5706        }
5707    }
5708
5709    // =========================================================
5710    // PERMISSIONS
5711    // =========================================================
5712
5713    static class PermissionController extends IPermissionController.Stub {
5714        ActivityManagerService mActivityManagerService;
5715        PermissionController(ActivityManagerService activityManagerService) {
5716            mActivityManagerService = activityManagerService;
5717        }
5718
5719        @Override
5720        public boolean checkPermission(String permission, int pid, int uid) {
5721            return mActivityManagerService.checkPermission(permission, pid,
5722                    uid) == PackageManager.PERMISSION_GRANTED;
5723        }
5724    }
5725
5726    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5727        @Override
5728        public int checkComponentPermission(String permission, int pid, int uid,
5729                int owningUid, boolean exported) {
5730            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5731                    owningUid, exported);
5732        }
5733
5734        @Override
5735        public Object getAMSLock() {
5736            return ActivityManagerService.this;
5737        }
5738    }
5739
5740    /**
5741     * This can be called with or without the global lock held.
5742     */
5743    int checkComponentPermission(String permission, int pid, int uid,
5744            int owningUid, boolean exported) {
5745        // We might be performing an operation on behalf of an indirect binder
5746        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5747        // client identity accordingly before proceeding.
5748        Identity tlsIdentity = sCallerIdentity.get();
5749        if (tlsIdentity != null) {
5750            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5751                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5752            uid = tlsIdentity.uid;
5753            pid = tlsIdentity.pid;
5754        }
5755
5756        if (pid == MY_PID) {
5757            return PackageManager.PERMISSION_GRANTED;
5758        }
5759
5760        return ActivityManager.checkComponentPermission(permission, uid,
5761                owningUid, exported);
5762    }
5763
5764    /**
5765     * As the only public entry point for permissions checking, this method
5766     * can enforce the semantic that requesting a check on a null global
5767     * permission is automatically denied.  (Internally a null permission
5768     * string is used when calling {@link #checkComponentPermission} in cases
5769     * when only uid-based security is needed.)
5770     *
5771     * This can be called with or without the global lock held.
5772     */
5773    @Override
5774    public int checkPermission(String permission, int pid, int uid) {
5775        if (permission == null) {
5776            return PackageManager.PERMISSION_DENIED;
5777        }
5778        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5779    }
5780
5781    /**
5782     * Binder IPC calls go through the public entry point.
5783     * This can be called with or without the global lock held.
5784     */
5785    int checkCallingPermission(String permission) {
5786        return checkPermission(permission,
5787                Binder.getCallingPid(),
5788                UserHandle.getAppId(Binder.getCallingUid()));
5789    }
5790
5791    /**
5792     * This can be called with or without the global lock held.
5793     */
5794    void enforceCallingPermission(String permission, String func) {
5795        if (checkCallingPermission(permission)
5796                == PackageManager.PERMISSION_GRANTED) {
5797            return;
5798        }
5799
5800        String msg = "Permission Denial: " + func + " from pid="
5801                + Binder.getCallingPid()
5802                + ", uid=" + Binder.getCallingUid()
5803                + " requires " + permission;
5804        Slog.w(TAG, msg);
5805        throw new SecurityException(msg);
5806    }
5807
5808    /**
5809     * Determine if UID is holding permissions required to access {@link Uri} in
5810     * the given {@link ProviderInfo}. Final permission checking is always done
5811     * in {@link ContentProvider}.
5812     */
5813    private final boolean checkHoldingPermissionsLocked(
5814            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
5815        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5816                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
5817
5818        if (pi.applicationInfo.uid == uid) {
5819            return true;
5820        } else if (!pi.exported) {
5821            return false;
5822        }
5823
5824        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
5825        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
5826        try {
5827            // check if target holds top-level <provider> permissions
5828            if (!readMet && pi.readPermission != null
5829                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
5830                readMet = true;
5831            }
5832            if (!writeMet && pi.writePermission != null
5833                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
5834                writeMet = true;
5835            }
5836
5837            // track if unprotected read/write is allowed; any denied
5838            // <path-permission> below removes this ability
5839            boolean allowDefaultRead = pi.readPermission == null;
5840            boolean allowDefaultWrite = pi.writePermission == null;
5841
5842            // check if target holds any <path-permission> that match uri
5843            final PathPermission[] pps = pi.pathPermissions;
5844            if (pps != null) {
5845                final String path = uri.getPath();
5846                int i = pps.length;
5847                while (i > 0 && (!readMet || !writeMet)) {
5848                    i--;
5849                    PathPermission pp = pps[i];
5850                    if (pp.match(path)) {
5851                        if (!readMet) {
5852                            final String pprperm = pp.getReadPermission();
5853                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
5854                                    + pprperm + " for " + pp.getPath()
5855                                    + ": match=" + pp.match(path)
5856                                    + " check=" + pm.checkUidPermission(pprperm, uid));
5857                            if (pprperm != null) {
5858                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
5859                                    readMet = true;
5860                                } else {
5861                                    allowDefaultRead = false;
5862                                }
5863                            }
5864                        }
5865                        if (!writeMet) {
5866                            final String ppwperm = pp.getWritePermission();
5867                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
5868                                    + ppwperm + " for " + pp.getPath()
5869                                    + ": match=" + pp.match(path)
5870                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
5871                            if (ppwperm != null) {
5872                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
5873                                    writeMet = true;
5874                                } else {
5875                                    allowDefaultWrite = false;
5876                                }
5877                            }
5878                        }
5879                    }
5880                }
5881            }
5882
5883            // grant unprotected <provider> read/write, if not blocked by
5884            // <path-permission> above
5885            if (allowDefaultRead) readMet = true;
5886            if (allowDefaultWrite) writeMet = true;
5887
5888        } catch (RemoteException e) {
5889            return false;
5890        }
5891
5892        return readMet && writeMet;
5893    }
5894
5895    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
5896        ProviderInfo pi = null;
5897        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
5898        if (cpr != null) {
5899            pi = cpr.info;
5900        } else {
5901            try {
5902                pi = AppGlobals.getPackageManager().resolveContentProvider(
5903                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
5904            } catch (RemoteException ex) {
5905            }
5906        }
5907        return pi;
5908    }
5909
5910    private UriPermission findUriPermissionLocked(int targetUid, Uri uri) {
5911        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5912        if (targetUris != null) {
5913            return targetUris.get(uri);
5914        } else {
5915            return null;
5916        }
5917    }
5918
5919    private UriPermission findOrCreateUriPermissionLocked(
5920            String sourcePkg, String targetPkg, int targetUid, Uri uri) {
5921        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5922        if (targetUris == null) {
5923            targetUris = Maps.newArrayMap();
5924            mGrantedUriPermissions.put(targetUid, targetUris);
5925        }
5926
5927        UriPermission perm = targetUris.get(uri);
5928        if (perm == null) {
5929            perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri);
5930            targetUris.put(uri, perm);
5931        }
5932
5933        return perm;
5934    }
5935
5936    private final boolean checkUriPermissionLocked(
5937            Uri uri, int uid, int modeFlags, int minStrength) {
5938        // Root gets to do everything.
5939        if (uid == 0) {
5940            return true;
5941        }
5942        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5943        if (perms == null) return false;
5944        UriPermission perm = perms.get(uri);
5945        if (perm == null) return false;
5946        return perm.getStrength(modeFlags) >= minStrength;
5947    }
5948
5949    @Override
5950    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
5951        enforceNotIsolatedCaller("checkUriPermission");
5952
5953        // Another redirected-binder-call permissions check as in
5954        // {@link checkComponentPermission}.
5955        Identity tlsIdentity = sCallerIdentity.get();
5956        if (tlsIdentity != null) {
5957            uid = tlsIdentity.uid;
5958            pid = tlsIdentity.pid;
5959        }
5960
5961        // Our own process gets to do everything.
5962        if (pid == MY_PID) {
5963            return PackageManager.PERMISSION_GRANTED;
5964        }
5965        synchronized(this) {
5966            return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED)
5967                    ? PackageManager.PERMISSION_GRANTED
5968                    : PackageManager.PERMISSION_DENIED;
5969        }
5970    }
5971
5972    /**
5973     * Check if the targetPkg can be granted permission to access uri by
5974     * the callingUid using the given modeFlags.  Throws a security exception
5975     * if callingUid is not allowed to do this.  Returns the uid of the target
5976     * if the URI permission grant should be performed; returns -1 if it is not
5977     * needed (for example targetPkg already has permission to access the URI).
5978     * If you already know the uid of the target, you can supply it in
5979     * lastTargetUid else set that to -1.
5980     */
5981    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5982            Uri uri, int modeFlags, int lastTargetUid) {
5983        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
5984        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5985                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5986        if (modeFlags == 0) {
5987            return -1;
5988        }
5989
5990        if (targetPkg != null) {
5991            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5992                    "Checking grant " + targetPkg + " permission to " + uri);
5993        }
5994
5995        final IPackageManager pm = AppGlobals.getPackageManager();
5996
5997        // If this is not a content: uri, we can't do anything with it.
5998        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
5999            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6000                    "Can't grant URI permission for non-content URI: " + uri);
6001            return -1;
6002        }
6003
6004        final String authority = uri.getAuthority();
6005        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6006        if (pi == null) {
6007            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
6008            return -1;
6009        }
6010
6011        int targetUid = lastTargetUid;
6012        if (targetUid < 0 && targetPkg != null) {
6013            try {
6014                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6015                if (targetUid < 0) {
6016                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6017                            "Can't grant URI permission no uid for: " + targetPkg);
6018                    return -1;
6019                }
6020            } catch (RemoteException ex) {
6021                return -1;
6022            }
6023        }
6024
6025        if (targetUid >= 0) {
6026            // First...  does the target actually need this permission?
6027            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
6028                // No need to grant the target this permission.
6029                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6030                        "Target " + targetPkg + " already has full permission to " + uri);
6031                return -1;
6032            }
6033        } else {
6034            // First...  there is no target package, so can anyone access it?
6035            boolean allowed = pi.exported;
6036            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6037                if (pi.readPermission != null) {
6038                    allowed = false;
6039                }
6040            }
6041            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6042                if (pi.writePermission != null) {
6043                    allowed = false;
6044                }
6045            }
6046            if (allowed) {
6047                return -1;
6048            }
6049        }
6050
6051        // Second...  is the provider allowing granting of URI permissions?
6052        if (!pi.grantUriPermissions) {
6053            throw new SecurityException("Provider " + pi.packageName
6054                    + "/" + pi.name
6055                    + " does not allow granting of Uri permissions (uri "
6056                    + uri + ")");
6057        }
6058        if (pi.uriPermissionPatterns != null) {
6059            final int N = pi.uriPermissionPatterns.length;
6060            boolean allowed = false;
6061            for (int i=0; i<N; i++) {
6062                if (pi.uriPermissionPatterns[i] != null
6063                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
6064                    allowed = true;
6065                    break;
6066                }
6067            }
6068            if (!allowed) {
6069                throw new SecurityException("Provider " + pi.packageName
6070                        + "/" + pi.name
6071                        + " does not allow granting of permission to path of Uri "
6072                        + uri);
6073            }
6074        }
6075
6076        // Third...  does the caller itself have permission to access
6077        // this uri?
6078        if (callingUid != Process.myUid()) {
6079            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6080                // Require they hold a strong enough Uri permission
6081                final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6082                        : UriPermission.STRENGTH_OWNED;
6083                if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) {
6084                    throw new SecurityException("Uid " + callingUid
6085                            + " does not have permission to uri " + uri);
6086                }
6087            }
6088        }
6089
6090        return targetUid;
6091    }
6092
6093    @Override
6094    public int checkGrantUriPermission(int callingUid, String targetPkg,
6095            Uri uri, int modeFlags) {
6096        enforceNotIsolatedCaller("checkGrantUriPermission");
6097        synchronized(this) {
6098            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6099        }
6100    }
6101
6102    void grantUriPermissionUncheckedLocked(
6103            int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
6104        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6105        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6106                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6107        if (modeFlags == 0) {
6108            return;
6109        }
6110
6111        // So here we are: the caller has the assumed permission
6112        // to the uri, and the target doesn't.  Let's now give this to
6113        // the target.
6114
6115        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6116                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
6117
6118        final String authority = uri.getAuthority();
6119        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid));
6120        if (pi == null) {
6121            Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString());
6122            return;
6123        }
6124
6125        final UriPermission perm = findOrCreateUriPermissionLocked(
6126                pi.packageName, targetPkg, targetUid, uri);
6127        perm.grantModes(modeFlags, persistable, owner);
6128    }
6129
6130    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
6131            int modeFlags, UriPermissionOwner owner) {
6132        if (targetPkg == null) {
6133            throw new NullPointerException("targetPkg");
6134        }
6135
6136        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6137        if (targetUid < 0) {
6138            return;
6139        }
6140
6141        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
6142    }
6143
6144    static class NeededUriGrants extends ArrayList<Uri> {
6145        final String targetPkg;
6146        final int targetUid;
6147        final int flags;
6148
6149        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6150            this.targetPkg = targetPkg;
6151            this.targetUid = targetUid;
6152            this.flags = flags;
6153        }
6154    }
6155
6156    /**
6157     * Like checkGrantUriPermissionLocked, but takes an Intent.
6158     */
6159    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6160            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6161        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6162                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6163                + " clip=" + (intent != null ? intent.getClipData() : null)
6164                + " from " + intent + "; flags=0x"
6165                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6166
6167        if (targetPkg == null) {
6168            throw new NullPointerException("targetPkg");
6169        }
6170
6171        if (intent == null) {
6172            return null;
6173        }
6174        Uri data = intent.getData();
6175        ClipData clip = intent.getClipData();
6176        if (data == null && clip == null) {
6177            return null;
6178        }
6179
6180        if (data != null) {
6181            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
6182                mode, needed != null ? needed.targetUid : -1);
6183            if (targetUid > 0) {
6184                if (needed == null) {
6185                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6186                }
6187                needed.add(data);
6188            }
6189        }
6190        if (clip != null) {
6191            for (int i=0; i<clip.getItemCount(); i++) {
6192                Uri uri = clip.getItemAt(i).getUri();
6193                if (uri != null) {
6194                    int targetUid = -1;
6195                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
6196                            mode, needed != null ? needed.targetUid : -1);
6197                    if (targetUid > 0) {
6198                        if (needed == null) {
6199                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6200                        }
6201                        needed.add(uri);
6202                    }
6203                } else {
6204                    Intent clipIntent = clip.getItemAt(i).getIntent();
6205                    if (clipIntent != null) {
6206                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6207                                callingUid, targetPkg, clipIntent, mode, needed);
6208                        if (newNeeded != null) {
6209                            needed = newNeeded;
6210                        }
6211                    }
6212                }
6213            }
6214        }
6215
6216        return needed;
6217    }
6218
6219    /**
6220     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6221     */
6222    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6223            UriPermissionOwner owner) {
6224        if (needed != null) {
6225            for (int i=0; i<needed.size(); i++) {
6226                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6227                        needed.get(i), needed.flags, owner);
6228            }
6229        }
6230    }
6231
6232    void grantUriPermissionFromIntentLocked(int callingUid,
6233            String targetPkg, Intent intent, UriPermissionOwner owner) {
6234        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6235                intent, intent != null ? intent.getFlags() : 0, null);
6236        if (needed == null) {
6237            return;
6238        }
6239
6240        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6241    }
6242
6243    @Override
6244    public void grantUriPermission(IApplicationThread caller, String targetPkg,
6245            Uri uri, int modeFlags) {
6246        enforceNotIsolatedCaller("grantUriPermission");
6247        synchronized(this) {
6248            final ProcessRecord r = getRecordForAppLocked(caller);
6249            if (r == null) {
6250                throw new SecurityException("Unable to find app for caller "
6251                        + caller
6252                        + " when granting permission to uri " + uri);
6253            }
6254            if (targetPkg == null) {
6255                throw new IllegalArgumentException("null target");
6256            }
6257            if (uri == null) {
6258                throw new IllegalArgumentException("null uri");
6259            }
6260
6261            // Persistable only supported through Intents
6262            Preconditions.checkFlagsArgument(modeFlags,
6263                    Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6264
6265            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
6266                    null);
6267        }
6268    }
6269
6270    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6271        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
6272                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
6273            ArrayMap<Uri, UriPermission> perms
6274                    = mGrantedUriPermissions.get(perm.targetUid);
6275            if (perms != null) {
6276                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6277                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6278                perms.remove(perm.uri);
6279                if (perms.size() == 0) {
6280                    mGrantedUriPermissions.remove(perm.targetUid);
6281                }
6282            }
6283        }
6284    }
6285
6286    private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) {
6287        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri);
6288
6289        final IPackageManager pm = AppGlobals.getPackageManager();
6290        final String authority = uri.getAuthority();
6291        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6292        if (pi == null) {
6293            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
6294            return;
6295        }
6296
6297        // Does the caller have this permission on the URI?
6298        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6299            // Right now, if you are not the original owner of the permission,
6300            // you are not allowed to revoke it.
6301            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6302                throw new SecurityException("Uid " + callingUid
6303                        + " does not have permission to uri " + uri);
6304            //}
6305        }
6306
6307        boolean persistChanged = false;
6308
6309        // Go through all of the permissions and remove any that match.
6310        final List<String> SEGMENTS = uri.getPathSegments();
6311        if (SEGMENTS != null) {
6312            final int NS = SEGMENTS.size();
6313            int N = mGrantedUriPermissions.size();
6314            for (int i=0; i<N; i++) {
6315                ArrayMap<Uri, UriPermission> perms
6316                        = mGrantedUriPermissions.valueAt(i);
6317                Iterator<UriPermission> it = perms.values().iterator();
6318            toploop:
6319                while (it.hasNext()) {
6320                    UriPermission perm = it.next();
6321                    Uri targetUri = perm.uri;
6322                    if (!authority.equals(targetUri.getAuthority())) {
6323                        continue;
6324                    }
6325                    List<String> targetSegments = targetUri.getPathSegments();
6326                    if (targetSegments == null) {
6327                        continue;
6328                    }
6329                    if (targetSegments.size() < NS) {
6330                        continue;
6331                    }
6332                    for (int j=0; j<NS; j++) {
6333                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
6334                            continue toploop;
6335                        }
6336                    }
6337                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6338                            "Revoking " + perm.targetUid + " permission to " + perm.uri);
6339                    persistChanged |= perm.clearModes(modeFlags, true);
6340                    if (perm.modeFlags == 0) {
6341                        it.remove();
6342                    }
6343                }
6344                if (perms.size() == 0) {
6345                    mGrantedUriPermissions.remove(
6346                            mGrantedUriPermissions.keyAt(i));
6347                    N--;
6348                    i--;
6349                }
6350            }
6351        }
6352
6353        if (persistChanged) {
6354            schedulePersistUriGrants();
6355        }
6356    }
6357
6358    @Override
6359    public void revokeUriPermission(IApplicationThread caller, Uri uri,
6360            int modeFlags) {
6361        enforceNotIsolatedCaller("revokeUriPermission");
6362        synchronized(this) {
6363            final ProcessRecord r = getRecordForAppLocked(caller);
6364            if (r == null) {
6365                throw new SecurityException("Unable to find app for caller "
6366                        + caller
6367                        + " when revoking permission to uri " + uri);
6368            }
6369            if (uri == null) {
6370                Slog.w(TAG, "revokeUriPermission: null uri");
6371                return;
6372            }
6373
6374            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6375                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6376            if (modeFlags == 0) {
6377                return;
6378            }
6379
6380            final IPackageManager pm = AppGlobals.getPackageManager();
6381            final String authority = uri.getAuthority();
6382            final ProviderInfo pi = getProviderInfoLocked(authority, r.userId);
6383            if (pi == null) {
6384                Slog.w(TAG, "No content provider found for permission revoke: "
6385                        + uri.toSafeString());
6386                return;
6387            }
6388
6389            revokeUriPermissionLocked(r.uid, uri, modeFlags);
6390        }
6391    }
6392
6393    /**
6394     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6395     * given package.
6396     *
6397     * @param packageName Package name to match, or {@code null} to apply to all
6398     *            packages.
6399     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6400     *            to all users.
6401     * @param persistable If persistable grants should be removed.
6402     */
6403    private void removeUriPermissionsForPackageLocked(
6404            String packageName, int userHandle, boolean persistable) {
6405        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6406            throw new IllegalArgumentException("Must narrow by either package or user");
6407        }
6408
6409        boolean persistChanged = false;
6410
6411        final int size = mGrantedUriPermissions.size();
6412        for (int i = 0; i < size; i++) {
6413            // Only inspect grants matching user
6414            if (userHandle == UserHandle.USER_ALL
6415                    || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) {
6416                final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i)
6417                        .values().iterator();
6418                while (it.hasNext()) {
6419                    final UriPermission perm = it.next();
6420
6421                    // Only inspect grants matching package
6422                    if (packageName == null || perm.sourcePkg.equals(packageName)
6423                            || perm.targetPkg.equals(packageName)) {
6424                        persistChanged |= perm.clearModes(~0, persistable);
6425
6426                        // Only remove when no modes remain; any persisted grants
6427                        // will keep this alive.
6428                        if (perm.modeFlags == 0) {
6429                            it.remove();
6430                        }
6431                    }
6432                }
6433            }
6434        }
6435
6436        if (persistChanged) {
6437            schedulePersistUriGrants();
6438        }
6439    }
6440
6441    @Override
6442    public IBinder newUriPermissionOwner(String name) {
6443        enforceNotIsolatedCaller("newUriPermissionOwner");
6444        synchronized(this) {
6445            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6446            return owner.getExternalTokenLocked();
6447        }
6448    }
6449
6450    @Override
6451    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
6452            Uri uri, int modeFlags) {
6453        synchronized(this) {
6454            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6455            if (owner == null) {
6456                throw new IllegalArgumentException("Unknown owner: " + token);
6457            }
6458            if (fromUid != Binder.getCallingUid()) {
6459                if (Binder.getCallingUid() != Process.myUid()) {
6460                    // Only system code can grant URI permissions on behalf
6461                    // of other users.
6462                    throw new SecurityException("nice try");
6463                }
6464            }
6465            if (targetPkg == null) {
6466                throw new IllegalArgumentException("null target");
6467            }
6468            if (uri == null) {
6469                throw new IllegalArgumentException("null uri");
6470            }
6471
6472            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
6473        }
6474    }
6475
6476    @Override
6477    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
6478        synchronized(this) {
6479            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6480            if (owner == null) {
6481                throw new IllegalArgumentException("Unknown owner: " + token);
6482            }
6483
6484            if (uri == null) {
6485                owner.removeUriPermissionsLocked(mode);
6486            } else {
6487                owner.removeUriPermissionLocked(uri, mode);
6488            }
6489        }
6490    }
6491
6492    private void schedulePersistUriGrants() {
6493        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6494            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6495                    10 * DateUtils.SECOND_IN_MILLIS);
6496        }
6497    }
6498
6499    private void writeGrantedUriPermissions() {
6500        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6501
6502        // Snapshot permissions so we can persist without lock
6503        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6504        synchronized (this) {
6505            final int size = mGrantedUriPermissions.size();
6506            for (int i = 0 ; i < size; i++) {
6507                for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) {
6508                    if (perm.persistedModeFlags != 0) {
6509                        persist.add(perm.snapshot());
6510                    }
6511                }
6512            }
6513        }
6514
6515        FileOutputStream fos = null;
6516        try {
6517            fos = mGrantFile.startWrite();
6518
6519            XmlSerializer out = new FastXmlSerializer();
6520            out.setOutput(fos, "utf-8");
6521            out.startDocument(null, true);
6522            out.startTag(null, TAG_URI_GRANTS);
6523            for (UriPermission.Snapshot perm : persist) {
6524                out.startTag(null, TAG_URI_GRANT);
6525                writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle);
6526                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6527                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6528                out.attribute(null, ATTR_URI, String.valueOf(perm.uri));
6529                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6530                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6531                out.endTag(null, TAG_URI_GRANT);
6532            }
6533            out.endTag(null, TAG_URI_GRANTS);
6534            out.endDocument();
6535
6536            mGrantFile.finishWrite(fos);
6537        } catch (IOException e) {
6538            if (fos != null) {
6539                mGrantFile.failWrite(fos);
6540            }
6541        }
6542    }
6543
6544    private void readGrantedUriPermissionsLocked() {
6545        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6546
6547        final long now = System.currentTimeMillis();
6548
6549        FileInputStream fis = null;
6550        try {
6551            fis = mGrantFile.openRead();
6552            final XmlPullParser in = Xml.newPullParser();
6553            in.setInput(fis, null);
6554
6555            int type;
6556            while ((type = in.next()) != END_DOCUMENT) {
6557                final String tag = in.getName();
6558                if (type == START_TAG) {
6559                    if (TAG_URI_GRANT.equals(tag)) {
6560                        final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE);
6561                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6562                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6563                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6564                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6565                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6566
6567                        // Sanity check that provider still belongs to source package
6568                        final ProviderInfo pi = getProviderInfoLocked(
6569                                uri.getAuthority(), userHandle);
6570                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6571                            int targetUid = -1;
6572                            try {
6573                                targetUid = AppGlobals.getPackageManager()
6574                                        .getPackageUid(targetPkg, userHandle);
6575                            } catch (RemoteException e) {
6576                            }
6577                            if (targetUid != -1) {
6578                                final UriPermission perm = findOrCreateUriPermissionLocked(
6579                                        sourcePkg, targetPkg, targetUid, uri);
6580                                perm.initPersistedModes(modeFlags, createdTime);
6581                            }
6582                        } else {
6583                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6584                                    + " but instead found " + pi);
6585                        }
6586                    }
6587                }
6588            }
6589        } catch (FileNotFoundException e) {
6590            // Missing grants is okay
6591        } catch (IOException e) {
6592            Log.wtf(TAG, "Failed reading Uri grants", e);
6593        } catch (XmlPullParserException e) {
6594            Log.wtf(TAG, "Failed reading Uri grants", e);
6595        } finally {
6596            IoUtils.closeQuietly(fis);
6597        }
6598    }
6599
6600    @Override
6601    public void takePersistableUriPermission(Uri uri, int modeFlags) {
6602        enforceNotIsolatedCaller("takePersistableUriPermission");
6603
6604        Preconditions.checkFlagsArgument(modeFlags,
6605                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6606
6607        synchronized (this) {
6608            final int callingUid = Binder.getCallingUid();
6609            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6610            if (perm == null) {
6611                throw new SecurityException("No permission grant found for UID " + callingUid
6612                        + " and Uri " + uri.toSafeString());
6613            }
6614
6615            boolean persistChanged = perm.takePersistableModes(modeFlags);
6616            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6617
6618            if (persistChanged) {
6619                schedulePersistUriGrants();
6620            }
6621        }
6622    }
6623
6624    @Override
6625    public void releasePersistableUriPermission(Uri uri, int modeFlags) {
6626        enforceNotIsolatedCaller("releasePersistableUriPermission");
6627
6628        Preconditions.checkFlagsArgument(modeFlags,
6629                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6630
6631        synchronized (this) {
6632            final int callingUid = Binder.getCallingUid();
6633
6634            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6635            if (perm == null) {
6636                Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri "
6637                        + uri.toSafeString());
6638                return;
6639            }
6640
6641            final boolean persistChanged = perm.releasePersistableModes(modeFlags);
6642            removeUriPermissionIfNeededLocked(perm);
6643            if (persistChanged) {
6644                schedulePersistUriGrants();
6645            }
6646        }
6647    }
6648
6649    /**
6650     * Prune any older {@link UriPermission} for the given UID until outstanding
6651     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6652     *
6653     * @return if any mutations occured that require persisting.
6654     */
6655    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6656        final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6657        if (perms == null) return false;
6658        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6659
6660        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6661        for (UriPermission perm : perms.values()) {
6662            if (perm.persistedModeFlags != 0) {
6663                persisted.add(perm);
6664            }
6665        }
6666
6667        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6668        if (trimCount <= 0) return false;
6669
6670        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6671        for (int i = 0; i < trimCount; i++) {
6672            final UriPermission perm = persisted.get(i);
6673
6674            if (DEBUG_URI_PERMISSION) {
6675                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6676            }
6677
6678            perm.releasePersistableModes(~0);
6679            removeUriPermissionIfNeededLocked(perm);
6680        }
6681
6682        return true;
6683    }
6684
6685    @Override
6686    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6687            String packageName, boolean incoming) {
6688        enforceNotIsolatedCaller("getPersistedUriPermissions");
6689        Preconditions.checkNotNull(packageName, "packageName");
6690
6691        final int callingUid = Binder.getCallingUid();
6692        final IPackageManager pm = AppGlobals.getPackageManager();
6693        try {
6694            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6695            if (packageUid != callingUid) {
6696                throw new SecurityException(
6697                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6698            }
6699        } catch (RemoteException e) {
6700            throw new SecurityException("Failed to verify package name ownership");
6701        }
6702
6703        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6704        synchronized (this) {
6705            if (incoming) {
6706                final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6707                if (perms == null) {
6708                    Slog.w(TAG, "No permission grants found for " + packageName);
6709                } else {
6710                    final int size = perms.size();
6711                    for (int i = 0; i < size; i++) {
6712                        final UriPermission perm = perms.valueAt(i);
6713                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6714                            result.add(perm.buildPersistedPublicApiObject());
6715                        }
6716                    }
6717                }
6718            } else {
6719                final int size = mGrantedUriPermissions.size();
6720                for (int i = 0; i < size; i++) {
6721                    final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6722                    final int permsSize = perms.size();
6723                    for (int j = 0; j < permsSize; j++) {
6724                        final UriPermission perm = perms.valueAt(j);
6725                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6726                            result.add(perm.buildPersistedPublicApiObject());
6727                        }
6728                    }
6729                }
6730            }
6731        }
6732        return new ParceledListSlice<android.content.UriPermission>(result);
6733    }
6734
6735    @Override
6736    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6737        synchronized (this) {
6738            ProcessRecord app =
6739                who != null ? getRecordForAppLocked(who) : null;
6740            if (app == null) return;
6741
6742            Message msg = Message.obtain();
6743            msg.what = WAIT_FOR_DEBUGGER_MSG;
6744            msg.obj = app;
6745            msg.arg1 = waiting ? 1 : 0;
6746            mHandler.sendMessage(msg);
6747        }
6748    }
6749
6750    @Override
6751    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
6752        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
6753        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
6754        outInfo.availMem = Process.getFreeMemory();
6755        outInfo.totalMem = Process.getTotalMemory();
6756        outInfo.threshold = homeAppMem;
6757        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
6758        outInfo.hiddenAppThreshold = cachedAppMem;
6759        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
6760                ProcessList.SERVICE_ADJ);
6761        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
6762                ProcessList.VISIBLE_APP_ADJ);
6763        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
6764                ProcessList.FOREGROUND_APP_ADJ);
6765    }
6766
6767    // =========================================================
6768    // TASK MANAGEMENT
6769    // =========================================================
6770
6771    @Override
6772    public List<RunningTaskInfo> getTasks(int maxNum, int flags,
6773                         IThumbnailReceiver receiver) {
6774        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
6775
6776        PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver);
6777        ActivityRecord topRecord = null;
6778
6779        synchronized(this) {
6780            if (localLOGV) Slog.v(
6781                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
6782                + ", receiver=" + receiver);
6783
6784            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
6785                    != PackageManager.PERMISSION_GRANTED) {
6786                if (receiver != null) {
6787                    // If the caller wants to wait for pending thumbnails,
6788                    // it ain't gonna get them.
6789                    try {
6790                        receiver.finished();
6791                    } catch (RemoteException ex) {
6792                    }
6793                }
6794                String msg = "Permission Denial: getTasks() from pid="
6795                        + Binder.getCallingPid()
6796                        + ", uid=" + Binder.getCallingUid()
6797                        + " requires " + android.Manifest.permission.GET_TASKS;
6798                Slog.w(TAG, msg);
6799                throw new SecurityException(msg);
6800            }
6801
6802            // TODO: Improve with MRU list from all ActivityStacks.
6803            topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list);
6804
6805            if (!pending.pendingRecords.isEmpty()) {
6806                mPendingThumbnails.add(pending);
6807            }
6808        }
6809
6810        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
6811
6812        if (topRecord != null) {
6813            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
6814            try {
6815                IApplicationThread topThumbnail = topRecord.app.thread;
6816                topThumbnail.requestThumbnail(topRecord.appToken);
6817            } catch (Exception e) {
6818                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
6819                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
6820            }
6821        }
6822
6823        if (pending == null && receiver != null) {
6824            // In this case all thumbnails were available and the client
6825            // is being asked to be told when the remaining ones come in...
6826            // which is unusually, since the top-most currently running
6827            // activity should never have a canned thumbnail!  Oh well.
6828            try {
6829                receiver.finished();
6830            } catch (RemoteException ex) {
6831            }
6832        }
6833
6834        return list;
6835    }
6836
6837    TaskRecord getMostRecentTask() {
6838        return mRecentTasks.get(0);
6839    }
6840
6841    @Override
6842    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
6843            int flags, int userId) {
6844        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6845                false, true, "getRecentTasks", null);
6846
6847        synchronized (this) {
6848            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
6849                    "getRecentTasks()");
6850            final boolean detailed = checkCallingPermission(
6851                    android.Manifest.permission.GET_DETAILED_TASKS)
6852                    == PackageManager.PERMISSION_GRANTED;
6853
6854            IPackageManager pm = AppGlobals.getPackageManager();
6855
6856            final int N = mRecentTasks.size();
6857            ArrayList<ActivityManager.RecentTaskInfo> res
6858                    = new ArrayList<ActivityManager.RecentTaskInfo>(
6859                            maxNum < N ? maxNum : N);
6860            for (int i=0; i<N && maxNum > 0; i++) {
6861                TaskRecord tr = mRecentTasks.get(i);
6862                // Only add calling user's recent tasks
6863                if (tr.userId != userId) continue;
6864                // Return the entry if desired by the caller.  We always return
6865                // the first entry, because callers always expect this to be the
6866                // foreground app.  We may filter others if the caller has
6867                // not supplied RECENT_WITH_EXCLUDED and there is some reason
6868                // we should exclude the entry.
6869
6870                if (i == 0
6871                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
6872                        || (tr.intent == null)
6873                        || ((tr.intent.getFlags()
6874                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
6875                    ActivityManager.RecentTaskInfo rti
6876                            = new ActivityManager.RecentTaskInfo();
6877                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
6878                    rti.persistentId = tr.taskId;
6879                    rti.baseIntent = new Intent(
6880                            tr.intent != null ? tr.intent : tr.affinityIntent);
6881                    if (!detailed) {
6882                        rti.baseIntent.replaceExtras((Bundle)null);
6883                    }
6884                    rti.origActivity = tr.origActivity;
6885                    rti.description = tr.lastDescription;
6886                    rti.stackId = tr.stack.mStackId;
6887
6888                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
6889                        // Check whether this activity is currently available.
6890                        try {
6891                            if (rti.origActivity != null) {
6892                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
6893                                        == null) {
6894                                    continue;
6895                                }
6896                            } else if (rti.baseIntent != null) {
6897                                if (pm.queryIntentActivities(rti.baseIntent,
6898                                        null, 0, userId) == null) {
6899                                    continue;
6900                                }
6901                            }
6902                        } catch (RemoteException e) {
6903                            // Will never happen.
6904                        }
6905                    }
6906
6907                    res.add(rti);
6908                    maxNum--;
6909                }
6910            }
6911            return res;
6912        }
6913    }
6914
6915    private TaskRecord recentTaskForIdLocked(int id) {
6916        final int N = mRecentTasks.size();
6917            for (int i=0; i<N; i++) {
6918                TaskRecord tr = mRecentTasks.get(i);
6919                if (tr.taskId == id) {
6920                    return tr;
6921                }
6922            }
6923            return null;
6924    }
6925
6926    @Override
6927    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
6928        synchronized (this) {
6929            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6930                    "getTaskThumbnails()");
6931            TaskRecord tr = recentTaskForIdLocked(id);
6932            if (tr != null) {
6933                return tr.getTaskThumbnailsLocked();
6934            }
6935        }
6936        return null;
6937    }
6938
6939    @Override
6940    public Bitmap getTaskTopThumbnail(int id) {
6941        synchronized (this) {
6942            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6943                    "getTaskTopThumbnail()");
6944            TaskRecord tr = recentTaskForIdLocked(id);
6945            if (tr != null) {
6946                return tr.getTaskTopThumbnailLocked();
6947            }
6948        }
6949        return null;
6950    }
6951
6952    @Override
6953    public boolean removeSubTask(int taskId, int subTaskIndex) {
6954        synchronized (this) {
6955            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6956                    "removeSubTask()");
6957            long ident = Binder.clearCallingIdentity();
6958            try {
6959                TaskRecord tr = recentTaskForIdLocked(taskId);
6960                if (tr != null) {
6961                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
6962                }
6963                return false;
6964            } finally {
6965                Binder.restoreCallingIdentity(ident);
6966            }
6967        }
6968    }
6969
6970    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
6971        if (!pr.killedByAm) {
6972            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
6973            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
6974                    pr.processName, pr.setAdj, reason);
6975            pr.killedByAm = true;
6976            Process.killProcessQuiet(pr.pid);
6977        }
6978    }
6979
6980    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
6981        tr.disposeThumbnail();
6982        mRecentTasks.remove(tr);
6983        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
6984        Intent baseIntent = new Intent(
6985                tr.intent != null ? tr.intent : tr.affinityIntent);
6986        ComponentName component = baseIntent.getComponent();
6987        if (component == null) {
6988            Slog.w(TAG, "Now component for base intent of task: " + tr);
6989            return;
6990        }
6991
6992        // Find any running services associated with this app.
6993        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
6994
6995        if (killProcesses) {
6996            // Find any running processes associated with this app.
6997            final String pkg = component.getPackageName();
6998            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
6999            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7000            for (int i=0; i<pmap.size(); i++) {
7001                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7002                for (int j=0; j<uids.size(); j++) {
7003                    ProcessRecord proc = uids.valueAt(j);
7004                    if (proc.userId != tr.userId) {
7005                        continue;
7006                    }
7007                    if (!proc.pkgList.containsKey(pkg)) {
7008                        continue;
7009                    }
7010                    procs.add(proc);
7011                }
7012            }
7013
7014            // Kill the running processes.
7015            for (int i=0; i<procs.size(); i++) {
7016                ProcessRecord pr = procs.get(i);
7017                if (pr == mHomeProcess) {
7018                    // Don't kill the home process along with tasks from the same package.
7019                    continue;
7020                }
7021                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7022                    killUnneededProcessLocked(pr, "remove task");
7023                } else {
7024                    pr.waitingToKill = "remove task";
7025                }
7026            }
7027        }
7028    }
7029
7030    @Override
7031    public boolean removeTask(int taskId, int flags) {
7032        synchronized (this) {
7033            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7034                    "removeTask()");
7035            long ident = Binder.clearCallingIdentity();
7036            try {
7037                TaskRecord tr = recentTaskForIdLocked(taskId);
7038                if (tr != null) {
7039                    ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false);
7040                    if (r != null) {
7041                        cleanUpRemovedTaskLocked(tr, flags);
7042                        return true;
7043                    }
7044                    if (tr.mActivities.size() == 0) {
7045                        // Caller is just removing a recent task that is
7046                        // not actively running.  That is easy!
7047                        cleanUpRemovedTaskLocked(tr, flags);
7048                        return true;
7049                    }
7050                    Slog.w(TAG, "removeTask: task " + taskId
7051                            + " does not have activities to remove, "
7052                            + " but numActivities=" + tr.numActivities
7053                            + ": " + tr);
7054                }
7055            } finally {
7056                Binder.restoreCallingIdentity(ident);
7057            }
7058        }
7059        return false;
7060    }
7061
7062    /**
7063     * TODO: Add mController hook
7064     */
7065    @Override
7066    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7067        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7068                "moveTaskToFront()");
7069
7070        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7071        synchronized(this) {
7072            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7073                    Binder.getCallingUid(), "Task to front")) {
7074                ActivityOptions.abort(options);
7075                return;
7076            }
7077            final long origId = Binder.clearCallingIdentity();
7078            try {
7079                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7080                if (task == null) {
7081                    return;
7082                }
7083                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7084                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7085                    return;
7086                }
7087                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7088            } finally {
7089                Binder.restoreCallingIdentity(origId);
7090            }
7091            ActivityOptions.abort(options);
7092        }
7093    }
7094
7095    @Override
7096    public void moveTaskToBack(int taskId) {
7097        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7098                "moveTaskToBack()");
7099
7100        synchronized(this) {
7101            TaskRecord tr = recentTaskForIdLocked(taskId);
7102            if (tr != null) {
7103                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7104                ActivityStack stack = tr.stack;
7105                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7106                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7107                            Binder.getCallingUid(), "Task to back")) {
7108                        return;
7109                    }
7110                }
7111                final long origId = Binder.clearCallingIdentity();
7112                try {
7113                    stack.moveTaskToBackLocked(taskId, null);
7114                } finally {
7115                    Binder.restoreCallingIdentity(origId);
7116                }
7117            }
7118        }
7119    }
7120
7121    /**
7122     * Moves an activity, and all of the other activities within the same task, to the bottom
7123     * of the history stack.  The activity's order within the task is unchanged.
7124     *
7125     * @param token A reference to the activity we wish to move
7126     * @param nonRoot If false then this only works if the activity is the root
7127     *                of a task; if true it will work for any activity in a task.
7128     * @return Returns true if the move completed, false if not.
7129     */
7130    @Override
7131    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7132        enforceNotIsolatedCaller("moveActivityTaskToBack");
7133        synchronized(this) {
7134            final long origId = Binder.clearCallingIdentity();
7135            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7136            if (taskId >= 0) {
7137                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7138            }
7139            Binder.restoreCallingIdentity(origId);
7140        }
7141        return false;
7142    }
7143
7144    @Override
7145    public void moveTaskBackwards(int task) {
7146        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7147                "moveTaskBackwards()");
7148
7149        synchronized(this) {
7150            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7151                    Binder.getCallingUid(), "Task backwards")) {
7152                return;
7153            }
7154            final long origId = Binder.clearCallingIdentity();
7155            moveTaskBackwardsLocked(task);
7156            Binder.restoreCallingIdentity(origId);
7157        }
7158    }
7159
7160    private final void moveTaskBackwardsLocked(int task) {
7161        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7162    }
7163
7164    @Override
7165    public IBinder getHomeActivityToken() throws RemoteException {
7166        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7167                "getHomeActivityToken()");
7168        synchronized (this) {
7169            return mStackSupervisor.getHomeActivityToken();
7170        }
7171    }
7172
7173    @Override
7174    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7175            IActivityContainerCallback callback) throws RemoteException {
7176        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7177                "createActivityContainer()");
7178        synchronized (this) {
7179            if (parentActivityToken == null) {
7180                throw new IllegalArgumentException("parent token must not be null");
7181            }
7182            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7183            if (r == null) {
7184                return null;
7185            }
7186            return mStackSupervisor.createActivityContainer(r, callback);
7187        }
7188    }
7189
7190    @Override
7191    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7192        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7193                "deleteActivityContainer()");
7194        synchronized (this) {
7195            mStackSupervisor.deleteActivityContainer(container);
7196        }
7197    }
7198
7199    @Override
7200    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7201            throws RemoteException {
7202        synchronized (this) {
7203            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7204            if (stack != null) {
7205                return stack.mActivityContainer;
7206            }
7207            return null;
7208        }
7209    }
7210
7211    @Override
7212    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7213        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7214                "moveTaskToStack()");
7215        if (stackId == HOME_STACK_ID) {
7216            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7217                    new RuntimeException("here").fillInStackTrace());
7218        }
7219        synchronized (this) {
7220            long ident = Binder.clearCallingIdentity();
7221            try {
7222                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7223                        + stackId + " toTop=" + toTop);
7224                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7225            } finally {
7226                Binder.restoreCallingIdentity(ident);
7227            }
7228        }
7229    }
7230
7231    @Override
7232    public void resizeStack(int stackBoxId, Rect bounds) {
7233        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7234                "resizeStackBox()");
7235        long ident = Binder.clearCallingIdentity();
7236        try {
7237            mWindowManager.resizeStack(stackBoxId, bounds);
7238        } finally {
7239            Binder.restoreCallingIdentity(ident);
7240        }
7241    }
7242
7243    @Override
7244    public List<StackInfo> getAllStackInfos() {
7245        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7246                "getAllStackInfos()");
7247        long ident = Binder.clearCallingIdentity();
7248        try {
7249            synchronized (this) {
7250                return mStackSupervisor.getAllStackInfosLocked();
7251            }
7252        } finally {
7253            Binder.restoreCallingIdentity(ident);
7254        }
7255    }
7256
7257    @Override
7258    public StackInfo getStackInfo(int stackId) {
7259        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7260                "getStackInfo()");
7261        long ident = Binder.clearCallingIdentity();
7262        try {
7263            synchronized (this) {
7264                return mStackSupervisor.getStackInfoLocked(stackId);
7265            }
7266        } finally {
7267            Binder.restoreCallingIdentity(ident);
7268        }
7269    }
7270
7271    @Override
7272    public boolean isInHomeStack(int taskId) {
7273        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7274                "getStackInfo()");
7275        long ident = Binder.clearCallingIdentity();
7276        try {
7277            synchronized (this) {
7278                TaskRecord tr = recentTaskForIdLocked(taskId);
7279                if (tr != null) {
7280                    return tr.stack.isHomeStack();
7281                }
7282            }
7283        } finally {
7284            Binder.restoreCallingIdentity(ident);
7285        }
7286        return false;
7287    }
7288
7289    @Override
7290    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7291        synchronized(this) {
7292            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7293        }
7294    }
7295
7296    private boolean isLockTaskAuthorized(ComponentName name) {
7297//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7298//                "startLockTaskMode()");
7299//        DevicePolicyManager dpm = (DevicePolicyManager)
7300//                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7301//        return dpm != null && dpm.isLockTaskPermitted(name);
7302        return true;
7303    }
7304
7305    private void startLockTaskMode(TaskRecord task) {
7306        if (!isLockTaskAuthorized(task.intent.getComponent())) {
7307            return;
7308        }
7309        long ident = Binder.clearCallingIdentity();
7310        try {
7311            synchronized (this) {
7312                // Since we lost lock on task, make sure it is still there.
7313                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7314                if (task != null) {
7315                    mStackSupervisor.setLockTaskModeLocked(task);
7316                }
7317            }
7318        } finally {
7319            Binder.restoreCallingIdentity(ident);
7320        }
7321    }
7322
7323    @Override
7324    public void startLockTaskMode(int taskId) {
7325        long ident = Binder.clearCallingIdentity();
7326        try {
7327            final TaskRecord task;
7328            synchronized (this) {
7329                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7330            }
7331            if (task != null) {
7332                startLockTaskMode(task);
7333            }
7334        } finally {
7335            Binder.restoreCallingIdentity(ident);
7336        }
7337    }
7338
7339    @Override
7340    public void startLockTaskMode(IBinder token) {
7341        long ident = Binder.clearCallingIdentity();
7342        try {
7343            final TaskRecord task;
7344            synchronized (this) {
7345                final ActivityRecord r = ActivityRecord.forToken(token);
7346                if (r == null) {
7347                    return;
7348                }
7349                task = r.task;
7350            }
7351            if (task != null) {
7352                startLockTaskMode(task);
7353            }
7354        } finally {
7355            Binder.restoreCallingIdentity(ident);
7356        }
7357    }
7358
7359    @Override
7360    public void stopLockTaskMode() {
7361//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7362//                "stopLockTaskMode()");
7363        synchronized (this) {
7364            mStackSupervisor.setLockTaskModeLocked(null);
7365        }
7366    }
7367
7368    @Override
7369    public boolean isInLockTaskMode() {
7370        synchronized (this) {
7371            return mStackSupervisor.isInLockTaskMode();
7372        }
7373    }
7374
7375    // =========================================================
7376    // THUMBNAILS
7377    // =========================================================
7378
7379    public void reportThumbnail(IBinder token,
7380            Bitmap thumbnail, CharSequence description) {
7381        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
7382        final long origId = Binder.clearCallingIdentity();
7383        sendPendingThumbnail(null, token, thumbnail, description, true);
7384        Binder.restoreCallingIdentity(origId);
7385    }
7386
7387    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
7388            Bitmap thumbnail, CharSequence description, boolean always) {
7389        TaskRecord task;
7390        ArrayList<PendingThumbnailsRecord> receivers = null;
7391
7392        //System.out.println("Send pending thumbnail: " + r);
7393
7394        synchronized(this) {
7395            if (r == null) {
7396                r = ActivityRecord.isInStackLocked(token);
7397                if (r == null) {
7398                    return;
7399                }
7400            }
7401            if (thumbnail == null && r.thumbHolder != null) {
7402                thumbnail = r.thumbHolder.lastThumbnail;
7403                description = r.thumbHolder.lastDescription;
7404            }
7405            if (thumbnail == null && !always) {
7406                // If there is no thumbnail, and this entry is not actually
7407                // going away, then abort for now and pick up the next
7408                // thumbnail we get.
7409                return;
7410            }
7411            task = r.task;
7412
7413            int N = mPendingThumbnails.size();
7414            int i=0;
7415            while (i<N) {
7416                PendingThumbnailsRecord pr = mPendingThumbnails.get(i);
7417                //System.out.println("Looking in " + pr.pendingRecords);
7418                if (pr.pendingRecords.remove(r)) {
7419                    if (receivers == null) {
7420                        receivers = new ArrayList<PendingThumbnailsRecord>();
7421                    }
7422                    receivers.add(pr);
7423                    if (pr.pendingRecords.size() == 0) {
7424                        pr.finished = true;
7425                        mPendingThumbnails.remove(i);
7426                        N--;
7427                        continue;
7428                    }
7429                }
7430                i++;
7431            }
7432        }
7433
7434        if (receivers != null) {
7435            final int N = receivers.size();
7436            for (int i=0; i<N; i++) {
7437                try {
7438                    PendingThumbnailsRecord pr = receivers.get(i);
7439                    pr.receiver.newThumbnail(
7440                        task != null ? task.taskId : -1, thumbnail, description);
7441                    if (pr.finished) {
7442                        pr.receiver.finished();
7443                    }
7444                } catch (Exception e) {
7445                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
7446                }
7447            }
7448        }
7449    }
7450
7451    // =========================================================
7452    // CONTENT PROVIDERS
7453    // =========================================================
7454
7455    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7456        List<ProviderInfo> providers = null;
7457        try {
7458            providers = AppGlobals.getPackageManager().
7459                queryContentProviders(app.processName, app.uid,
7460                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7461        } catch (RemoteException ex) {
7462        }
7463        if (DEBUG_MU)
7464            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7465        int userId = app.userId;
7466        if (providers != null) {
7467            int N = providers.size();
7468            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7469            for (int i=0; i<N; i++) {
7470                ProviderInfo cpi =
7471                    (ProviderInfo)providers.get(i);
7472                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7473                        cpi.name, cpi.flags);
7474                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7475                    // This is a singleton provider, but a user besides the
7476                    // default user is asking to initialize a process it runs
7477                    // in...  well, no, it doesn't actually run in this process,
7478                    // it runs in the process of the default user.  Get rid of it.
7479                    providers.remove(i);
7480                    N--;
7481                    i--;
7482                    continue;
7483                }
7484
7485                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7486                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7487                if (cpr == null) {
7488                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7489                    mProviderMap.putProviderByClass(comp, cpr);
7490                }
7491                if (DEBUG_MU)
7492                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7493                app.pubProviders.put(cpi.name, cpr);
7494                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7495                    // Don't add this if it is a platform component that is marked
7496                    // to run in multiple processes, because this is actually
7497                    // part of the framework so doesn't make sense to track as a
7498                    // separate apk in the process.
7499                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7500                }
7501                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7502            }
7503        }
7504        return providers;
7505    }
7506
7507    /**
7508     * Check if {@link ProcessRecord} has a possible chance at accessing the
7509     * given {@link ProviderInfo}. Final permission checking is always done
7510     * in {@link ContentProvider}.
7511     */
7512    private final String checkContentProviderPermissionLocked(
7513            ProviderInfo cpi, ProcessRecord r) {
7514        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7515        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7516        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7517                cpi.applicationInfo.uid, cpi.exported)
7518                == PackageManager.PERMISSION_GRANTED) {
7519            return null;
7520        }
7521        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7522                cpi.applicationInfo.uid, cpi.exported)
7523                == PackageManager.PERMISSION_GRANTED) {
7524            return null;
7525        }
7526
7527        PathPermission[] pps = cpi.pathPermissions;
7528        if (pps != null) {
7529            int i = pps.length;
7530            while (i > 0) {
7531                i--;
7532                PathPermission pp = pps[i];
7533                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7534                        cpi.applicationInfo.uid, cpi.exported)
7535                        == PackageManager.PERMISSION_GRANTED) {
7536                    return null;
7537                }
7538                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7539                        cpi.applicationInfo.uid, cpi.exported)
7540                        == PackageManager.PERMISSION_GRANTED) {
7541                    return null;
7542                }
7543            }
7544        }
7545
7546        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7547        if (perms != null) {
7548            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
7549                if (uri.getKey().getAuthority().equals(cpi.authority)) {
7550                    return null;
7551                }
7552            }
7553        }
7554
7555        String msg;
7556        if (!cpi.exported) {
7557            msg = "Permission Denial: opening provider " + cpi.name
7558                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7559                    + ", uid=" + callingUid + ") that is not exported from uid "
7560                    + cpi.applicationInfo.uid;
7561        } else {
7562            msg = "Permission Denial: opening provider " + cpi.name
7563                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7564                    + ", uid=" + callingUid + ") requires "
7565                    + cpi.readPermission + " or " + cpi.writePermission;
7566        }
7567        Slog.w(TAG, msg);
7568        return msg;
7569    }
7570
7571    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7572            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7573        if (r != null) {
7574            for (int i=0; i<r.conProviders.size(); i++) {
7575                ContentProviderConnection conn = r.conProviders.get(i);
7576                if (conn.provider == cpr) {
7577                    if (DEBUG_PROVIDER) Slog.v(TAG,
7578                            "Adding provider requested by "
7579                            + r.processName + " from process "
7580                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7581                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7582                    if (stable) {
7583                        conn.stableCount++;
7584                        conn.numStableIncs++;
7585                    } else {
7586                        conn.unstableCount++;
7587                        conn.numUnstableIncs++;
7588                    }
7589                    return conn;
7590                }
7591            }
7592            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7593            if (stable) {
7594                conn.stableCount = 1;
7595                conn.numStableIncs = 1;
7596            } else {
7597                conn.unstableCount = 1;
7598                conn.numUnstableIncs = 1;
7599            }
7600            cpr.connections.add(conn);
7601            r.conProviders.add(conn);
7602            return conn;
7603        }
7604        cpr.addExternalProcessHandleLocked(externalProcessToken);
7605        return null;
7606    }
7607
7608    boolean decProviderCountLocked(ContentProviderConnection conn,
7609            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7610        if (conn != null) {
7611            cpr = conn.provider;
7612            if (DEBUG_PROVIDER) Slog.v(TAG,
7613                    "Removing provider requested by "
7614                    + conn.client.processName + " from process "
7615                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7616                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7617            if (stable) {
7618                conn.stableCount--;
7619            } else {
7620                conn.unstableCount--;
7621            }
7622            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7623                cpr.connections.remove(conn);
7624                conn.client.conProviders.remove(conn);
7625                return true;
7626            }
7627            return false;
7628        }
7629        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7630        return false;
7631    }
7632
7633    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7634            String name, IBinder token, boolean stable, int userId) {
7635        ContentProviderRecord cpr;
7636        ContentProviderConnection conn = null;
7637        ProviderInfo cpi = null;
7638
7639        synchronized(this) {
7640            ProcessRecord r = null;
7641            if (caller != null) {
7642                r = getRecordForAppLocked(caller);
7643                if (r == null) {
7644                    throw new SecurityException(
7645                            "Unable to find app for caller " + caller
7646                          + " (pid=" + Binder.getCallingPid()
7647                          + ") when getting content provider " + name);
7648                }
7649            }
7650
7651            // First check if this content provider has been published...
7652            cpr = mProviderMap.getProviderByName(name, userId);
7653            boolean providerRunning = cpr != null;
7654            if (providerRunning) {
7655                cpi = cpr.info;
7656                String msg;
7657                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7658                    throw new SecurityException(msg);
7659                }
7660
7661                if (r != null && cpr.canRunHere(r)) {
7662                    // This provider has been published or is in the process
7663                    // of being published...  but it is also allowed to run
7664                    // in the caller's process, so don't make a connection
7665                    // and just let the caller instantiate its own instance.
7666                    ContentProviderHolder holder = cpr.newHolder(null);
7667                    // don't give caller the provider object, it needs
7668                    // to make its own.
7669                    holder.provider = null;
7670                    return holder;
7671                }
7672
7673                final long origId = Binder.clearCallingIdentity();
7674
7675                // In this case the provider instance already exists, so we can
7676                // return it right away.
7677                conn = incProviderCountLocked(r, cpr, token, stable);
7678                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7679                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7680                        // If this is a perceptible app accessing the provider,
7681                        // make sure to count it as being accessed and thus
7682                        // back up on the LRU list.  This is good because
7683                        // content providers are often expensive to start.
7684                        updateLruProcessLocked(cpr.proc, false, null);
7685                    }
7686                }
7687
7688                if (cpr.proc != null) {
7689                    if (false) {
7690                        if (cpr.name.flattenToShortString().equals(
7691                                "com.android.providers.calendar/.CalendarProvider2")) {
7692                            Slog.v(TAG, "****************** KILLING "
7693                                + cpr.name.flattenToShortString());
7694                            Process.killProcess(cpr.proc.pid);
7695                        }
7696                    }
7697                    boolean success = updateOomAdjLocked(cpr.proc);
7698                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7699                    // NOTE: there is still a race here where a signal could be
7700                    // pending on the process even though we managed to update its
7701                    // adj level.  Not sure what to do about this, but at least
7702                    // the race is now smaller.
7703                    if (!success) {
7704                        // Uh oh...  it looks like the provider's process
7705                        // has been killed on us.  We need to wait for a new
7706                        // process to be started, and make sure its death
7707                        // doesn't kill our process.
7708                        Slog.i(TAG,
7709                                "Existing provider " + cpr.name.flattenToShortString()
7710                                + " is crashing; detaching " + r);
7711                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7712                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7713                        if (!lastRef) {
7714                            // This wasn't the last ref our process had on
7715                            // the provider...  we have now been killed, bail.
7716                            return null;
7717                        }
7718                        providerRunning = false;
7719                        conn = null;
7720                    }
7721                }
7722
7723                Binder.restoreCallingIdentity(origId);
7724            }
7725
7726            boolean singleton;
7727            if (!providerRunning) {
7728                try {
7729                    cpi = AppGlobals.getPackageManager().
7730                        resolveContentProvider(name,
7731                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7732                } catch (RemoteException ex) {
7733                }
7734                if (cpi == null) {
7735                    return null;
7736                }
7737                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7738                        cpi.name, cpi.flags);
7739                if (singleton) {
7740                    userId = 0;
7741                }
7742                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7743
7744                String msg;
7745                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7746                    throw new SecurityException(msg);
7747                }
7748
7749                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
7750                        && !cpi.processName.equals("system")) {
7751                    // If this content provider does not run in the system
7752                    // process, and the system is not yet ready to run other
7753                    // processes, then fail fast instead of hanging.
7754                    throw new IllegalArgumentException(
7755                            "Attempt to launch content provider before system ready");
7756                }
7757
7758                // Make sure that the user who owns this provider is started.  If not,
7759                // we don't want to allow it to run.
7760                if (mStartedUsers.get(userId) == null) {
7761                    Slog.w(TAG, "Unable to launch app "
7762                            + cpi.applicationInfo.packageName + "/"
7763                            + cpi.applicationInfo.uid + " for provider "
7764                            + name + ": user " + userId + " is stopped");
7765                    return null;
7766                }
7767
7768                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7769                cpr = mProviderMap.getProviderByClass(comp, userId);
7770                final boolean firstClass = cpr == null;
7771                if (firstClass) {
7772                    try {
7773                        ApplicationInfo ai =
7774                            AppGlobals.getPackageManager().
7775                                getApplicationInfo(
7776                                        cpi.applicationInfo.packageName,
7777                                        STOCK_PM_FLAGS, userId);
7778                        if (ai == null) {
7779                            Slog.w(TAG, "No package info for content provider "
7780                                    + cpi.name);
7781                            return null;
7782                        }
7783                        ai = getAppInfoForUser(ai, userId);
7784                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
7785                    } catch (RemoteException ex) {
7786                        // pm is in same process, this will never happen.
7787                    }
7788                }
7789
7790                if (r != null && cpr.canRunHere(r)) {
7791                    // If this is a multiprocess provider, then just return its
7792                    // info and allow the caller to instantiate it.  Only do
7793                    // this if the provider is the same user as the caller's
7794                    // process, or can run as root (so can be in any process).
7795                    return cpr.newHolder(null);
7796                }
7797
7798                if (DEBUG_PROVIDER) {
7799                    RuntimeException e = new RuntimeException("here");
7800                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
7801                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
7802                }
7803
7804                // This is single process, and our app is now connecting to it.
7805                // See if we are already in the process of launching this
7806                // provider.
7807                final int N = mLaunchingProviders.size();
7808                int i;
7809                for (i=0; i<N; i++) {
7810                    if (mLaunchingProviders.get(i) == cpr) {
7811                        break;
7812                    }
7813                }
7814
7815                // If the provider is not already being launched, then get it
7816                // started.
7817                if (i >= N) {
7818                    final long origId = Binder.clearCallingIdentity();
7819
7820                    try {
7821                        // Content provider is now in use, its package can't be stopped.
7822                        try {
7823                            AppGlobals.getPackageManager().setPackageStoppedState(
7824                                    cpr.appInfo.packageName, false, userId);
7825                        } catch (RemoteException e) {
7826                        } catch (IllegalArgumentException e) {
7827                            Slog.w(TAG, "Failed trying to unstop package "
7828                                    + cpr.appInfo.packageName + ": " + e);
7829                        }
7830
7831                        // Use existing process if already started
7832                        ProcessRecord proc = getProcessRecordLocked(
7833                                cpi.processName, cpr.appInfo.uid, false);
7834                        if (proc != null && proc.thread != null) {
7835                            if (DEBUG_PROVIDER) {
7836                                Slog.d(TAG, "Installing in existing process " + proc);
7837                            }
7838                            proc.pubProviders.put(cpi.name, cpr);
7839                            try {
7840                                proc.thread.scheduleInstallProvider(cpi);
7841                            } catch (RemoteException e) {
7842                            }
7843                        } else {
7844                            proc = startProcessLocked(cpi.processName,
7845                                    cpr.appInfo, false, 0, "content provider",
7846                                    new ComponentName(cpi.applicationInfo.packageName,
7847                                            cpi.name), false, false, false);
7848                            if (proc == null) {
7849                                Slog.w(TAG, "Unable to launch app "
7850                                        + cpi.applicationInfo.packageName + "/"
7851                                        + cpi.applicationInfo.uid + " for provider "
7852                                        + name + ": process is bad");
7853                                return null;
7854                            }
7855                        }
7856                        cpr.launchingApp = proc;
7857                        mLaunchingProviders.add(cpr);
7858                    } finally {
7859                        Binder.restoreCallingIdentity(origId);
7860                    }
7861                }
7862
7863                // Make sure the provider is published (the same provider class
7864                // may be published under multiple names).
7865                if (firstClass) {
7866                    mProviderMap.putProviderByClass(comp, cpr);
7867                }
7868
7869                mProviderMap.putProviderByName(name, cpr);
7870                conn = incProviderCountLocked(r, cpr, token, stable);
7871                if (conn != null) {
7872                    conn.waiting = true;
7873                }
7874            }
7875        }
7876
7877        // Wait for the provider to be published...
7878        synchronized (cpr) {
7879            while (cpr.provider == null) {
7880                if (cpr.launchingApp == null) {
7881                    Slog.w(TAG, "Unable to launch app "
7882                            + cpi.applicationInfo.packageName + "/"
7883                            + cpi.applicationInfo.uid + " for provider "
7884                            + name + ": launching app became null");
7885                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
7886                            UserHandle.getUserId(cpi.applicationInfo.uid),
7887                            cpi.applicationInfo.packageName,
7888                            cpi.applicationInfo.uid, name);
7889                    return null;
7890                }
7891                try {
7892                    if (DEBUG_MU) {
7893                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
7894                                + cpr.launchingApp);
7895                    }
7896                    if (conn != null) {
7897                        conn.waiting = true;
7898                    }
7899                    cpr.wait();
7900                } catch (InterruptedException ex) {
7901                } finally {
7902                    if (conn != null) {
7903                        conn.waiting = false;
7904                    }
7905                }
7906            }
7907        }
7908        return cpr != null ? cpr.newHolder(conn) : null;
7909    }
7910
7911    public final ContentProviderHolder getContentProvider(
7912            IApplicationThread caller, String name, int userId, boolean stable) {
7913        enforceNotIsolatedCaller("getContentProvider");
7914        if (caller == null) {
7915            String msg = "null IApplicationThread when getting content provider "
7916                    + name;
7917            Slog.w(TAG, msg);
7918            throw new SecurityException(msg);
7919        }
7920
7921        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7922                false, true, "getContentProvider", null);
7923        return getContentProviderImpl(caller, name, null, stable, userId);
7924    }
7925
7926    public ContentProviderHolder getContentProviderExternal(
7927            String name, int userId, IBinder token) {
7928        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7929            "Do not have permission in call getContentProviderExternal()");
7930        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7931                false, true, "getContentProvider", null);
7932        return getContentProviderExternalUnchecked(name, token, userId);
7933    }
7934
7935    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
7936            IBinder token, int userId) {
7937        return getContentProviderImpl(null, name, token, true, userId);
7938    }
7939
7940    /**
7941     * Drop a content provider from a ProcessRecord's bookkeeping
7942     */
7943    public void removeContentProvider(IBinder connection, boolean stable) {
7944        enforceNotIsolatedCaller("removeContentProvider");
7945        long ident = Binder.clearCallingIdentity();
7946        try {
7947            synchronized (this) {
7948                ContentProviderConnection conn;
7949                try {
7950                    conn = (ContentProviderConnection)connection;
7951                } catch (ClassCastException e) {
7952                    String msg ="removeContentProvider: " + connection
7953                            + " not a ContentProviderConnection";
7954                    Slog.w(TAG, msg);
7955                    throw new IllegalArgumentException(msg);
7956                }
7957                if (conn == null) {
7958                    throw new NullPointerException("connection is null");
7959                }
7960                if (decProviderCountLocked(conn, null, null, stable)) {
7961                    updateOomAdjLocked();
7962                }
7963            }
7964        } finally {
7965            Binder.restoreCallingIdentity(ident);
7966        }
7967    }
7968
7969    public void removeContentProviderExternal(String name, IBinder token) {
7970        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7971            "Do not have permission in call removeContentProviderExternal()");
7972        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
7973    }
7974
7975    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
7976        synchronized (this) {
7977            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
7978            if(cpr == null) {
7979                //remove from mProvidersByClass
7980                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
7981                return;
7982            }
7983
7984            //update content provider record entry info
7985            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
7986            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
7987            if (localCpr.hasExternalProcessHandles()) {
7988                if (localCpr.removeExternalProcessHandleLocked(token)) {
7989                    updateOomAdjLocked();
7990                } else {
7991                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
7992                            + " with no external reference for token: "
7993                            + token + ".");
7994                }
7995            } else {
7996                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
7997                        + " with no external references.");
7998            }
7999        }
8000    }
8001
8002    public final void publishContentProviders(IApplicationThread caller,
8003            List<ContentProviderHolder> providers) {
8004        if (providers == null) {
8005            return;
8006        }
8007
8008        enforceNotIsolatedCaller("publishContentProviders");
8009        synchronized (this) {
8010            final ProcessRecord r = getRecordForAppLocked(caller);
8011            if (DEBUG_MU)
8012                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8013            if (r == null) {
8014                throw new SecurityException(
8015                        "Unable to find app for caller " + caller
8016                      + " (pid=" + Binder.getCallingPid()
8017                      + ") when publishing content providers");
8018            }
8019
8020            final long origId = Binder.clearCallingIdentity();
8021
8022            final int N = providers.size();
8023            for (int i=0; i<N; i++) {
8024                ContentProviderHolder src = providers.get(i);
8025                if (src == null || src.info == null || src.provider == null) {
8026                    continue;
8027                }
8028                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8029                if (DEBUG_MU)
8030                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8031                if (dst != null) {
8032                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8033                    mProviderMap.putProviderByClass(comp, dst);
8034                    String names[] = dst.info.authority.split(";");
8035                    for (int j = 0; j < names.length; j++) {
8036                        mProviderMap.putProviderByName(names[j], dst);
8037                    }
8038
8039                    int NL = mLaunchingProviders.size();
8040                    int j;
8041                    for (j=0; j<NL; j++) {
8042                        if (mLaunchingProviders.get(j) == dst) {
8043                            mLaunchingProviders.remove(j);
8044                            j--;
8045                            NL--;
8046                        }
8047                    }
8048                    synchronized (dst) {
8049                        dst.provider = src.provider;
8050                        dst.proc = r;
8051                        dst.notifyAll();
8052                    }
8053                    updateOomAdjLocked(r);
8054                }
8055            }
8056
8057            Binder.restoreCallingIdentity(origId);
8058        }
8059    }
8060
8061    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8062        ContentProviderConnection conn;
8063        try {
8064            conn = (ContentProviderConnection)connection;
8065        } catch (ClassCastException e) {
8066            String msg ="refContentProvider: " + connection
8067                    + " not a ContentProviderConnection";
8068            Slog.w(TAG, msg);
8069            throw new IllegalArgumentException(msg);
8070        }
8071        if (conn == null) {
8072            throw new NullPointerException("connection is null");
8073        }
8074
8075        synchronized (this) {
8076            if (stable > 0) {
8077                conn.numStableIncs += stable;
8078            }
8079            stable = conn.stableCount + stable;
8080            if (stable < 0) {
8081                throw new IllegalStateException("stableCount < 0: " + stable);
8082            }
8083
8084            if (unstable > 0) {
8085                conn.numUnstableIncs += unstable;
8086            }
8087            unstable = conn.unstableCount + unstable;
8088            if (unstable < 0) {
8089                throw new IllegalStateException("unstableCount < 0: " + unstable);
8090            }
8091
8092            if ((stable+unstable) <= 0) {
8093                throw new IllegalStateException("ref counts can't go to zero here: stable="
8094                        + stable + " unstable=" + unstable);
8095            }
8096            conn.stableCount = stable;
8097            conn.unstableCount = unstable;
8098            return !conn.dead;
8099        }
8100    }
8101
8102    public void unstableProviderDied(IBinder connection) {
8103        ContentProviderConnection conn;
8104        try {
8105            conn = (ContentProviderConnection)connection;
8106        } catch (ClassCastException e) {
8107            String msg ="refContentProvider: " + connection
8108                    + " not a ContentProviderConnection";
8109            Slog.w(TAG, msg);
8110            throw new IllegalArgumentException(msg);
8111        }
8112        if (conn == null) {
8113            throw new NullPointerException("connection is null");
8114        }
8115
8116        // Safely retrieve the content provider associated with the connection.
8117        IContentProvider provider;
8118        synchronized (this) {
8119            provider = conn.provider.provider;
8120        }
8121
8122        if (provider == null) {
8123            // Um, yeah, we're way ahead of you.
8124            return;
8125        }
8126
8127        // Make sure the caller is being honest with us.
8128        if (provider.asBinder().pingBinder()) {
8129            // Er, no, still looks good to us.
8130            synchronized (this) {
8131                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8132                        + " says " + conn + " died, but we don't agree");
8133                return;
8134            }
8135        }
8136
8137        // Well look at that!  It's dead!
8138        synchronized (this) {
8139            if (conn.provider.provider != provider) {
8140                // But something changed...  good enough.
8141                return;
8142            }
8143
8144            ProcessRecord proc = conn.provider.proc;
8145            if (proc == null || proc.thread == null) {
8146                // Seems like the process is already cleaned up.
8147                return;
8148            }
8149
8150            // As far as we're concerned, this is just like receiving a
8151            // death notification...  just a bit prematurely.
8152            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8153                    + ") early provider death");
8154            final long ident = Binder.clearCallingIdentity();
8155            try {
8156                appDiedLocked(proc, proc.pid, proc.thread);
8157            } finally {
8158                Binder.restoreCallingIdentity(ident);
8159            }
8160        }
8161    }
8162
8163    @Override
8164    public void appNotRespondingViaProvider(IBinder connection) {
8165        enforceCallingPermission(
8166                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8167
8168        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8169        if (conn == null) {
8170            Slog.w(TAG, "ContentProviderConnection is null");
8171            return;
8172        }
8173
8174        final ProcessRecord host = conn.provider.proc;
8175        if (host == null) {
8176            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8177            return;
8178        }
8179
8180        final long token = Binder.clearCallingIdentity();
8181        try {
8182            appNotResponding(host, null, null, false, "ContentProvider not responding");
8183        } finally {
8184            Binder.restoreCallingIdentity(token);
8185        }
8186    }
8187
8188    public final void installSystemProviders() {
8189        List<ProviderInfo> providers;
8190        synchronized (this) {
8191            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8192            providers = generateApplicationProvidersLocked(app);
8193            if (providers != null) {
8194                for (int i=providers.size()-1; i>=0; i--) {
8195                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8196                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8197                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8198                                + ": not system .apk");
8199                        providers.remove(i);
8200                    }
8201                }
8202            }
8203        }
8204        if (providers != null) {
8205            mSystemThread.installSystemProviders(providers);
8206        }
8207
8208        mCoreSettingsObserver = new CoreSettingsObserver(this);
8209
8210        mUsageStatsService.monitorPackages();
8211    }
8212
8213    /**
8214     * Allows app to retrieve the MIME type of a URI without having permission
8215     * to access its content provider.
8216     *
8217     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8218     *
8219     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8220     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8221     */
8222    public String getProviderMimeType(Uri uri, int userId) {
8223        enforceNotIsolatedCaller("getProviderMimeType");
8224        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8225                userId, false, true, "getProviderMimeType", null);
8226        final String name = uri.getAuthority();
8227        final long ident = Binder.clearCallingIdentity();
8228        ContentProviderHolder holder = null;
8229
8230        try {
8231            holder = getContentProviderExternalUnchecked(name, null, userId);
8232            if (holder != null) {
8233                return holder.provider.getType(uri);
8234            }
8235        } catch (RemoteException e) {
8236            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8237            return null;
8238        } finally {
8239            if (holder != null) {
8240                removeContentProviderExternalUnchecked(name, null, userId);
8241            }
8242            Binder.restoreCallingIdentity(ident);
8243        }
8244
8245        return null;
8246    }
8247
8248    // =========================================================
8249    // GLOBAL MANAGEMENT
8250    // =========================================================
8251
8252    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8253            boolean isolated) {
8254        String proc = customProcess != null ? customProcess : info.processName;
8255        BatteryStatsImpl.Uid.Proc ps = null;
8256        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8257        int uid = info.uid;
8258        if (isolated) {
8259            int userId = UserHandle.getUserId(uid);
8260            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8261            while (true) {
8262                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8263                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8264                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8265                }
8266                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8267                mNextIsolatedProcessUid++;
8268                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8269                    // No process for this uid, use it.
8270                    break;
8271                }
8272                stepsLeft--;
8273                if (stepsLeft <= 0) {
8274                    return null;
8275                }
8276            }
8277        }
8278        return new ProcessRecord(stats, info, proc, uid);
8279    }
8280
8281    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8282        ProcessRecord app;
8283        if (!isolated) {
8284            app = getProcessRecordLocked(info.processName, info.uid, true);
8285        } else {
8286            app = null;
8287        }
8288
8289        if (app == null) {
8290            app = newProcessRecordLocked(info, null, isolated);
8291            mProcessNames.put(info.processName, app.uid, app);
8292            if (isolated) {
8293                mIsolatedProcesses.put(app.uid, app);
8294            }
8295            updateLruProcessLocked(app, false, null);
8296            updateOomAdjLocked();
8297        }
8298
8299        // This package really, really can not be stopped.
8300        try {
8301            AppGlobals.getPackageManager().setPackageStoppedState(
8302                    info.packageName, false, UserHandle.getUserId(app.uid));
8303        } catch (RemoteException e) {
8304        } catch (IllegalArgumentException e) {
8305            Slog.w(TAG, "Failed trying to unstop package "
8306                    + info.packageName + ": " + e);
8307        }
8308
8309        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8310                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8311            app.persistent = true;
8312            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8313        }
8314        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8315            mPersistentStartingProcesses.add(app);
8316            startProcessLocked(app, "added application", app.processName);
8317        }
8318
8319        return app;
8320    }
8321
8322    public void unhandledBack() {
8323        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8324                "unhandledBack()");
8325
8326        synchronized(this) {
8327            final long origId = Binder.clearCallingIdentity();
8328            try {
8329                getFocusedStack().unhandledBackLocked();
8330            } finally {
8331                Binder.restoreCallingIdentity(origId);
8332            }
8333        }
8334    }
8335
8336    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8337        enforceNotIsolatedCaller("openContentUri");
8338        final int userId = UserHandle.getCallingUserId();
8339        String name = uri.getAuthority();
8340        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8341        ParcelFileDescriptor pfd = null;
8342        if (cph != null) {
8343            // We record the binder invoker's uid in thread-local storage before
8344            // going to the content provider to open the file.  Later, in the code
8345            // that handles all permissions checks, we look for this uid and use
8346            // that rather than the Activity Manager's own uid.  The effect is that
8347            // we do the check against the caller's permissions even though it looks
8348            // to the content provider like the Activity Manager itself is making
8349            // the request.
8350            sCallerIdentity.set(new Identity(
8351                    Binder.getCallingPid(), Binder.getCallingUid()));
8352            try {
8353                pfd = cph.provider.openFile(null, uri, "r", null);
8354            } catch (FileNotFoundException e) {
8355                // do nothing; pfd will be returned null
8356            } finally {
8357                // Ensure that whatever happens, we clean up the identity state
8358                sCallerIdentity.remove();
8359            }
8360
8361            // We've got the fd now, so we're done with the provider.
8362            removeContentProviderExternalUnchecked(name, null, userId);
8363        } else {
8364            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8365        }
8366        return pfd;
8367    }
8368
8369    // Actually is sleeping or shutting down or whatever else in the future
8370    // is an inactive state.
8371    public boolean isSleepingOrShuttingDown() {
8372        return mSleeping || mShuttingDown;
8373    }
8374
8375    public void goingToSleep() {
8376        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8377                != PackageManager.PERMISSION_GRANTED) {
8378            throw new SecurityException("Requires permission "
8379                    + android.Manifest.permission.DEVICE_POWER);
8380        }
8381
8382        synchronized(this) {
8383            mWentToSleep = true;
8384            updateEventDispatchingLocked();
8385
8386            if (!mSleeping) {
8387                mSleeping = true;
8388                mStackSupervisor.goingToSleepLocked();
8389
8390                // Initialize the wake times of all processes.
8391                checkExcessivePowerUsageLocked(false);
8392                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8393                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8394                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8395            }
8396        }
8397    }
8398
8399    @Override
8400    public boolean shutdown(int timeout) {
8401        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8402                != PackageManager.PERMISSION_GRANTED) {
8403            throw new SecurityException("Requires permission "
8404                    + android.Manifest.permission.SHUTDOWN);
8405        }
8406
8407        boolean timedout = false;
8408
8409        synchronized(this) {
8410            mShuttingDown = true;
8411            updateEventDispatchingLocked();
8412            timedout = mStackSupervisor.shutdownLocked(timeout);
8413        }
8414
8415        mAppOpsService.shutdown();
8416        mUsageStatsService.shutdown();
8417        mBatteryStatsService.shutdown();
8418        synchronized (this) {
8419            mProcessStats.shutdownLocked();
8420        }
8421
8422        return timedout;
8423    }
8424
8425    public final void activitySlept(IBinder token) {
8426        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8427
8428        final long origId = Binder.clearCallingIdentity();
8429
8430        synchronized (this) {
8431            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8432            if (r != null) {
8433                mStackSupervisor.activitySleptLocked(r);
8434            }
8435        }
8436
8437        Binder.restoreCallingIdentity(origId);
8438    }
8439
8440    void logLockScreen(String msg) {
8441        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8442                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8443                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8444                mStackSupervisor.mDismissKeyguardOnNextActivity);
8445    }
8446
8447    private void comeOutOfSleepIfNeededLocked() {
8448        if (!mWentToSleep && !mLockScreenShown) {
8449            if (mSleeping) {
8450                mSleeping = false;
8451                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8452            }
8453        }
8454    }
8455
8456    public void wakingUp() {
8457        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8458                != PackageManager.PERMISSION_GRANTED) {
8459            throw new SecurityException("Requires permission "
8460                    + android.Manifest.permission.DEVICE_POWER);
8461        }
8462
8463        synchronized(this) {
8464            mWentToSleep = false;
8465            updateEventDispatchingLocked();
8466            comeOutOfSleepIfNeededLocked();
8467        }
8468    }
8469
8470    private void updateEventDispatchingLocked() {
8471        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8472    }
8473
8474    public void setLockScreenShown(boolean shown) {
8475        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8476                != PackageManager.PERMISSION_GRANTED) {
8477            throw new SecurityException("Requires permission "
8478                    + android.Manifest.permission.DEVICE_POWER);
8479        }
8480
8481        synchronized(this) {
8482            long ident = Binder.clearCallingIdentity();
8483            try {
8484                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8485                mLockScreenShown = shown;
8486                comeOutOfSleepIfNeededLocked();
8487            } finally {
8488                Binder.restoreCallingIdentity(ident);
8489            }
8490        }
8491    }
8492
8493    public void stopAppSwitches() {
8494        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8495                != PackageManager.PERMISSION_GRANTED) {
8496            throw new SecurityException("Requires permission "
8497                    + android.Manifest.permission.STOP_APP_SWITCHES);
8498        }
8499
8500        synchronized(this) {
8501            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8502                    + APP_SWITCH_DELAY_TIME;
8503            mDidAppSwitch = false;
8504            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8505            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8506            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8507        }
8508    }
8509
8510    public void resumeAppSwitches() {
8511        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8512                != PackageManager.PERMISSION_GRANTED) {
8513            throw new SecurityException("Requires permission "
8514                    + android.Manifest.permission.STOP_APP_SWITCHES);
8515        }
8516
8517        synchronized(this) {
8518            // Note that we don't execute any pending app switches... we will
8519            // let those wait until either the timeout, or the next start
8520            // activity request.
8521            mAppSwitchesAllowedTime = 0;
8522        }
8523    }
8524
8525    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8526            String name) {
8527        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8528            return true;
8529        }
8530
8531        final int perm = checkComponentPermission(
8532                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8533                callingUid, -1, true);
8534        if (perm == PackageManager.PERMISSION_GRANTED) {
8535            return true;
8536        }
8537
8538        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8539        return false;
8540    }
8541
8542    public void setDebugApp(String packageName, boolean waitForDebugger,
8543            boolean persistent) {
8544        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8545                "setDebugApp()");
8546
8547        long ident = Binder.clearCallingIdentity();
8548        try {
8549            // Note that this is not really thread safe if there are multiple
8550            // callers into it at the same time, but that's not a situation we
8551            // care about.
8552            if (persistent) {
8553                final ContentResolver resolver = mContext.getContentResolver();
8554                Settings.Global.putString(
8555                    resolver, Settings.Global.DEBUG_APP,
8556                    packageName);
8557                Settings.Global.putInt(
8558                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8559                    waitForDebugger ? 1 : 0);
8560            }
8561
8562            synchronized (this) {
8563                if (!persistent) {
8564                    mOrigDebugApp = mDebugApp;
8565                    mOrigWaitForDebugger = mWaitForDebugger;
8566                }
8567                mDebugApp = packageName;
8568                mWaitForDebugger = waitForDebugger;
8569                mDebugTransient = !persistent;
8570                if (packageName != null) {
8571                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8572                            false, UserHandle.USER_ALL, "set debug app");
8573                }
8574            }
8575        } finally {
8576            Binder.restoreCallingIdentity(ident);
8577        }
8578    }
8579
8580    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8581        synchronized (this) {
8582            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8583            if (!isDebuggable) {
8584                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8585                    throw new SecurityException("Process not debuggable: " + app.packageName);
8586                }
8587            }
8588
8589            mOpenGlTraceApp = processName;
8590        }
8591    }
8592
8593    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8594            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8595        synchronized (this) {
8596            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8597            if (!isDebuggable) {
8598                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8599                    throw new SecurityException("Process not debuggable: " + app.packageName);
8600                }
8601            }
8602            mProfileApp = processName;
8603            mProfileFile = profileFile;
8604            if (mProfileFd != null) {
8605                try {
8606                    mProfileFd.close();
8607                } catch (IOException e) {
8608                }
8609                mProfileFd = null;
8610            }
8611            mProfileFd = profileFd;
8612            mProfileType = 0;
8613            mAutoStopProfiler = autoStopProfiler;
8614        }
8615    }
8616
8617    @Override
8618    public void setAlwaysFinish(boolean enabled) {
8619        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8620                "setAlwaysFinish()");
8621
8622        Settings.Global.putInt(
8623                mContext.getContentResolver(),
8624                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8625
8626        synchronized (this) {
8627            mAlwaysFinishActivities = enabled;
8628        }
8629    }
8630
8631    @Override
8632    public void setActivityController(IActivityController controller) {
8633        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8634                "setActivityController()");
8635        synchronized (this) {
8636            mController = controller;
8637            Watchdog.getInstance().setActivityController(controller);
8638        }
8639    }
8640
8641    @Override
8642    public void setUserIsMonkey(boolean userIsMonkey) {
8643        synchronized (this) {
8644            synchronized (mPidsSelfLocked) {
8645                final int callingPid = Binder.getCallingPid();
8646                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8647                if (precessRecord == null) {
8648                    throw new SecurityException("Unknown process: " + callingPid);
8649                }
8650                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8651                    throw new SecurityException("Only an instrumentation process "
8652                            + "with a UiAutomation can call setUserIsMonkey");
8653                }
8654            }
8655            mUserIsMonkey = userIsMonkey;
8656        }
8657    }
8658
8659    @Override
8660    public boolean isUserAMonkey() {
8661        synchronized (this) {
8662            // If there is a controller also implies the user is a monkey.
8663            return (mUserIsMonkey || mController != null);
8664        }
8665    }
8666
8667    public void requestBugReport() {
8668        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8669        SystemProperties.set("ctl.start", "bugreport");
8670    }
8671
8672    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8673        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8674    }
8675
8676    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8677        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8678            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8679        }
8680        return KEY_DISPATCHING_TIMEOUT;
8681    }
8682
8683    @Override
8684    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8685        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8686                != PackageManager.PERMISSION_GRANTED) {
8687            throw new SecurityException("Requires permission "
8688                    + android.Manifest.permission.FILTER_EVENTS);
8689        }
8690        ProcessRecord proc;
8691        long timeout;
8692        synchronized (this) {
8693            synchronized (mPidsSelfLocked) {
8694                proc = mPidsSelfLocked.get(pid);
8695            }
8696            timeout = getInputDispatchingTimeoutLocked(proc);
8697        }
8698
8699        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8700            return -1;
8701        }
8702
8703        return timeout;
8704    }
8705
8706    /**
8707     * Handle input dispatching timeouts.
8708     * Returns whether input dispatching should be aborted or not.
8709     */
8710    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8711            final ActivityRecord activity, final ActivityRecord parent,
8712            final boolean aboveSystem, String reason) {
8713        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8714                != PackageManager.PERMISSION_GRANTED) {
8715            throw new SecurityException("Requires permission "
8716                    + android.Manifest.permission.FILTER_EVENTS);
8717        }
8718
8719        final String annotation;
8720        if (reason == null) {
8721            annotation = "Input dispatching timed out";
8722        } else {
8723            annotation = "Input dispatching timed out (" + reason + ")";
8724        }
8725
8726        if (proc != null) {
8727            synchronized (this) {
8728                if (proc.debugging) {
8729                    return false;
8730                }
8731
8732                if (mDidDexOpt) {
8733                    // Give more time since we were dexopting.
8734                    mDidDexOpt = false;
8735                    return false;
8736                }
8737
8738                if (proc.instrumentationClass != null) {
8739                    Bundle info = new Bundle();
8740                    info.putString("shortMsg", "keyDispatchingTimedOut");
8741                    info.putString("longMsg", annotation);
8742                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8743                    return true;
8744                }
8745            }
8746            mHandler.post(new Runnable() {
8747                @Override
8748                public void run() {
8749                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
8750                }
8751            });
8752        }
8753
8754        return true;
8755    }
8756
8757    public Bundle getAssistContextExtras(int requestType) {
8758        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
8759                "getAssistContextExtras()");
8760        PendingAssistExtras pae;
8761        Bundle extras = new Bundle();
8762        synchronized (this) {
8763            ActivityRecord activity = getFocusedStack().mResumedActivity;
8764            if (activity == null) {
8765                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
8766                return null;
8767            }
8768            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
8769            if (activity.app == null || activity.app.thread == null) {
8770                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
8771                return extras;
8772            }
8773            if (activity.app.pid == Binder.getCallingPid()) {
8774                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
8775                return extras;
8776            }
8777            pae = new PendingAssistExtras(activity);
8778            try {
8779                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
8780                        requestType);
8781                mPendingAssistExtras.add(pae);
8782                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
8783            } catch (RemoteException e) {
8784                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
8785                return extras;
8786            }
8787        }
8788        synchronized (pae) {
8789            while (!pae.haveResult) {
8790                try {
8791                    pae.wait();
8792                } catch (InterruptedException e) {
8793                }
8794            }
8795            if (pae.result != null) {
8796                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
8797            }
8798        }
8799        synchronized (this) {
8800            mPendingAssistExtras.remove(pae);
8801            mHandler.removeCallbacks(pae);
8802        }
8803        return extras;
8804    }
8805
8806    public void reportAssistContextExtras(IBinder token, Bundle extras) {
8807        PendingAssistExtras pae = (PendingAssistExtras)token;
8808        synchronized (pae) {
8809            pae.result = extras;
8810            pae.haveResult = true;
8811            pae.notifyAll();
8812        }
8813    }
8814
8815    public void registerProcessObserver(IProcessObserver observer) {
8816        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8817                "registerProcessObserver()");
8818        synchronized (this) {
8819            mProcessObservers.register(observer);
8820        }
8821    }
8822
8823    @Override
8824    public void unregisterProcessObserver(IProcessObserver observer) {
8825        synchronized (this) {
8826            mProcessObservers.unregister(observer);
8827        }
8828    }
8829
8830    @Override
8831    public boolean convertFromTranslucent(IBinder token) {
8832        final long origId = Binder.clearCallingIdentity();
8833        try {
8834            synchronized (this) {
8835                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8836                if (r == null) {
8837                    return false;
8838                }
8839                if (r.changeWindowTranslucency(true)) {
8840                    mWindowManager.setAppFullscreen(token, true);
8841                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8842                    return true;
8843                }
8844                return false;
8845            }
8846        } finally {
8847            Binder.restoreCallingIdentity(origId);
8848        }
8849    }
8850
8851    @Override
8852    public boolean convertToTranslucent(IBinder token) {
8853        final long origId = Binder.clearCallingIdentity();
8854        try {
8855            synchronized (this) {
8856                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8857                if (r == null) {
8858                    return false;
8859                }
8860                if (r.changeWindowTranslucency(false)) {
8861                    r.task.stack.convertToTranslucent(r);
8862                    mWindowManager.setAppFullscreen(token, false);
8863                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8864                    return true;
8865                }
8866                return false;
8867            }
8868        } finally {
8869            Binder.restoreCallingIdentity(origId);
8870        }
8871    }
8872
8873    @Override
8874    public void setImmersive(IBinder token, boolean immersive) {
8875        synchronized(this) {
8876            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8877            if (r == null) {
8878                throw new IllegalArgumentException();
8879            }
8880            r.immersive = immersive;
8881
8882            // update associated state if we're frontmost
8883            if (r == mFocusedActivity) {
8884                if (DEBUG_IMMERSIVE) {
8885                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
8886                }
8887                applyUpdateLockStateLocked(r);
8888            }
8889        }
8890    }
8891
8892    @Override
8893    public boolean isImmersive(IBinder token) {
8894        synchronized (this) {
8895            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8896            if (r == null) {
8897                throw new IllegalArgumentException();
8898            }
8899            return r.immersive;
8900        }
8901    }
8902
8903    public boolean isTopActivityImmersive() {
8904        enforceNotIsolatedCaller("startActivity");
8905        synchronized (this) {
8906            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
8907            return (r != null) ? r.immersive : false;
8908        }
8909    }
8910
8911    public final void enterSafeMode() {
8912        synchronized(this) {
8913            // It only makes sense to do this before the system is ready
8914            // and started launching other packages.
8915            if (!mSystemReady) {
8916                try {
8917                    AppGlobals.getPackageManager().enterSafeMode();
8918                } catch (RemoteException e) {
8919                }
8920            }
8921        }
8922    }
8923
8924    public final void showSafeModeOverlay() {
8925        View v = LayoutInflater.from(mContext).inflate(
8926                com.android.internal.R.layout.safe_mode, null);
8927        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
8928        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
8929        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
8930        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
8931        lp.gravity = Gravity.BOTTOM | Gravity.START;
8932        lp.format = v.getBackground().getOpacity();
8933        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
8934                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
8935        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
8936        ((WindowManager)mContext.getSystemService(
8937                Context.WINDOW_SERVICE)).addView(v, lp);
8938    }
8939
8940    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
8941        if (!(sender instanceof PendingIntentRecord)) {
8942            return;
8943        }
8944        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8945        synchronized (stats) {
8946            if (mBatteryStatsService.isOnBattery()) {
8947                mBatteryStatsService.enforceCallingPermission();
8948                PendingIntentRecord rec = (PendingIntentRecord)sender;
8949                int MY_UID = Binder.getCallingUid();
8950                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
8951                BatteryStatsImpl.Uid.Pkg pkg =
8952                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
8953                            sourcePkg != null ? sourcePkg : rec.key.packageName);
8954                pkg.incWakeupsLocked();
8955            }
8956        }
8957    }
8958
8959    public boolean killPids(int[] pids, String pReason, boolean secure) {
8960        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8961            throw new SecurityException("killPids only available to the system");
8962        }
8963        String reason = (pReason == null) ? "Unknown" : pReason;
8964        // XXX Note: don't acquire main activity lock here, because the window
8965        // manager calls in with its locks held.
8966
8967        boolean killed = false;
8968        synchronized (mPidsSelfLocked) {
8969            int[] types = new int[pids.length];
8970            int worstType = 0;
8971            for (int i=0; i<pids.length; i++) {
8972                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8973                if (proc != null) {
8974                    int type = proc.setAdj;
8975                    types[i] = type;
8976                    if (type > worstType) {
8977                        worstType = type;
8978                    }
8979                }
8980            }
8981
8982            // If the worst oom_adj is somewhere in the cached proc LRU range,
8983            // then constrain it so we will kill all cached procs.
8984            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
8985                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
8986                worstType = ProcessList.CACHED_APP_MIN_ADJ;
8987            }
8988
8989            // If this is not a secure call, don't let it kill processes that
8990            // are important.
8991            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
8992                worstType = ProcessList.SERVICE_ADJ;
8993            }
8994
8995            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
8996            for (int i=0; i<pids.length; i++) {
8997                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8998                if (proc == null) {
8999                    continue;
9000                }
9001                int adj = proc.setAdj;
9002                if (adj >= worstType && !proc.killedByAm) {
9003                    killUnneededProcessLocked(proc, reason);
9004                    killed = true;
9005                }
9006            }
9007        }
9008        return killed;
9009    }
9010
9011    @Override
9012    public void killUid(int uid, String reason) {
9013        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9014            throw new SecurityException("killUid only available to the system");
9015        }
9016        synchronized (this) {
9017            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9018                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9019                    reason != null ? reason : "kill uid");
9020        }
9021    }
9022
9023    @Override
9024    public boolean killProcessesBelowForeground(String reason) {
9025        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9026            throw new SecurityException("killProcessesBelowForeground() only available to system");
9027        }
9028
9029        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9030    }
9031
9032    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9033        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9034            throw new SecurityException("killProcessesBelowAdj() only available to system");
9035        }
9036
9037        boolean killed = false;
9038        synchronized (mPidsSelfLocked) {
9039            final int size = mPidsSelfLocked.size();
9040            for (int i = 0; i < size; i++) {
9041                final int pid = mPidsSelfLocked.keyAt(i);
9042                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9043                if (proc == null) continue;
9044
9045                final int adj = proc.setAdj;
9046                if (adj > belowAdj && !proc.killedByAm) {
9047                    killUnneededProcessLocked(proc, reason);
9048                    killed = true;
9049                }
9050            }
9051        }
9052        return killed;
9053    }
9054
9055    @Override
9056    public void hang(final IBinder who, boolean allowRestart) {
9057        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9058                != PackageManager.PERMISSION_GRANTED) {
9059            throw new SecurityException("Requires permission "
9060                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9061        }
9062
9063        final IBinder.DeathRecipient death = new DeathRecipient() {
9064            @Override
9065            public void binderDied() {
9066                synchronized (this) {
9067                    notifyAll();
9068                }
9069            }
9070        };
9071
9072        try {
9073            who.linkToDeath(death, 0);
9074        } catch (RemoteException e) {
9075            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9076            return;
9077        }
9078
9079        synchronized (this) {
9080            Watchdog.getInstance().setAllowRestart(allowRestart);
9081            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9082            synchronized (death) {
9083                while (who.isBinderAlive()) {
9084                    try {
9085                        death.wait();
9086                    } catch (InterruptedException e) {
9087                    }
9088                }
9089            }
9090            Watchdog.getInstance().setAllowRestart(true);
9091        }
9092    }
9093
9094    @Override
9095    public void restart() {
9096        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9097                != PackageManager.PERMISSION_GRANTED) {
9098            throw new SecurityException("Requires permission "
9099                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9100        }
9101
9102        Log.i(TAG, "Sending shutdown broadcast...");
9103
9104        BroadcastReceiver br = new BroadcastReceiver() {
9105            @Override public void onReceive(Context context, Intent intent) {
9106                // Now the broadcast is done, finish up the low-level shutdown.
9107                Log.i(TAG, "Shutting down activity manager...");
9108                shutdown(10000);
9109                Log.i(TAG, "Shutdown complete, restarting!");
9110                Process.killProcess(Process.myPid());
9111                System.exit(10);
9112            }
9113        };
9114
9115        // First send the high-level shut down broadcast.
9116        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9117        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9118        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9119        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9120        mContext.sendOrderedBroadcastAsUser(intent,
9121                UserHandle.ALL, null, br, mHandler, 0, null, null);
9122        */
9123        br.onReceive(mContext, intent);
9124    }
9125
9126    private long getLowRamTimeSinceIdle(long now) {
9127        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9128    }
9129
9130    @Override
9131    public void performIdleMaintenance() {
9132        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9133                != PackageManager.PERMISSION_GRANTED) {
9134            throw new SecurityException("Requires permission "
9135                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9136        }
9137
9138        synchronized (this) {
9139            final long now = SystemClock.uptimeMillis();
9140            final long timeSinceLastIdle = now - mLastIdleTime;
9141            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9142            mLastIdleTime = now;
9143            mLowRamTimeSinceLastIdle = 0;
9144            if (mLowRamStartTime != 0) {
9145                mLowRamStartTime = now;
9146            }
9147
9148            StringBuilder sb = new StringBuilder(128);
9149            sb.append("Idle maintenance over ");
9150            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9151            sb.append(" low RAM for ");
9152            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9153            Slog.i(TAG, sb.toString());
9154
9155            // If at least 1/3 of our time since the last idle period has been spent
9156            // with RAM low, then we want to kill processes.
9157            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9158
9159            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9160                ProcessRecord proc = mLruProcesses.get(i);
9161                if (proc.notCachedSinceIdle) {
9162                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9163                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9164                        if (doKilling && proc.initialIdlePss != 0
9165                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9166                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9167                                    + " from " + proc.initialIdlePss + ")");
9168                        }
9169                    }
9170                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9171                    proc.notCachedSinceIdle = true;
9172                    proc.initialIdlePss = 0;
9173                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9174                            mSleeping, now);
9175                }
9176            }
9177
9178            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9179            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9180        }
9181    }
9182
9183    public final void startRunning(String pkg, String cls, String action,
9184            String data) {
9185        synchronized(this) {
9186            if (mStartRunning) {
9187                return;
9188            }
9189            mStartRunning = true;
9190            mTopComponent = pkg != null && cls != null
9191                    ? new ComponentName(pkg, cls) : null;
9192            mTopAction = action != null ? action : Intent.ACTION_MAIN;
9193            mTopData = data;
9194            if (!mSystemReady) {
9195                return;
9196            }
9197        }
9198
9199        systemReady(null);
9200    }
9201
9202    private void retrieveSettings() {
9203        final ContentResolver resolver = mContext.getContentResolver();
9204        String debugApp = Settings.Global.getString(
9205            resolver, Settings.Global.DEBUG_APP);
9206        boolean waitForDebugger = Settings.Global.getInt(
9207            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9208        boolean alwaysFinishActivities = Settings.Global.getInt(
9209            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9210        boolean forceRtl = Settings.Global.getInt(
9211                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9212        // Transfer any global setting for forcing RTL layout, into a System Property
9213        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9214
9215        Configuration configuration = new Configuration();
9216        Settings.System.getConfiguration(resolver, configuration);
9217        if (forceRtl) {
9218            // This will take care of setting the correct layout direction flags
9219            configuration.setLayoutDirection(configuration.locale);
9220        }
9221
9222        synchronized (this) {
9223            mDebugApp = mOrigDebugApp = debugApp;
9224            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9225            mAlwaysFinishActivities = alwaysFinishActivities;
9226            // This happens before any activities are started, so we can
9227            // change mConfiguration in-place.
9228            updateConfigurationLocked(configuration, null, false, true);
9229            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9230        }
9231    }
9232
9233    public boolean testIsSystemReady() {
9234        // no need to synchronize(this) just to read & return the value
9235        return mSystemReady;
9236    }
9237
9238    private static File getCalledPreBootReceiversFile() {
9239        File dataDir = Environment.getDataDirectory();
9240        File systemDir = new File(dataDir, "system");
9241        File fname = new File(systemDir, "called_pre_boots.dat");
9242        return fname;
9243    }
9244
9245    static final int LAST_DONE_VERSION = 10000;
9246
9247    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9248        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9249        File file = getCalledPreBootReceiversFile();
9250        FileInputStream fis = null;
9251        try {
9252            fis = new FileInputStream(file);
9253            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9254            int fvers = dis.readInt();
9255            if (fvers == LAST_DONE_VERSION) {
9256                String vers = dis.readUTF();
9257                String codename = dis.readUTF();
9258                String build = dis.readUTF();
9259                if (android.os.Build.VERSION.RELEASE.equals(vers)
9260                        && android.os.Build.VERSION.CODENAME.equals(codename)
9261                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9262                    int num = dis.readInt();
9263                    while (num > 0) {
9264                        num--;
9265                        String pkg = dis.readUTF();
9266                        String cls = dis.readUTF();
9267                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9268                    }
9269                }
9270            }
9271        } catch (FileNotFoundException e) {
9272        } catch (IOException e) {
9273            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9274        } finally {
9275            if (fis != null) {
9276                try {
9277                    fis.close();
9278                } catch (IOException e) {
9279                }
9280            }
9281        }
9282        return lastDoneReceivers;
9283    }
9284
9285    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9286        File file = getCalledPreBootReceiversFile();
9287        FileOutputStream fos = null;
9288        DataOutputStream dos = null;
9289        try {
9290            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9291            fos = new FileOutputStream(file);
9292            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9293            dos.writeInt(LAST_DONE_VERSION);
9294            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9295            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9296            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9297            dos.writeInt(list.size());
9298            for (int i=0; i<list.size(); i++) {
9299                dos.writeUTF(list.get(i).getPackageName());
9300                dos.writeUTF(list.get(i).getClassName());
9301            }
9302        } catch (IOException e) {
9303            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9304            file.delete();
9305        } finally {
9306            FileUtils.sync(fos);
9307            if (dos != null) {
9308                try {
9309                    dos.close();
9310                } catch (IOException e) {
9311                    // TODO Auto-generated catch block
9312                    e.printStackTrace();
9313                }
9314            }
9315        }
9316    }
9317
9318    public void systemReady(final Runnable goingCallback) {
9319        synchronized(this) {
9320            if (mSystemReady) {
9321                if (goingCallback != null) goingCallback.run();
9322                return;
9323            }
9324
9325            // Check to see if there are any update receivers to run.
9326            if (!mDidUpdate) {
9327                if (mWaitingUpdate) {
9328                    return;
9329                }
9330                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9331                List<ResolveInfo> ris = null;
9332                try {
9333                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9334                            intent, null, 0, 0);
9335                } catch (RemoteException e) {
9336                }
9337                if (ris != null) {
9338                    for (int i=ris.size()-1; i>=0; i--) {
9339                        if ((ris.get(i).activityInfo.applicationInfo.flags
9340                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9341                            ris.remove(i);
9342                        }
9343                    }
9344                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9345
9346                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9347
9348                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9349                    for (int i=0; i<ris.size(); i++) {
9350                        ActivityInfo ai = ris.get(i).activityInfo;
9351                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9352                        if (lastDoneReceivers.contains(comp)) {
9353                            // We already did the pre boot receiver for this app with the current
9354                            // platform version, so don't do it again...
9355                            ris.remove(i);
9356                            i--;
9357                            // ...however, do keep it as one that has been done, so we don't
9358                            // forget about it when rewriting the file of last done receivers.
9359                            doneReceivers.add(comp);
9360                        }
9361                    }
9362
9363                    final int[] users = getUsersLocked();
9364                    for (int i=0; i<ris.size(); i++) {
9365                        ActivityInfo ai = ris.get(i).activityInfo;
9366                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9367                        doneReceivers.add(comp);
9368                        intent.setComponent(comp);
9369                        for (int j=0; j<users.length; j++) {
9370                            IIntentReceiver finisher = null;
9371                            if (i == ris.size()-1 && j == users.length-1) {
9372                                finisher = new IIntentReceiver.Stub() {
9373                                    public void performReceive(Intent intent, int resultCode,
9374                                            String data, Bundle extras, boolean ordered,
9375                                            boolean sticky, int sendingUser) {
9376                                        // The raw IIntentReceiver interface is called
9377                                        // with the AM lock held, so redispatch to
9378                                        // execute our code without the lock.
9379                                        mHandler.post(new Runnable() {
9380                                            public void run() {
9381                                                synchronized (ActivityManagerService.this) {
9382                                                    mDidUpdate = true;
9383                                                }
9384                                                writeLastDonePreBootReceivers(doneReceivers);
9385                                                showBootMessage(mContext.getText(
9386                                                        R.string.android_upgrading_complete),
9387                                                        false);
9388                                                systemReady(goingCallback);
9389                                            }
9390                                        });
9391                                    }
9392                                };
9393                            }
9394                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9395                                    + " for user " + users[j]);
9396                            broadcastIntentLocked(null, null, intent, null, finisher,
9397                                    0, null, null, null, AppOpsManager.OP_NONE,
9398                                    true, false, MY_PID, Process.SYSTEM_UID,
9399                                    users[j]);
9400                            if (finisher != null) {
9401                                mWaitingUpdate = true;
9402                            }
9403                        }
9404                    }
9405                }
9406                if (mWaitingUpdate) {
9407                    return;
9408                }
9409                mDidUpdate = true;
9410            }
9411
9412            mAppOpsService.systemReady();
9413            mSystemReady = true;
9414            if (!mStartRunning) {
9415                return;
9416            }
9417        }
9418
9419        ArrayList<ProcessRecord> procsToKill = null;
9420        synchronized(mPidsSelfLocked) {
9421            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9422                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9423                if (!isAllowedWhileBooting(proc.info)){
9424                    if (procsToKill == null) {
9425                        procsToKill = new ArrayList<ProcessRecord>();
9426                    }
9427                    procsToKill.add(proc);
9428                }
9429            }
9430        }
9431
9432        synchronized(this) {
9433            if (procsToKill != null) {
9434                for (int i=procsToKill.size()-1; i>=0; i--) {
9435                    ProcessRecord proc = procsToKill.get(i);
9436                    Slog.i(TAG, "Removing system update proc: " + proc);
9437                    removeProcessLocked(proc, true, false, "system update done");
9438                }
9439            }
9440
9441            // Now that we have cleaned up any update processes, we
9442            // are ready to start launching real processes and know that
9443            // we won't trample on them any more.
9444            mProcessesReady = true;
9445        }
9446
9447        Slog.i(TAG, "System now ready");
9448        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9449            SystemClock.uptimeMillis());
9450
9451        synchronized(this) {
9452            // Make sure we have no pre-ready processes sitting around.
9453
9454            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9455                ResolveInfo ri = mContext.getPackageManager()
9456                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9457                                STOCK_PM_FLAGS);
9458                CharSequence errorMsg = null;
9459                if (ri != null) {
9460                    ActivityInfo ai = ri.activityInfo;
9461                    ApplicationInfo app = ai.applicationInfo;
9462                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9463                        mTopAction = Intent.ACTION_FACTORY_TEST;
9464                        mTopData = null;
9465                        mTopComponent = new ComponentName(app.packageName,
9466                                ai.name);
9467                    } else {
9468                        errorMsg = mContext.getResources().getText(
9469                                com.android.internal.R.string.factorytest_not_system);
9470                    }
9471                } else {
9472                    errorMsg = mContext.getResources().getText(
9473                            com.android.internal.R.string.factorytest_no_action);
9474                }
9475                if (errorMsg != null) {
9476                    mTopAction = null;
9477                    mTopData = null;
9478                    mTopComponent = null;
9479                    Message msg = Message.obtain();
9480                    msg.what = SHOW_FACTORY_ERROR_MSG;
9481                    msg.getData().putCharSequence("msg", errorMsg);
9482                    mHandler.sendMessage(msg);
9483                }
9484            }
9485        }
9486
9487        retrieveSettings();
9488
9489        synchronized (this) {
9490            readGrantedUriPermissionsLocked();
9491        }
9492
9493        if (goingCallback != null) goingCallback.run();
9494
9495        synchronized (this) {
9496            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9497                try {
9498                    List apps = AppGlobals.getPackageManager().
9499                        getPersistentApplications(STOCK_PM_FLAGS);
9500                    if (apps != null) {
9501                        int N = apps.size();
9502                        int i;
9503                        for (i=0; i<N; i++) {
9504                            ApplicationInfo info
9505                                = (ApplicationInfo)apps.get(i);
9506                            if (info != null &&
9507                                    !info.packageName.equals("android")) {
9508                                addAppLocked(info, false);
9509                            }
9510                        }
9511                    }
9512                } catch (RemoteException ex) {
9513                    // pm is in same process, this will never happen.
9514                }
9515            }
9516
9517            // Start up initial activity.
9518            mBooting = true;
9519
9520            try {
9521                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9522                    Message msg = Message.obtain();
9523                    msg.what = SHOW_UID_ERROR_MSG;
9524                    mHandler.sendMessage(msg);
9525                }
9526            } catch (RemoteException e) {
9527            }
9528
9529            long ident = Binder.clearCallingIdentity();
9530            try {
9531                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9532                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9533                        | Intent.FLAG_RECEIVER_FOREGROUND);
9534                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9535                broadcastIntentLocked(null, null, intent,
9536                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9537                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9538                intent = new Intent(Intent.ACTION_USER_STARTING);
9539                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9540                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9541                broadcastIntentLocked(null, null, intent,
9542                        null, new IIntentReceiver.Stub() {
9543                            @Override
9544                            public void performReceive(Intent intent, int resultCode, String data,
9545                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9546                                    throws RemoteException {
9547                            }
9548                        }, 0, null, null,
9549                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9550                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9551            } finally {
9552                Binder.restoreCallingIdentity(ident);
9553            }
9554            mStackSupervisor.resumeTopActivitiesLocked();
9555            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9556        }
9557    }
9558
9559    private boolean makeAppCrashingLocked(ProcessRecord app,
9560            String shortMsg, String longMsg, String stackTrace) {
9561        app.crashing = true;
9562        app.crashingReport = generateProcessError(app,
9563                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9564        startAppProblemLocked(app);
9565        app.stopFreezingAllLocked();
9566        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9567    }
9568
9569    private void makeAppNotRespondingLocked(ProcessRecord app,
9570            String activity, String shortMsg, String longMsg) {
9571        app.notResponding = true;
9572        app.notRespondingReport = generateProcessError(app,
9573                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9574                activity, shortMsg, longMsg, null);
9575        startAppProblemLocked(app);
9576        app.stopFreezingAllLocked();
9577    }
9578
9579    /**
9580     * Generate a process error record, suitable for attachment to a ProcessRecord.
9581     *
9582     * @param app The ProcessRecord in which the error occurred.
9583     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9584     *                      ActivityManager.AppErrorStateInfo
9585     * @param activity The activity associated with the crash, if known.
9586     * @param shortMsg Short message describing the crash.
9587     * @param longMsg Long message describing the crash.
9588     * @param stackTrace Full crash stack trace, may be null.
9589     *
9590     * @return Returns a fully-formed AppErrorStateInfo record.
9591     */
9592    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9593            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9594        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9595
9596        report.condition = condition;
9597        report.processName = app.processName;
9598        report.pid = app.pid;
9599        report.uid = app.info.uid;
9600        report.tag = activity;
9601        report.shortMsg = shortMsg;
9602        report.longMsg = longMsg;
9603        report.stackTrace = stackTrace;
9604
9605        return report;
9606    }
9607
9608    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9609        synchronized (this) {
9610            app.crashing = false;
9611            app.crashingReport = null;
9612            app.notResponding = false;
9613            app.notRespondingReport = null;
9614            if (app.anrDialog == fromDialog) {
9615                app.anrDialog = null;
9616            }
9617            if (app.waitDialog == fromDialog) {
9618                app.waitDialog = null;
9619            }
9620            if (app.pid > 0 && app.pid != MY_PID) {
9621                handleAppCrashLocked(app, null, null, null);
9622                killUnneededProcessLocked(app, "user request after error");
9623            }
9624        }
9625    }
9626
9627    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9628            String stackTrace) {
9629        long now = SystemClock.uptimeMillis();
9630
9631        Long crashTime;
9632        if (!app.isolated) {
9633            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9634        } else {
9635            crashTime = null;
9636        }
9637        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9638            // This process loses!
9639            Slog.w(TAG, "Process " + app.info.processName
9640                    + " has crashed too many times: killing!");
9641            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9642                    app.userId, app.info.processName, app.uid);
9643            mStackSupervisor.handleAppCrashLocked(app);
9644            if (!app.persistent) {
9645                // We don't want to start this process again until the user
9646                // explicitly does so...  but for persistent process, we really
9647                // need to keep it running.  If a persistent process is actually
9648                // repeatedly crashing, then badness for everyone.
9649                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9650                        app.info.processName);
9651                if (!app.isolated) {
9652                    // XXX We don't have a way to mark isolated processes
9653                    // as bad, since they don't have a peristent identity.
9654                    mBadProcesses.put(app.info.processName, app.uid,
9655                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9656                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9657                }
9658                app.bad = true;
9659                app.removed = true;
9660                // Don't let services in this process be restarted and potentially
9661                // annoy the user repeatedly.  Unless it is persistent, since those
9662                // processes run critical code.
9663                removeProcessLocked(app, false, false, "crash");
9664                mStackSupervisor.resumeTopActivitiesLocked();
9665                return false;
9666            }
9667            mStackSupervisor.resumeTopActivitiesLocked();
9668        } else {
9669            mStackSupervisor.finishTopRunningActivityLocked(app);
9670        }
9671
9672        // Bump up the crash count of any services currently running in the proc.
9673        for (int i=app.services.size()-1; i>=0; i--) {
9674            // Any services running in the application need to be placed
9675            // back in the pending list.
9676            ServiceRecord sr = app.services.valueAt(i);
9677            sr.crashCount++;
9678        }
9679
9680        // If the crashing process is what we consider to be the "home process" and it has been
9681        // replaced by a third-party app, clear the package preferred activities from packages
9682        // with a home activity running in the process to prevent a repeatedly crashing app
9683        // from blocking the user to manually clear the list.
9684        final ArrayList<ActivityRecord> activities = app.activities;
9685        if (app == mHomeProcess && activities.size() > 0
9686                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9687            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9688                final ActivityRecord r = activities.get(activityNdx);
9689                if (r.isHomeActivity()) {
9690                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9691                    try {
9692                        ActivityThread.getPackageManager()
9693                                .clearPackagePreferredActivities(r.packageName);
9694                    } catch (RemoteException c) {
9695                        // pm is in same process, this will never happen.
9696                    }
9697                }
9698            }
9699        }
9700
9701        if (!app.isolated) {
9702            // XXX Can't keep track of crash times for isolated processes,
9703            // because they don't have a perisistent identity.
9704            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9705        }
9706
9707        return true;
9708    }
9709
9710    void startAppProblemLocked(ProcessRecord app) {
9711        if (app.userId == mCurrentUserId) {
9712            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9713                    mContext, app.info.packageName, app.info.flags);
9714        } else {
9715            // If this app is not running under the current user, then we
9716            // can't give it a report button because that would require
9717            // launching the report UI under a different user.
9718            app.errorReportReceiver = null;
9719        }
9720        skipCurrentReceiverLocked(app);
9721    }
9722
9723    void skipCurrentReceiverLocked(ProcessRecord app) {
9724        for (BroadcastQueue queue : mBroadcastQueues) {
9725            queue.skipCurrentReceiverLocked(app);
9726        }
9727    }
9728
9729    /**
9730     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9731     * The application process will exit immediately after this call returns.
9732     * @param app object of the crashing app, null for the system server
9733     * @param crashInfo describing the exception
9734     */
9735    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9736        ProcessRecord r = findAppProcess(app, "Crash");
9737        final String processName = app == null ? "system_server"
9738                : (r == null ? "unknown" : r.processName);
9739
9740        handleApplicationCrashInner("crash", r, processName, crashInfo);
9741    }
9742
9743    /* Native crash reporting uses this inner version because it needs to be somewhat
9744     * decoupled from the AM-managed cleanup lifecycle
9745     */
9746    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
9747            ApplicationErrorReport.CrashInfo crashInfo) {
9748        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
9749                UserHandle.getUserId(Binder.getCallingUid()), processName,
9750                r == null ? -1 : r.info.flags,
9751                crashInfo.exceptionClassName,
9752                crashInfo.exceptionMessage,
9753                crashInfo.throwFileName,
9754                crashInfo.throwLineNumber);
9755
9756        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
9757
9758        crashApplication(r, crashInfo);
9759    }
9760
9761    public void handleApplicationStrictModeViolation(
9762            IBinder app,
9763            int violationMask,
9764            StrictMode.ViolationInfo info) {
9765        ProcessRecord r = findAppProcess(app, "StrictMode");
9766        if (r == null) {
9767            return;
9768        }
9769
9770        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
9771            Integer stackFingerprint = info.hashCode();
9772            boolean logIt = true;
9773            synchronized (mAlreadyLoggedViolatedStacks) {
9774                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
9775                    logIt = false;
9776                    // TODO: sub-sample into EventLog for these, with
9777                    // the info.durationMillis?  Then we'd get
9778                    // the relative pain numbers, without logging all
9779                    // the stack traces repeatedly.  We'd want to do
9780                    // likewise in the client code, which also does
9781                    // dup suppression, before the Binder call.
9782                } else {
9783                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
9784                        mAlreadyLoggedViolatedStacks.clear();
9785                    }
9786                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
9787                }
9788            }
9789            if (logIt) {
9790                logStrictModeViolationToDropBox(r, info);
9791            }
9792        }
9793
9794        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
9795            AppErrorResult result = new AppErrorResult();
9796            synchronized (this) {
9797                final long origId = Binder.clearCallingIdentity();
9798
9799                Message msg = Message.obtain();
9800                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
9801                HashMap<String, Object> data = new HashMap<String, Object>();
9802                data.put("result", result);
9803                data.put("app", r);
9804                data.put("violationMask", violationMask);
9805                data.put("info", info);
9806                msg.obj = data;
9807                mHandler.sendMessage(msg);
9808
9809                Binder.restoreCallingIdentity(origId);
9810            }
9811            int res = result.get();
9812            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
9813        }
9814    }
9815
9816    // Depending on the policy in effect, there could be a bunch of
9817    // these in quick succession so we try to batch these together to
9818    // minimize disk writes, number of dropbox entries, and maximize
9819    // compression, by having more fewer, larger records.
9820    private void logStrictModeViolationToDropBox(
9821            ProcessRecord process,
9822            StrictMode.ViolationInfo info) {
9823        if (info == null) {
9824            return;
9825        }
9826        final boolean isSystemApp = process == null ||
9827                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
9828                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
9829        final String processName = process == null ? "unknown" : process.processName;
9830        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
9831        final DropBoxManager dbox = (DropBoxManager)
9832                mContext.getSystemService(Context.DROPBOX_SERVICE);
9833
9834        // Exit early if the dropbox isn't configured to accept this report type.
9835        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9836
9837        boolean bufferWasEmpty;
9838        boolean needsFlush;
9839        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
9840        synchronized (sb) {
9841            bufferWasEmpty = sb.length() == 0;
9842            appendDropBoxProcessHeaders(process, processName, sb);
9843            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9844            sb.append("System-App: ").append(isSystemApp).append("\n");
9845            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
9846            if (info.violationNumThisLoop != 0) {
9847                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
9848            }
9849            if (info.numAnimationsRunning != 0) {
9850                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
9851            }
9852            if (info.broadcastIntentAction != null) {
9853                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
9854            }
9855            if (info.durationMillis != -1) {
9856                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
9857            }
9858            if (info.numInstances != -1) {
9859                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
9860            }
9861            if (info.tags != null) {
9862                for (String tag : info.tags) {
9863                    sb.append("Span-Tag: ").append(tag).append("\n");
9864                }
9865            }
9866            sb.append("\n");
9867            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
9868                sb.append(info.crashInfo.stackTrace);
9869            }
9870            sb.append("\n");
9871
9872            // Only buffer up to ~64k.  Various logging bits truncate
9873            // things at 128k.
9874            needsFlush = (sb.length() > 64 * 1024);
9875        }
9876
9877        // Flush immediately if the buffer's grown too large, or this
9878        // is a non-system app.  Non-system apps are isolated with a
9879        // different tag & policy and not batched.
9880        //
9881        // Batching is useful during internal testing with
9882        // StrictMode settings turned up high.  Without batching,
9883        // thousands of separate files could be created on boot.
9884        if (!isSystemApp || needsFlush) {
9885            new Thread("Error dump: " + dropboxTag) {
9886                @Override
9887                public void run() {
9888                    String report;
9889                    synchronized (sb) {
9890                        report = sb.toString();
9891                        sb.delete(0, sb.length());
9892                        sb.trimToSize();
9893                    }
9894                    if (report.length() != 0) {
9895                        dbox.addText(dropboxTag, report);
9896                    }
9897                }
9898            }.start();
9899            return;
9900        }
9901
9902        // System app batching:
9903        if (!bufferWasEmpty) {
9904            // An existing dropbox-writing thread is outstanding, so
9905            // we don't need to start it up.  The existing thread will
9906            // catch the buffer appends we just did.
9907            return;
9908        }
9909
9910        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
9911        // (After this point, we shouldn't access AMS internal data structures.)
9912        new Thread("Error dump: " + dropboxTag) {
9913            @Override
9914            public void run() {
9915                // 5 second sleep to let stacks arrive and be batched together
9916                try {
9917                    Thread.sleep(5000);  // 5 seconds
9918                } catch (InterruptedException e) {}
9919
9920                String errorReport;
9921                synchronized (mStrictModeBuffer) {
9922                    errorReport = mStrictModeBuffer.toString();
9923                    if (errorReport.length() == 0) {
9924                        return;
9925                    }
9926                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
9927                    mStrictModeBuffer.trimToSize();
9928                }
9929                dbox.addText(dropboxTag, errorReport);
9930            }
9931        }.start();
9932    }
9933
9934    /**
9935     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
9936     * @param app object of the crashing app, null for the system server
9937     * @param tag reported by the caller
9938     * @param crashInfo describing the context of the error
9939     * @return true if the process should exit immediately (WTF is fatal)
9940     */
9941    public boolean handleApplicationWtf(IBinder app, String tag,
9942            ApplicationErrorReport.CrashInfo crashInfo) {
9943        ProcessRecord r = findAppProcess(app, "WTF");
9944        final String processName = app == null ? "system_server"
9945                : (r == null ? "unknown" : r.processName);
9946
9947        EventLog.writeEvent(EventLogTags.AM_WTF,
9948                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
9949                processName,
9950                r == null ? -1 : r.info.flags,
9951                tag, crashInfo.exceptionMessage);
9952
9953        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
9954
9955        if (r != null && r.pid != Process.myPid() &&
9956                Settings.Global.getInt(mContext.getContentResolver(),
9957                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
9958            crashApplication(r, crashInfo);
9959            return true;
9960        } else {
9961            return false;
9962        }
9963    }
9964
9965    /**
9966     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
9967     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
9968     */
9969    private ProcessRecord findAppProcess(IBinder app, String reason) {
9970        if (app == null) {
9971            return null;
9972        }
9973
9974        synchronized (this) {
9975            final int NP = mProcessNames.getMap().size();
9976            for (int ip=0; ip<NP; ip++) {
9977                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
9978                final int NA = apps.size();
9979                for (int ia=0; ia<NA; ia++) {
9980                    ProcessRecord p = apps.valueAt(ia);
9981                    if (p.thread != null && p.thread.asBinder() == app) {
9982                        return p;
9983                    }
9984                }
9985            }
9986
9987            Slog.w(TAG, "Can't find mystery application for " + reason
9988                    + " from pid=" + Binder.getCallingPid()
9989                    + " uid=" + Binder.getCallingUid() + ": " + app);
9990            return null;
9991        }
9992    }
9993
9994    /**
9995     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
9996     * to append various headers to the dropbox log text.
9997     */
9998    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
9999            StringBuilder sb) {
10000        // Watchdog thread ends up invoking this function (with
10001        // a null ProcessRecord) to add the stack file to dropbox.
10002        // Do not acquire a lock on this (am) in such cases, as it
10003        // could cause a potential deadlock, if and when watchdog
10004        // is invoked due to unavailability of lock on am and it
10005        // would prevent watchdog from killing system_server.
10006        if (process == null) {
10007            sb.append("Process: ").append(processName).append("\n");
10008            return;
10009        }
10010        // Note: ProcessRecord 'process' is guarded by the service
10011        // instance.  (notably process.pkgList, which could otherwise change
10012        // concurrently during execution of this method)
10013        synchronized (this) {
10014            sb.append("Process: ").append(processName).append("\n");
10015            int flags = process.info.flags;
10016            IPackageManager pm = AppGlobals.getPackageManager();
10017            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10018            for (int ip=0; ip<process.pkgList.size(); ip++) {
10019                String pkg = process.pkgList.keyAt(ip);
10020                sb.append("Package: ").append(pkg);
10021                try {
10022                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10023                    if (pi != null) {
10024                        sb.append(" v").append(pi.versionCode);
10025                        if (pi.versionName != null) {
10026                            sb.append(" (").append(pi.versionName).append(")");
10027                        }
10028                    }
10029                } catch (RemoteException e) {
10030                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10031                }
10032                sb.append("\n");
10033            }
10034        }
10035    }
10036
10037    private static String processClass(ProcessRecord process) {
10038        if (process == null || process.pid == MY_PID) {
10039            return "system_server";
10040        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10041            return "system_app";
10042        } else {
10043            return "data_app";
10044        }
10045    }
10046
10047    /**
10048     * Write a description of an error (crash, WTF, ANR) to the drop box.
10049     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10050     * @param process which caused the error, null means the system server
10051     * @param activity which triggered the error, null if unknown
10052     * @param parent activity related to the error, null if unknown
10053     * @param subject line related to the error, null if absent
10054     * @param report in long form describing the error, null if absent
10055     * @param logFile to include in the report, null if none
10056     * @param crashInfo giving an application stack trace, null if absent
10057     */
10058    public void addErrorToDropBox(String eventType,
10059            ProcessRecord process, String processName, ActivityRecord activity,
10060            ActivityRecord parent, String subject,
10061            final String report, final File logFile,
10062            final ApplicationErrorReport.CrashInfo crashInfo) {
10063        // NOTE -- this must never acquire the ActivityManagerService lock,
10064        // otherwise the watchdog may be prevented from resetting the system.
10065
10066        final String dropboxTag = processClass(process) + "_" + eventType;
10067        final DropBoxManager dbox = (DropBoxManager)
10068                mContext.getSystemService(Context.DROPBOX_SERVICE);
10069
10070        // Exit early if the dropbox isn't configured to accept this report type.
10071        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10072
10073        final StringBuilder sb = new StringBuilder(1024);
10074        appendDropBoxProcessHeaders(process, processName, sb);
10075        if (activity != null) {
10076            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10077        }
10078        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10079            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10080        }
10081        if (parent != null && parent != activity) {
10082            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10083        }
10084        if (subject != null) {
10085            sb.append("Subject: ").append(subject).append("\n");
10086        }
10087        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10088        if (Debug.isDebuggerConnected()) {
10089            sb.append("Debugger: Connected\n");
10090        }
10091        sb.append("\n");
10092
10093        // Do the rest in a worker thread to avoid blocking the caller on I/O
10094        // (After this point, we shouldn't access AMS internal data structures.)
10095        Thread worker = new Thread("Error dump: " + dropboxTag) {
10096            @Override
10097            public void run() {
10098                if (report != null) {
10099                    sb.append(report);
10100                }
10101                if (logFile != null) {
10102                    try {
10103                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10104                                    "\n\n[[TRUNCATED]]"));
10105                    } catch (IOException e) {
10106                        Slog.e(TAG, "Error reading " + logFile, e);
10107                    }
10108                }
10109                if (crashInfo != null && crashInfo.stackTrace != null) {
10110                    sb.append(crashInfo.stackTrace);
10111                }
10112
10113                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10114                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10115                if (lines > 0) {
10116                    sb.append("\n");
10117
10118                    // Merge several logcat streams, and take the last N lines
10119                    InputStreamReader input = null;
10120                    try {
10121                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10122                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10123                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10124
10125                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10126                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10127                        input = new InputStreamReader(logcat.getInputStream());
10128
10129                        int num;
10130                        char[] buf = new char[8192];
10131                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10132                    } catch (IOException e) {
10133                        Slog.e(TAG, "Error running logcat", e);
10134                    } finally {
10135                        if (input != null) try { input.close(); } catch (IOException e) {}
10136                    }
10137                }
10138
10139                dbox.addText(dropboxTag, sb.toString());
10140            }
10141        };
10142
10143        if (process == null) {
10144            // If process is null, we are being called from some internal code
10145            // and may be about to die -- run this synchronously.
10146            worker.run();
10147        } else {
10148            worker.start();
10149        }
10150    }
10151
10152    /**
10153     * Bring up the "unexpected error" dialog box for a crashing app.
10154     * Deal with edge cases (intercepts from instrumented applications,
10155     * ActivityController, error intent receivers, that sort of thing).
10156     * @param r the application crashing
10157     * @param crashInfo describing the failure
10158     */
10159    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10160        long timeMillis = System.currentTimeMillis();
10161        String shortMsg = crashInfo.exceptionClassName;
10162        String longMsg = crashInfo.exceptionMessage;
10163        String stackTrace = crashInfo.stackTrace;
10164        if (shortMsg != null && longMsg != null) {
10165            longMsg = shortMsg + ": " + longMsg;
10166        } else if (shortMsg != null) {
10167            longMsg = shortMsg;
10168        }
10169
10170        AppErrorResult result = new AppErrorResult();
10171        synchronized (this) {
10172            if (mController != null) {
10173                try {
10174                    String name = r != null ? r.processName : null;
10175                    int pid = r != null ? r.pid : Binder.getCallingPid();
10176                    if (!mController.appCrashed(name, pid,
10177                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10178                        Slog.w(TAG, "Force-killing crashed app " + name
10179                                + " at watcher's request");
10180                        Process.killProcess(pid);
10181                        return;
10182                    }
10183                } catch (RemoteException e) {
10184                    mController = null;
10185                    Watchdog.getInstance().setActivityController(null);
10186                }
10187            }
10188
10189            final long origId = Binder.clearCallingIdentity();
10190
10191            // If this process is running instrumentation, finish it.
10192            if (r != null && r.instrumentationClass != null) {
10193                Slog.w(TAG, "Error in app " + r.processName
10194                      + " running instrumentation " + r.instrumentationClass + ":");
10195                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10196                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10197                Bundle info = new Bundle();
10198                info.putString("shortMsg", shortMsg);
10199                info.putString("longMsg", longMsg);
10200                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10201                Binder.restoreCallingIdentity(origId);
10202                return;
10203            }
10204
10205            // If we can't identify the process or it's already exceeded its crash quota,
10206            // quit right away without showing a crash dialog.
10207            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10208                Binder.restoreCallingIdentity(origId);
10209                return;
10210            }
10211
10212            Message msg = Message.obtain();
10213            msg.what = SHOW_ERROR_MSG;
10214            HashMap data = new HashMap();
10215            data.put("result", result);
10216            data.put("app", r);
10217            msg.obj = data;
10218            mHandler.sendMessage(msg);
10219
10220            Binder.restoreCallingIdentity(origId);
10221        }
10222
10223        int res = result.get();
10224
10225        Intent appErrorIntent = null;
10226        synchronized (this) {
10227            if (r != null && !r.isolated) {
10228                // XXX Can't keep track of crash time for isolated processes,
10229                // since they don't have a persistent identity.
10230                mProcessCrashTimes.put(r.info.processName, r.uid,
10231                        SystemClock.uptimeMillis());
10232            }
10233            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10234                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10235            }
10236        }
10237
10238        if (appErrorIntent != null) {
10239            try {
10240                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10241            } catch (ActivityNotFoundException e) {
10242                Slog.w(TAG, "bug report receiver dissappeared", e);
10243            }
10244        }
10245    }
10246
10247    Intent createAppErrorIntentLocked(ProcessRecord r,
10248            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10249        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10250        if (report == null) {
10251            return null;
10252        }
10253        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10254        result.setComponent(r.errorReportReceiver);
10255        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10256        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10257        return result;
10258    }
10259
10260    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10261            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10262        if (r.errorReportReceiver == null) {
10263            return null;
10264        }
10265
10266        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10267            return null;
10268        }
10269
10270        ApplicationErrorReport report = new ApplicationErrorReport();
10271        report.packageName = r.info.packageName;
10272        report.installerPackageName = r.errorReportReceiver.getPackageName();
10273        report.processName = r.processName;
10274        report.time = timeMillis;
10275        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10276
10277        if (r.crashing || r.forceCrashReport) {
10278            report.type = ApplicationErrorReport.TYPE_CRASH;
10279            report.crashInfo = crashInfo;
10280        } else if (r.notResponding) {
10281            report.type = ApplicationErrorReport.TYPE_ANR;
10282            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10283
10284            report.anrInfo.activity = r.notRespondingReport.tag;
10285            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10286            report.anrInfo.info = r.notRespondingReport.longMsg;
10287        }
10288
10289        return report;
10290    }
10291
10292    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10293        enforceNotIsolatedCaller("getProcessesInErrorState");
10294        // assume our apps are happy - lazy create the list
10295        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10296
10297        final boolean allUsers = ActivityManager.checkUidPermission(
10298                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10299                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10300        int userId = UserHandle.getUserId(Binder.getCallingUid());
10301
10302        synchronized (this) {
10303
10304            // iterate across all processes
10305            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10306                ProcessRecord app = mLruProcesses.get(i);
10307                if (!allUsers && app.userId != userId) {
10308                    continue;
10309                }
10310                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10311                    // This one's in trouble, so we'll generate a report for it
10312                    // crashes are higher priority (in case there's a crash *and* an anr)
10313                    ActivityManager.ProcessErrorStateInfo report = null;
10314                    if (app.crashing) {
10315                        report = app.crashingReport;
10316                    } else if (app.notResponding) {
10317                        report = app.notRespondingReport;
10318                    }
10319
10320                    if (report != null) {
10321                        if (errList == null) {
10322                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10323                        }
10324                        errList.add(report);
10325                    } else {
10326                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10327                                " crashing = " + app.crashing +
10328                                " notResponding = " + app.notResponding);
10329                    }
10330                }
10331            }
10332        }
10333
10334        return errList;
10335    }
10336
10337    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10338        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10339            if (currApp != null) {
10340                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10341            }
10342            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10343        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10344            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10345        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10346            if (currApp != null) {
10347                currApp.lru = 0;
10348            }
10349            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10350        } else if (adj >= ProcessList.SERVICE_ADJ) {
10351            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10352        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10353            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10354        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10355            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10356        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10357            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10358        } else {
10359            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10360        }
10361    }
10362
10363    private void fillInProcMemInfo(ProcessRecord app,
10364            ActivityManager.RunningAppProcessInfo outInfo) {
10365        outInfo.pid = app.pid;
10366        outInfo.uid = app.info.uid;
10367        if (mHeavyWeightProcess == app) {
10368            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10369        }
10370        if (app.persistent) {
10371            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10372        }
10373        if (app.activities.size() > 0) {
10374            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10375        }
10376        outInfo.lastTrimLevel = app.trimMemoryLevel;
10377        int adj = app.curAdj;
10378        outInfo.importance = oomAdjToImportance(adj, outInfo);
10379        outInfo.importanceReasonCode = app.adjTypeCode;
10380    }
10381
10382    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10383        enforceNotIsolatedCaller("getRunningAppProcesses");
10384        // Lazy instantiation of list
10385        List<ActivityManager.RunningAppProcessInfo> runList = null;
10386        final boolean allUsers = ActivityManager.checkUidPermission(
10387                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10388                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10389        int userId = UserHandle.getUserId(Binder.getCallingUid());
10390        synchronized (this) {
10391            // Iterate across all processes
10392            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10393                ProcessRecord app = mLruProcesses.get(i);
10394                if (!allUsers && app.userId != userId) {
10395                    continue;
10396                }
10397                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10398                    // Generate process state info for running application
10399                    ActivityManager.RunningAppProcessInfo currApp =
10400                        new ActivityManager.RunningAppProcessInfo(app.processName,
10401                                app.pid, app.getPackageList());
10402                    fillInProcMemInfo(app, currApp);
10403                    if (app.adjSource instanceof ProcessRecord) {
10404                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10405                        currApp.importanceReasonImportance = oomAdjToImportance(
10406                                app.adjSourceOom, null);
10407                    } else if (app.adjSource instanceof ActivityRecord) {
10408                        ActivityRecord r = (ActivityRecord)app.adjSource;
10409                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10410                    }
10411                    if (app.adjTarget instanceof ComponentName) {
10412                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10413                    }
10414                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10415                    //        + " lru=" + currApp.lru);
10416                    if (runList == null) {
10417                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10418                    }
10419                    runList.add(currApp);
10420                }
10421            }
10422        }
10423        return runList;
10424    }
10425
10426    public List<ApplicationInfo> getRunningExternalApplications() {
10427        enforceNotIsolatedCaller("getRunningExternalApplications");
10428        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10429        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10430        if (runningApps != null && runningApps.size() > 0) {
10431            Set<String> extList = new HashSet<String>();
10432            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10433                if (app.pkgList != null) {
10434                    for (String pkg : app.pkgList) {
10435                        extList.add(pkg);
10436                    }
10437                }
10438            }
10439            IPackageManager pm = AppGlobals.getPackageManager();
10440            for (String pkg : extList) {
10441                try {
10442                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10443                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10444                        retList.add(info);
10445                    }
10446                } catch (RemoteException e) {
10447                }
10448            }
10449        }
10450        return retList;
10451    }
10452
10453    @Override
10454    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10455        enforceNotIsolatedCaller("getMyMemoryState");
10456        synchronized (this) {
10457            ProcessRecord proc;
10458            synchronized (mPidsSelfLocked) {
10459                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10460            }
10461            fillInProcMemInfo(proc, outInfo);
10462        }
10463    }
10464
10465    @Override
10466    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10467        if (checkCallingPermission(android.Manifest.permission.DUMP)
10468                != PackageManager.PERMISSION_GRANTED) {
10469            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10470                    + Binder.getCallingPid()
10471                    + ", uid=" + Binder.getCallingUid()
10472                    + " without permission "
10473                    + android.Manifest.permission.DUMP);
10474            return;
10475        }
10476
10477        boolean dumpAll = false;
10478        boolean dumpClient = false;
10479        String dumpPackage = null;
10480
10481        int opti = 0;
10482        while (opti < args.length) {
10483            String opt = args[opti];
10484            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10485                break;
10486            }
10487            opti++;
10488            if ("-a".equals(opt)) {
10489                dumpAll = true;
10490            } else if ("-c".equals(opt)) {
10491                dumpClient = true;
10492            } else if ("-h".equals(opt)) {
10493                pw.println("Activity manager dump options:");
10494                pw.println("  [-a] [-c] [-h] [cmd] ...");
10495                pw.println("  cmd may be one of:");
10496                pw.println("    a[ctivities]: activity stack state");
10497                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10498                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10499                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10500                pw.println("    o[om]: out of memory management");
10501                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10502                pw.println("    provider [COMP_SPEC]: provider client-side state");
10503                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10504                pw.println("    service [COMP_SPEC]: service client-side state");
10505                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10506                pw.println("    all: dump all activities");
10507                pw.println("    top: dump the top activity");
10508                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10509                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10510                pw.println("    a partial substring in a component name, a");
10511                pw.println("    hex object identifier.");
10512                pw.println("  -a: include all available server state.");
10513                pw.println("  -c: include client state.");
10514                return;
10515            } else {
10516                pw.println("Unknown argument: " + opt + "; use -h for help");
10517            }
10518        }
10519
10520        long origId = Binder.clearCallingIdentity();
10521        boolean more = false;
10522        // Is the caller requesting to dump a particular piece of data?
10523        if (opti < args.length) {
10524            String cmd = args[opti];
10525            opti++;
10526            if ("activities".equals(cmd) || "a".equals(cmd)) {
10527                synchronized (this) {
10528                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10529                }
10530            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10531                String[] newArgs;
10532                String name;
10533                if (opti >= args.length) {
10534                    name = null;
10535                    newArgs = EMPTY_STRING_ARRAY;
10536                } else {
10537                    name = args[opti];
10538                    opti++;
10539                    newArgs = new String[args.length - opti];
10540                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10541                            args.length - opti);
10542                }
10543                synchronized (this) {
10544                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10545                }
10546            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10547                String[] newArgs;
10548                String name;
10549                if (opti >= args.length) {
10550                    name = null;
10551                    newArgs = EMPTY_STRING_ARRAY;
10552                } else {
10553                    name = args[opti];
10554                    opti++;
10555                    newArgs = new String[args.length - opti];
10556                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10557                            args.length - opti);
10558                }
10559                synchronized (this) {
10560                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10561                }
10562            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10563                String[] newArgs;
10564                String name;
10565                if (opti >= args.length) {
10566                    name = null;
10567                    newArgs = EMPTY_STRING_ARRAY;
10568                } else {
10569                    name = args[opti];
10570                    opti++;
10571                    newArgs = new String[args.length - opti];
10572                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10573                            args.length - opti);
10574                }
10575                synchronized (this) {
10576                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10577                }
10578            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10579                synchronized (this) {
10580                    dumpOomLocked(fd, pw, args, opti, true);
10581                }
10582            } else if ("provider".equals(cmd)) {
10583                String[] newArgs;
10584                String name;
10585                if (opti >= args.length) {
10586                    name = null;
10587                    newArgs = EMPTY_STRING_ARRAY;
10588                } else {
10589                    name = args[opti];
10590                    opti++;
10591                    newArgs = new String[args.length - opti];
10592                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10593                }
10594                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10595                    pw.println("No providers match: " + name);
10596                    pw.println("Use -h for help.");
10597                }
10598            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10599                synchronized (this) {
10600                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10601                }
10602            } else if ("service".equals(cmd)) {
10603                String[] newArgs;
10604                String name;
10605                if (opti >= args.length) {
10606                    name = null;
10607                    newArgs = EMPTY_STRING_ARRAY;
10608                } else {
10609                    name = args[opti];
10610                    opti++;
10611                    newArgs = new String[args.length - opti];
10612                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10613                            args.length - opti);
10614                }
10615                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10616                    pw.println("No services match: " + name);
10617                    pw.println("Use -h for help.");
10618                }
10619            } else if ("package".equals(cmd)) {
10620                String[] newArgs;
10621                if (opti >= args.length) {
10622                    pw.println("package: no package name specified");
10623                    pw.println("Use -h for help.");
10624                } else {
10625                    dumpPackage = args[opti];
10626                    opti++;
10627                    newArgs = new String[args.length - opti];
10628                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10629                            args.length - opti);
10630                    args = newArgs;
10631                    opti = 0;
10632                    more = true;
10633                }
10634            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10635                synchronized (this) {
10636                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10637                }
10638            } else {
10639                // Dumping a single activity?
10640                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10641                    pw.println("Bad activity command, or no activities match: " + cmd);
10642                    pw.println("Use -h for help.");
10643                }
10644            }
10645            if (!more) {
10646                Binder.restoreCallingIdentity(origId);
10647                return;
10648            }
10649        }
10650
10651        // No piece of data specified, dump everything.
10652        synchronized (this) {
10653            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10654            pw.println();
10655            if (dumpAll) {
10656                pw.println("-------------------------------------------------------------------------------");
10657            }
10658            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10659            pw.println();
10660            if (dumpAll) {
10661                pw.println("-------------------------------------------------------------------------------");
10662            }
10663            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10664            pw.println();
10665            if (dumpAll) {
10666                pw.println("-------------------------------------------------------------------------------");
10667            }
10668            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10669            pw.println();
10670            if (dumpAll) {
10671                pw.println("-------------------------------------------------------------------------------");
10672            }
10673            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10674            pw.println();
10675            if (dumpAll) {
10676                pw.println("-------------------------------------------------------------------------------");
10677            }
10678            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10679        }
10680        Binder.restoreCallingIdentity(origId);
10681    }
10682
10683    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10684            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10685        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10686
10687        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10688                dumpPackage);
10689        boolean needSep = printedAnything;
10690
10691        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10692                dumpPackage, needSep, "  mFocusedActivity: ");
10693        if (printed) {
10694            printedAnything = true;
10695            needSep = false;
10696        }
10697
10698        if (dumpPackage == null) {
10699            if (needSep) {
10700                pw.println();
10701            }
10702            needSep = true;
10703            printedAnything = true;
10704            mStackSupervisor.dump(pw, "  ");
10705        }
10706
10707        if (mRecentTasks.size() > 0) {
10708            boolean printedHeader = false;
10709
10710            final int N = mRecentTasks.size();
10711            for (int i=0; i<N; i++) {
10712                TaskRecord tr = mRecentTasks.get(i);
10713                if (dumpPackage != null) {
10714                    if (tr.realActivity == null ||
10715                            !dumpPackage.equals(tr.realActivity)) {
10716                        continue;
10717                    }
10718                }
10719                if (!printedHeader) {
10720                    if (needSep) {
10721                        pw.println();
10722                    }
10723                    pw.println("  Recent tasks:");
10724                    printedHeader = true;
10725                    printedAnything = true;
10726                }
10727                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10728                        pw.println(tr);
10729                if (dumpAll) {
10730                    mRecentTasks.get(i).dump(pw, "    ");
10731                }
10732            }
10733        }
10734
10735        if (!printedAnything) {
10736            pw.println("  (nothing)");
10737        }
10738    }
10739
10740    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10741            int opti, boolean dumpAll, String dumpPackage) {
10742        boolean needSep = false;
10743        boolean printedAnything = false;
10744        int numPers = 0;
10745
10746        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
10747
10748        if (dumpAll) {
10749            final int NP = mProcessNames.getMap().size();
10750            for (int ip=0; ip<NP; ip++) {
10751                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
10752                final int NA = procs.size();
10753                for (int ia=0; ia<NA; ia++) {
10754                    ProcessRecord r = procs.valueAt(ia);
10755                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10756                        continue;
10757                    }
10758                    if (!needSep) {
10759                        pw.println("  All known processes:");
10760                        needSep = true;
10761                        printedAnything = true;
10762                    }
10763                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
10764                        pw.print(" UID "); pw.print(procs.keyAt(ia));
10765                        pw.print(" "); pw.println(r);
10766                    r.dump(pw, "    ");
10767                    if (r.persistent) {
10768                        numPers++;
10769                    }
10770                }
10771            }
10772        }
10773
10774        if (mIsolatedProcesses.size() > 0) {
10775            boolean printed = false;
10776            for (int i=0; i<mIsolatedProcesses.size(); i++) {
10777                ProcessRecord r = mIsolatedProcesses.valueAt(i);
10778                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10779                    continue;
10780                }
10781                if (!printed) {
10782                    if (needSep) {
10783                        pw.println();
10784                    }
10785                    pw.println("  Isolated process list (sorted by uid):");
10786                    printedAnything = true;
10787                    printed = true;
10788                    needSep = true;
10789                }
10790                pw.println(String.format("%sIsolated #%2d: %s",
10791                        "    ", i, r.toString()));
10792            }
10793        }
10794
10795        if (mLruProcesses.size() > 0) {
10796            if (needSep) {
10797                pw.println();
10798            }
10799            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
10800                    pw.print(" total, non-act at ");
10801                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10802                    pw.print(", non-svc at ");
10803                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10804                    pw.println("):");
10805            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
10806            needSep = true;
10807            printedAnything = true;
10808        }
10809
10810        if (dumpAll || dumpPackage != null) {
10811            synchronized (mPidsSelfLocked) {
10812                boolean printed = false;
10813                for (int i=0; i<mPidsSelfLocked.size(); i++) {
10814                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
10815                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10816                        continue;
10817                    }
10818                    if (!printed) {
10819                        if (needSep) pw.println();
10820                        needSep = true;
10821                        pw.println("  PID mappings:");
10822                        printed = true;
10823                        printedAnything = true;
10824                    }
10825                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
10826                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
10827                }
10828            }
10829        }
10830
10831        if (mForegroundProcesses.size() > 0) {
10832            synchronized (mPidsSelfLocked) {
10833                boolean printed = false;
10834                for (int i=0; i<mForegroundProcesses.size(); i++) {
10835                    ProcessRecord r = mPidsSelfLocked.get(
10836                            mForegroundProcesses.valueAt(i).pid);
10837                    if (dumpPackage != null && (r == null
10838                            || !r.pkgList.containsKey(dumpPackage))) {
10839                        continue;
10840                    }
10841                    if (!printed) {
10842                        if (needSep) pw.println();
10843                        needSep = true;
10844                        pw.println("  Foreground Processes:");
10845                        printed = true;
10846                        printedAnything = true;
10847                    }
10848                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
10849                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
10850                }
10851            }
10852        }
10853
10854        if (mPersistentStartingProcesses.size() > 0) {
10855            if (needSep) pw.println();
10856            needSep = true;
10857            printedAnything = true;
10858            pw.println("  Persisent processes that are starting:");
10859            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
10860                    "Starting Norm", "Restarting PERS", dumpPackage);
10861        }
10862
10863        if (mRemovedProcesses.size() > 0) {
10864            if (needSep) pw.println();
10865            needSep = true;
10866            printedAnything = true;
10867            pw.println("  Processes that are being removed:");
10868            dumpProcessList(pw, this, mRemovedProcesses, "    ",
10869                    "Removed Norm", "Removed PERS", dumpPackage);
10870        }
10871
10872        if (mProcessesOnHold.size() > 0) {
10873            if (needSep) pw.println();
10874            needSep = true;
10875            printedAnything = true;
10876            pw.println("  Processes that are on old until the system is ready:");
10877            dumpProcessList(pw, this, mProcessesOnHold, "    ",
10878                    "OnHold Norm", "OnHold PERS", dumpPackage);
10879        }
10880
10881        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
10882
10883        if (mProcessCrashTimes.getMap().size() > 0) {
10884            boolean printed = false;
10885            long now = SystemClock.uptimeMillis();
10886            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
10887            final int NP = pmap.size();
10888            for (int ip=0; ip<NP; ip++) {
10889                String pname = pmap.keyAt(ip);
10890                SparseArray<Long> uids = pmap.valueAt(ip);
10891                final int N = uids.size();
10892                for (int i=0; i<N; i++) {
10893                    int puid = uids.keyAt(i);
10894                    ProcessRecord r = mProcessNames.get(pname, puid);
10895                    if (dumpPackage != null && (r == null
10896                            || !r.pkgList.containsKey(dumpPackage))) {
10897                        continue;
10898                    }
10899                    if (!printed) {
10900                        if (needSep) pw.println();
10901                        needSep = true;
10902                        pw.println("  Time since processes crashed:");
10903                        printed = true;
10904                        printedAnything = true;
10905                    }
10906                    pw.print("    Process "); pw.print(pname);
10907                            pw.print(" uid "); pw.print(puid);
10908                            pw.print(": last crashed ");
10909                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
10910                            pw.println(" ago");
10911                }
10912            }
10913        }
10914
10915        if (mBadProcesses.getMap().size() > 0) {
10916            boolean printed = false;
10917            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
10918            final int NP = pmap.size();
10919            for (int ip=0; ip<NP; ip++) {
10920                String pname = pmap.keyAt(ip);
10921                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
10922                final int N = uids.size();
10923                for (int i=0; i<N; i++) {
10924                    int puid = uids.keyAt(i);
10925                    ProcessRecord r = mProcessNames.get(pname, puid);
10926                    if (dumpPackage != null && (r == null
10927                            || !r.pkgList.containsKey(dumpPackage))) {
10928                        continue;
10929                    }
10930                    if (!printed) {
10931                        if (needSep) pw.println();
10932                        needSep = true;
10933                        pw.println("  Bad processes:");
10934                        printedAnything = true;
10935                    }
10936                    BadProcessInfo info = uids.valueAt(i);
10937                    pw.print("    Bad process "); pw.print(pname);
10938                            pw.print(" uid "); pw.print(puid);
10939                            pw.print(": crashed at time "); pw.println(info.time);
10940                    if (info.shortMsg != null) {
10941                        pw.print("      Short msg: "); pw.println(info.shortMsg);
10942                    }
10943                    if (info.longMsg != null) {
10944                        pw.print("      Long msg: "); pw.println(info.longMsg);
10945                    }
10946                    if (info.stack != null) {
10947                        pw.println("      Stack:");
10948                        int lastPos = 0;
10949                        for (int pos=0; pos<info.stack.length(); pos++) {
10950                            if (info.stack.charAt(pos) == '\n') {
10951                                pw.print("        ");
10952                                pw.write(info.stack, lastPos, pos-lastPos);
10953                                pw.println();
10954                                lastPos = pos+1;
10955                            }
10956                        }
10957                        if (lastPos < info.stack.length()) {
10958                            pw.print("        ");
10959                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
10960                            pw.println();
10961                        }
10962                    }
10963                }
10964            }
10965        }
10966
10967        if (dumpPackage == null) {
10968            pw.println();
10969            needSep = false;
10970            pw.println("  mStartedUsers:");
10971            for (int i=0; i<mStartedUsers.size(); i++) {
10972                UserStartedState uss = mStartedUsers.valueAt(i);
10973                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
10974                        pw.print(": "); uss.dump("", pw);
10975            }
10976            pw.print("  mStartedUserArray: [");
10977            for (int i=0; i<mStartedUserArray.length; i++) {
10978                if (i > 0) pw.print(", ");
10979                pw.print(mStartedUserArray[i]);
10980            }
10981            pw.println("]");
10982            pw.print("  mUserLru: [");
10983            for (int i=0; i<mUserLru.size(); i++) {
10984                if (i > 0) pw.print(", ");
10985                pw.print(mUserLru.get(i));
10986            }
10987            pw.println("]");
10988            if (dumpAll) {
10989                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
10990            }
10991        }
10992        if (mHomeProcess != null && (dumpPackage == null
10993                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
10994            if (needSep) {
10995                pw.println();
10996                needSep = false;
10997            }
10998            pw.println("  mHomeProcess: " + mHomeProcess);
10999        }
11000        if (mPreviousProcess != null && (dumpPackage == null
11001                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11002            if (needSep) {
11003                pw.println();
11004                needSep = false;
11005            }
11006            pw.println("  mPreviousProcess: " + mPreviousProcess);
11007        }
11008        if (dumpAll) {
11009            StringBuilder sb = new StringBuilder(128);
11010            sb.append("  mPreviousProcessVisibleTime: ");
11011            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11012            pw.println(sb);
11013        }
11014        if (mHeavyWeightProcess != null && (dumpPackage == null
11015                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11016            if (needSep) {
11017                pw.println();
11018                needSep = false;
11019            }
11020            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11021        }
11022        if (dumpPackage == null) {
11023            pw.println("  mConfiguration: " + mConfiguration);
11024        }
11025        if (dumpAll) {
11026            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11027            if (mCompatModePackages.getPackages().size() > 0) {
11028                boolean printed = false;
11029                for (Map.Entry<String, Integer> entry
11030                        : mCompatModePackages.getPackages().entrySet()) {
11031                    String pkg = entry.getKey();
11032                    int mode = entry.getValue();
11033                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11034                        continue;
11035                    }
11036                    if (!printed) {
11037                        pw.println("  mScreenCompatPackages:");
11038                        printed = true;
11039                    }
11040                    pw.print("    "); pw.print(pkg); pw.print(": ");
11041                            pw.print(mode); pw.println();
11042                }
11043            }
11044        }
11045        if (dumpPackage == null) {
11046            if (mSleeping || mWentToSleep || mLockScreenShown) {
11047                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11048                        + " mLockScreenShown " + mLockScreenShown);
11049            }
11050            if (mShuttingDown) {
11051                pw.println("  mShuttingDown=" + mShuttingDown);
11052            }
11053        }
11054        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11055                || mOrigWaitForDebugger) {
11056            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11057                    || dumpPackage.equals(mOrigDebugApp)) {
11058                if (needSep) {
11059                    pw.println();
11060                    needSep = false;
11061                }
11062                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11063                        + " mDebugTransient=" + mDebugTransient
11064                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11065            }
11066        }
11067        if (mOpenGlTraceApp != null) {
11068            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11069                if (needSep) {
11070                    pw.println();
11071                    needSep = false;
11072                }
11073                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11074            }
11075        }
11076        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11077                || mProfileFd != null) {
11078            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11079                if (needSep) {
11080                    pw.println();
11081                    needSep = false;
11082                }
11083                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11084                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11085                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11086                        + mAutoStopProfiler);
11087            }
11088        }
11089        if (dumpPackage == null) {
11090            if (mAlwaysFinishActivities || mController != null) {
11091                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11092                        + " mController=" + mController);
11093            }
11094            if (dumpAll) {
11095                pw.println("  Total persistent processes: " + numPers);
11096                pw.println("  mStartRunning=" + mStartRunning
11097                        + " mProcessesReady=" + mProcessesReady
11098                        + " mSystemReady=" + mSystemReady);
11099                pw.println("  mBooting=" + mBooting
11100                        + " mBooted=" + mBooted
11101                        + " mFactoryTest=" + mFactoryTest);
11102                pw.print("  mLastPowerCheckRealtime=");
11103                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11104                        pw.println("");
11105                pw.print("  mLastPowerCheckUptime=");
11106                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11107                        pw.println("");
11108                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11109                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11110                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11111                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11112                        + " (" + mLruProcesses.size() + " total)"
11113                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11114                        + " mNumServiceProcs=" + mNumServiceProcs
11115                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11116                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11117                        + " mLastMemoryLevel" + mLastMemoryLevel
11118                        + " mLastNumProcesses" + mLastNumProcesses);
11119                long now = SystemClock.uptimeMillis();
11120                pw.print("  mLastIdleTime=");
11121                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11122                        pw.print(" mLowRamSinceLastIdle=");
11123                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11124                        pw.println();
11125            }
11126        }
11127
11128        if (!printedAnything) {
11129            pw.println("  (nothing)");
11130        }
11131    }
11132
11133    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11134            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11135        if (mProcessesToGc.size() > 0) {
11136            boolean printed = false;
11137            long now = SystemClock.uptimeMillis();
11138            for (int i=0; i<mProcessesToGc.size(); i++) {
11139                ProcessRecord proc = mProcessesToGc.get(i);
11140                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11141                    continue;
11142                }
11143                if (!printed) {
11144                    if (needSep) pw.println();
11145                    needSep = true;
11146                    pw.println("  Processes that are waiting to GC:");
11147                    printed = true;
11148                }
11149                pw.print("    Process "); pw.println(proc);
11150                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11151                        pw.print(", last gced=");
11152                        pw.print(now-proc.lastRequestedGc);
11153                        pw.print(" ms ago, last lowMem=");
11154                        pw.print(now-proc.lastLowMemory);
11155                        pw.println(" ms ago");
11156
11157            }
11158        }
11159        return needSep;
11160    }
11161
11162    void printOomLevel(PrintWriter pw, String name, int adj) {
11163        pw.print("    ");
11164        if (adj >= 0) {
11165            pw.print(' ');
11166            if (adj < 10) pw.print(' ');
11167        } else {
11168            if (adj > -10) pw.print(' ');
11169        }
11170        pw.print(adj);
11171        pw.print(": ");
11172        pw.print(name);
11173        pw.print(" (");
11174        pw.print(mProcessList.getMemLevel(adj)/1024);
11175        pw.println(" kB)");
11176    }
11177
11178    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11179            int opti, boolean dumpAll) {
11180        boolean needSep = false;
11181
11182        if (mLruProcesses.size() > 0) {
11183            if (needSep) pw.println();
11184            needSep = true;
11185            pw.println("  OOM levels:");
11186            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11187            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11188            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11189            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11190            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11191            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11192            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11193            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11194            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11195            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11196            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11197            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11198            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11199
11200            if (needSep) pw.println();
11201            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11202                    pw.print(" total, non-act at ");
11203                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11204                    pw.print(", non-svc at ");
11205                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11206                    pw.println("):");
11207            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11208            needSep = true;
11209        }
11210
11211        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11212
11213        pw.println();
11214        pw.println("  mHomeProcess: " + mHomeProcess);
11215        pw.println("  mPreviousProcess: " + mPreviousProcess);
11216        if (mHeavyWeightProcess != null) {
11217            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11218        }
11219
11220        return true;
11221    }
11222
11223    /**
11224     * There are three ways to call this:
11225     *  - no provider specified: dump all the providers
11226     *  - a flattened component name that matched an existing provider was specified as the
11227     *    first arg: dump that one provider
11228     *  - the first arg isn't the flattened component name of an existing provider:
11229     *    dump all providers whose component contains the first arg as a substring
11230     */
11231    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11232            int opti, boolean dumpAll) {
11233        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11234    }
11235
11236    static class ItemMatcher {
11237        ArrayList<ComponentName> components;
11238        ArrayList<String> strings;
11239        ArrayList<Integer> objects;
11240        boolean all;
11241
11242        ItemMatcher() {
11243            all = true;
11244        }
11245
11246        void build(String name) {
11247            ComponentName componentName = ComponentName.unflattenFromString(name);
11248            if (componentName != null) {
11249                if (components == null) {
11250                    components = new ArrayList<ComponentName>();
11251                }
11252                components.add(componentName);
11253                all = false;
11254            } else {
11255                int objectId = 0;
11256                // Not a '/' separated full component name; maybe an object ID?
11257                try {
11258                    objectId = Integer.parseInt(name, 16);
11259                    if (objects == null) {
11260                        objects = new ArrayList<Integer>();
11261                    }
11262                    objects.add(objectId);
11263                    all = false;
11264                } catch (RuntimeException e) {
11265                    // Not an integer; just do string match.
11266                    if (strings == null) {
11267                        strings = new ArrayList<String>();
11268                    }
11269                    strings.add(name);
11270                    all = false;
11271                }
11272            }
11273        }
11274
11275        int build(String[] args, int opti) {
11276            for (; opti<args.length; opti++) {
11277                String name = args[opti];
11278                if ("--".equals(name)) {
11279                    return opti+1;
11280                }
11281                build(name);
11282            }
11283            return opti;
11284        }
11285
11286        boolean match(Object object, ComponentName comp) {
11287            if (all) {
11288                return true;
11289            }
11290            if (components != null) {
11291                for (int i=0; i<components.size(); i++) {
11292                    if (components.get(i).equals(comp)) {
11293                        return true;
11294                    }
11295                }
11296            }
11297            if (objects != null) {
11298                for (int i=0; i<objects.size(); i++) {
11299                    if (System.identityHashCode(object) == objects.get(i)) {
11300                        return true;
11301                    }
11302                }
11303            }
11304            if (strings != null) {
11305                String flat = comp.flattenToString();
11306                for (int i=0; i<strings.size(); i++) {
11307                    if (flat.contains(strings.get(i))) {
11308                        return true;
11309                    }
11310                }
11311            }
11312            return false;
11313        }
11314    }
11315
11316    /**
11317     * There are three things that cmd can be:
11318     *  - a flattened component name that matches an existing activity
11319     *  - the cmd arg isn't the flattened component name of an existing activity:
11320     *    dump all activity whose component contains the cmd as a substring
11321     *  - A hex number of the ActivityRecord object instance.
11322     */
11323    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11324            int opti, boolean dumpAll) {
11325        ArrayList<ActivityRecord> activities;
11326
11327        synchronized (this) {
11328            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11329        }
11330
11331        if (activities.size() <= 0) {
11332            return false;
11333        }
11334
11335        String[] newArgs = new String[args.length - opti];
11336        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11337
11338        TaskRecord lastTask = null;
11339        boolean needSep = false;
11340        for (int i=activities.size()-1; i>=0; i--) {
11341            ActivityRecord r = activities.get(i);
11342            if (needSep) {
11343                pw.println();
11344            }
11345            needSep = true;
11346            synchronized (this) {
11347                if (lastTask != r.task) {
11348                    lastTask = r.task;
11349                    pw.print("TASK "); pw.print(lastTask.affinity);
11350                            pw.print(" id="); pw.println(lastTask.taskId);
11351                    if (dumpAll) {
11352                        lastTask.dump(pw, "  ");
11353                    }
11354                }
11355            }
11356            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11357        }
11358        return true;
11359    }
11360
11361    /**
11362     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11363     * there is a thread associated with the activity.
11364     */
11365    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11366            final ActivityRecord r, String[] args, boolean dumpAll) {
11367        String innerPrefix = prefix + "  ";
11368        synchronized (this) {
11369            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11370                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11371                    pw.print(" pid=");
11372                    if (r.app != null) pw.println(r.app.pid);
11373                    else pw.println("(not running)");
11374            if (dumpAll) {
11375                r.dump(pw, innerPrefix);
11376            }
11377        }
11378        if (r.app != null && r.app.thread != null) {
11379            // flush anything that is already in the PrintWriter since the thread is going
11380            // to write to the file descriptor directly
11381            pw.flush();
11382            try {
11383                TransferPipe tp = new TransferPipe();
11384                try {
11385                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11386                            r.appToken, innerPrefix, args);
11387                    tp.go(fd);
11388                } finally {
11389                    tp.kill();
11390                }
11391            } catch (IOException e) {
11392                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11393            } catch (RemoteException e) {
11394                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11395            }
11396        }
11397    }
11398
11399    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11400            int opti, boolean dumpAll, String dumpPackage) {
11401        boolean needSep = false;
11402        boolean onlyHistory = false;
11403        boolean printedAnything = false;
11404
11405        if ("history".equals(dumpPackage)) {
11406            if (opti < args.length && "-s".equals(args[opti])) {
11407                dumpAll = false;
11408            }
11409            onlyHistory = true;
11410            dumpPackage = null;
11411        }
11412
11413        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11414        if (!onlyHistory && dumpAll) {
11415            if (mRegisteredReceivers.size() > 0) {
11416                boolean printed = false;
11417                Iterator it = mRegisteredReceivers.values().iterator();
11418                while (it.hasNext()) {
11419                    ReceiverList r = (ReceiverList)it.next();
11420                    if (dumpPackage != null && (r.app == null ||
11421                            !dumpPackage.equals(r.app.info.packageName))) {
11422                        continue;
11423                    }
11424                    if (!printed) {
11425                        pw.println("  Registered Receivers:");
11426                        needSep = true;
11427                        printed = true;
11428                        printedAnything = true;
11429                    }
11430                    pw.print("  * "); pw.println(r);
11431                    r.dump(pw, "    ");
11432                }
11433            }
11434
11435            if (mReceiverResolver.dump(pw, needSep ?
11436                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11437                    "    ", dumpPackage, false)) {
11438                needSep = true;
11439                printedAnything = true;
11440            }
11441        }
11442
11443        for (BroadcastQueue q : mBroadcastQueues) {
11444            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11445            printedAnything |= needSep;
11446        }
11447
11448        needSep = true;
11449
11450        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11451            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11452                if (needSep) {
11453                    pw.println();
11454                }
11455                needSep = true;
11456                printedAnything = true;
11457                pw.print("  Sticky broadcasts for user ");
11458                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11459                StringBuilder sb = new StringBuilder(128);
11460                for (Map.Entry<String, ArrayList<Intent>> ent
11461                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11462                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11463                    if (dumpAll) {
11464                        pw.println(":");
11465                        ArrayList<Intent> intents = ent.getValue();
11466                        final int N = intents.size();
11467                        for (int i=0; i<N; i++) {
11468                            sb.setLength(0);
11469                            sb.append("    Intent: ");
11470                            intents.get(i).toShortString(sb, false, true, false, false);
11471                            pw.println(sb.toString());
11472                            Bundle bundle = intents.get(i).getExtras();
11473                            if (bundle != null) {
11474                                pw.print("      ");
11475                                pw.println(bundle.toString());
11476                            }
11477                        }
11478                    } else {
11479                        pw.println("");
11480                    }
11481                }
11482            }
11483        }
11484
11485        if (!onlyHistory && dumpAll) {
11486            pw.println();
11487            for (BroadcastQueue queue : mBroadcastQueues) {
11488                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11489                        + queue.mBroadcastsScheduled);
11490            }
11491            pw.println("  mHandler:");
11492            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11493            needSep = true;
11494            printedAnything = true;
11495        }
11496
11497        if (!printedAnything) {
11498            pw.println("  (nothing)");
11499        }
11500    }
11501
11502    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11503            int opti, boolean dumpAll, String dumpPackage) {
11504        boolean needSep;
11505        boolean printedAnything = false;
11506
11507        ItemMatcher matcher = new ItemMatcher();
11508        matcher.build(args, opti);
11509
11510        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11511
11512        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11513        printedAnything |= needSep;
11514
11515        if (mLaunchingProviders.size() > 0) {
11516            boolean printed = false;
11517            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11518                ContentProviderRecord r = mLaunchingProviders.get(i);
11519                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11520                    continue;
11521                }
11522                if (!printed) {
11523                    if (needSep) pw.println();
11524                    needSep = true;
11525                    pw.println("  Launching content providers:");
11526                    printed = true;
11527                    printedAnything = true;
11528                }
11529                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11530                        pw.println(r);
11531            }
11532        }
11533
11534        if (mGrantedUriPermissions.size() > 0) {
11535            boolean printed = false;
11536            int dumpUid = -2;
11537            if (dumpPackage != null) {
11538                try {
11539                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11540                } catch (NameNotFoundException e) {
11541                    dumpUid = -1;
11542                }
11543            }
11544            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11545                int uid = mGrantedUriPermissions.keyAt(i);
11546                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11547                    continue;
11548                }
11549                ArrayMap<Uri, UriPermission> perms
11550                        = mGrantedUriPermissions.valueAt(i);
11551                if (!printed) {
11552                    if (needSep) pw.println();
11553                    needSep = true;
11554                    pw.println("  Granted Uri Permissions:");
11555                    printed = true;
11556                    printedAnything = true;
11557                }
11558                pw.print("  * UID "); pw.print(uid);
11559                        pw.println(" holds:");
11560                for (UriPermission perm : perms.values()) {
11561                    pw.print("    "); pw.println(perm);
11562                    if (dumpAll) {
11563                        perm.dump(pw, "      ");
11564                    }
11565                }
11566            }
11567        }
11568
11569        if (!printedAnything) {
11570            pw.println("  (nothing)");
11571        }
11572    }
11573
11574    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11575            int opti, boolean dumpAll, String dumpPackage) {
11576        boolean printed = false;
11577
11578        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11579
11580        if (mIntentSenderRecords.size() > 0) {
11581            Iterator<WeakReference<PendingIntentRecord>> it
11582                    = mIntentSenderRecords.values().iterator();
11583            while (it.hasNext()) {
11584                WeakReference<PendingIntentRecord> ref = it.next();
11585                PendingIntentRecord rec = ref != null ? ref.get(): null;
11586                if (dumpPackage != null && (rec == null
11587                        || !dumpPackage.equals(rec.key.packageName))) {
11588                    continue;
11589                }
11590                printed = true;
11591                if (rec != null) {
11592                    pw.print("  * "); pw.println(rec);
11593                    if (dumpAll) {
11594                        rec.dump(pw, "    ");
11595                    }
11596                } else {
11597                    pw.print("  * "); pw.println(ref);
11598                }
11599            }
11600        }
11601
11602        if (!printed) {
11603            pw.println("  (nothing)");
11604        }
11605    }
11606
11607    private static final int dumpProcessList(PrintWriter pw,
11608            ActivityManagerService service, List list,
11609            String prefix, String normalLabel, String persistentLabel,
11610            String dumpPackage) {
11611        int numPers = 0;
11612        final int N = list.size()-1;
11613        for (int i=N; i>=0; i--) {
11614            ProcessRecord r = (ProcessRecord)list.get(i);
11615            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11616                continue;
11617            }
11618            pw.println(String.format("%s%s #%2d: %s",
11619                    prefix, (r.persistent ? persistentLabel : normalLabel),
11620                    i, r.toString()));
11621            if (r.persistent) {
11622                numPers++;
11623            }
11624        }
11625        return numPers;
11626    }
11627
11628    private static final boolean dumpProcessOomList(PrintWriter pw,
11629            ActivityManagerService service, List<ProcessRecord> origList,
11630            String prefix, String normalLabel, String persistentLabel,
11631            boolean inclDetails, String dumpPackage) {
11632
11633        ArrayList<Pair<ProcessRecord, Integer>> list
11634                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11635        for (int i=0; i<origList.size(); i++) {
11636            ProcessRecord r = origList.get(i);
11637            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11638                continue;
11639            }
11640            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11641        }
11642
11643        if (list.size() <= 0) {
11644            return false;
11645        }
11646
11647        Comparator<Pair<ProcessRecord, Integer>> comparator
11648                = new Comparator<Pair<ProcessRecord, Integer>>() {
11649            @Override
11650            public int compare(Pair<ProcessRecord, Integer> object1,
11651                    Pair<ProcessRecord, Integer> object2) {
11652                if (object1.first.setAdj != object2.first.setAdj) {
11653                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11654                }
11655                if (object1.second.intValue() != object2.second.intValue()) {
11656                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11657                }
11658                return 0;
11659            }
11660        };
11661
11662        Collections.sort(list, comparator);
11663
11664        final long curRealtime = SystemClock.elapsedRealtime();
11665        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11666        final long curUptime = SystemClock.uptimeMillis();
11667        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11668
11669        for (int i=list.size()-1; i>=0; i--) {
11670            ProcessRecord r = list.get(i).first;
11671            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11672            char schedGroup;
11673            switch (r.setSchedGroup) {
11674                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11675                    schedGroup = 'B';
11676                    break;
11677                case Process.THREAD_GROUP_DEFAULT:
11678                    schedGroup = 'F';
11679                    break;
11680                default:
11681                    schedGroup = '?';
11682                    break;
11683            }
11684            char foreground;
11685            if (r.foregroundActivities) {
11686                foreground = 'A';
11687            } else if (r.foregroundServices) {
11688                foreground = 'S';
11689            } else {
11690                foreground = ' ';
11691            }
11692            String procState = ProcessList.makeProcStateString(r.curProcState);
11693            pw.print(prefix);
11694            pw.print(r.persistent ? persistentLabel : normalLabel);
11695            pw.print(" #");
11696            int num = (origList.size()-1)-list.get(i).second;
11697            if (num < 10) pw.print(' ');
11698            pw.print(num);
11699            pw.print(": ");
11700            pw.print(oomAdj);
11701            pw.print(' ');
11702            pw.print(schedGroup);
11703            pw.print('/');
11704            pw.print(foreground);
11705            pw.print('/');
11706            pw.print(procState);
11707            pw.print(" trm:");
11708            if (r.trimMemoryLevel < 10) pw.print(' ');
11709            pw.print(r.trimMemoryLevel);
11710            pw.print(' ');
11711            pw.print(r.toShortString());
11712            pw.print(" (");
11713            pw.print(r.adjType);
11714            pw.println(')');
11715            if (r.adjSource != null || r.adjTarget != null) {
11716                pw.print(prefix);
11717                pw.print("    ");
11718                if (r.adjTarget instanceof ComponentName) {
11719                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11720                } else if (r.adjTarget != null) {
11721                    pw.print(r.adjTarget.toString());
11722                } else {
11723                    pw.print("{null}");
11724                }
11725                pw.print("<=");
11726                if (r.adjSource instanceof ProcessRecord) {
11727                    pw.print("Proc{");
11728                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11729                    pw.println("}");
11730                } else if (r.adjSource != null) {
11731                    pw.println(r.adjSource.toString());
11732                } else {
11733                    pw.println("{null}");
11734                }
11735            }
11736            if (inclDetails) {
11737                pw.print(prefix);
11738                pw.print("    ");
11739                pw.print("oom: max="); pw.print(r.maxAdj);
11740                pw.print(" curRaw="); pw.print(r.curRawAdj);
11741                pw.print(" setRaw="); pw.print(r.setRawAdj);
11742                pw.print(" cur="); pw.print(r.curAdj);
11743                pw.print(" set="); pw.println(r.setAdj);
11744                pw.print(prefix);
11745                pw.print("    ");
11746                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
11747                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
11748                pw.print(" lastPss="); pw.print(r.lastPss);
11749                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
11750                pw.print(prefix);
11751                pw.print("    ");
11752                pw.print("keeping="); pw.print(r.keeping);
11753                pw.print(" cached="); pw.print(r.cached);
11754                pw.print(" empty="); pw.print(r.empty);
11755                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
11756
11757                if (!r.keeping) {
11758                    if (r.lastWakeTime != 0) {
11759                        long wtime;
11760                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
11761                        synchronized (stats) {
11762                            wtime = stats.getProcessWakeTime(r.info.uid,
11763                                    r.pid, curRealtime);
11764                        }
11765                        long timeUsed = wtime - r.lastWakeTime;
11766                        pw.print(prefix);
11767                        pw.print("    ");
11768                        pw.print("keep awake over ");
11769                        TimeUtils.formatDuration(realtimeSince, pw);
11770                        pw.print(" used ");
11771                        TimeUtils.formatDuration(timeUsed, pw);
11772                        pw.print(" (");
11773                        pw.print((timeUsed*100)/realtimeSince);
11774                        pw.println("%)");
11775                    }
11776                    if (r.lastCpuTime != 0) {
11777                        long timeUsed = r.curCpuTime - r.lastCpuTime;
11778                        pw.print(prefix);
11779                        pw.print("    ");
11780                        pw.print("run cpu over ");
11781                        TimeUtils.formatDuration(uptimeSince, pw);
11782                        pw.print(" used ");
11783                        TimeUtils.formatDuration(timeUsed, pw);
11784                        pw.print(" (");
11785                        pw.print((timeUsed*100)/uptimeSince);
11786                        pw.println("%)");
11787                    }
11788                }
11789            }
11790        }
11791        return true;
11792    }
11793
11794    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
11795        ArrayList<ProcessRecord> procs;
11796        synchronized (this) {
11797            if (args != null && args.length > start
11798                    && args[start].charAt(0) != '-') {
11799                procs = new ArrayList<ProcessRecord>();
11800                int pid = -1;
11801                try {
11802                    pid = Integer.parseInt(args[start]);
11803                } catch (NumberFormatException e) {
11804                }
11805                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11806                    ProcessRecord proc = mLruProcesses.get(i);
11807                    if (proc.pid == pid) {
11808                        procs.add(proc);
11809                    } else if (proc.processName.equals(args[start])) {
11810                        procs.add(proc);
11811                    }
11812                }
11813                if (procs.size() <= 0) {
11814                    return null;
11815                }
11816            } else {
11817                procs = new ArrayList<ProcessRecord>(mLruProcesses);
11818            }
11819        }
11820        return procs;
11821    }
11822
11823    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
11824            PrintWriter pw, String[] args) {
11825        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11826        if (procs == null) {
11827            pw.println("No process found for: " + args[0]);
11828            return;
11829        }
11830
11831        long uptime = SystemClock.uptimeMillis();
11832        long realtime = SystemClock.elapsedRealtime();
11833        pw.println("Applications Graphics Acceleration Info:");
11834        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11835
11836        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11837            ProcessRecord r = procs.get(i);
11838            if (r.thread != null) {
11839                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
11840                pw.flush();
11841                try {
11842                    TransferPipe tp = new TransferPipe();
11843                    try {
11844                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
11845                        tp.go(fd);
11846                    } finally {
11847                        tp.kill();
11848                    }
11849                } catch (IOException e) {
11850                    pw.println("Failure while dumping the app: " + r);
11851                    pw.flush();
11852                } catch (RemoteException e) {
11853                    pw.println("Got a RemoteException while dumping the app " + r);
11854                    pw.flush();
11855                }
11856            }
11857        }
11858    }
11859
11860    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
11861        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11862        if (procs == null) {
11863            pw.println("No process found for: " + args[0]);
11864            return;
11865        }
11866
11867        pw.println("Applications Database Info:");
11868
11869        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11870            ProcessRecord r = procs.get(i);
11871            if (r.thread != null) {
11872                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
11873                pw.flush();
11874                try {
11875                    TransferPipe tp = new TransferPipe();
11876                    try {
11877                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
11878                        tp.go(fd);
11879                    } finally {
11880                        tp.kill();
11881                    }
11882                } catch (IOException e) {
11883                    pw.println("Failure while dumping the app: " + r);
11884                    pw.flush();
11885                } catch (RemoteException e) {
11886                    pw.println("Got a RemoteException while dumping the app " + r);
11887                    pw.flush();
11888                }
11889            }
11890        }
11891    }
11892
11893    final static class MemItem {
11894        final boolean isProc;
11895        final String label;
11896        final String shortLabel;
11897        final long pss;
11898        final int id;
11899        final boolean hasActivities;
11900        ArrayList<MemItem> subitems;
11901
11902        public MemItem(String _label, String _shortLabel, long _pss, int _id,
11903                boolean _hasActivities) {
11904            isProc = true;
11905            label = _label;
11906            shortLabel = _shortLabel;
11907            pss = _pss;
11908            id = _id;
11909            hasActivities = _hasActivities;
11910        }
11911
11912        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
11913            isProc = false;
11914            label = _label;
11915            shortLabel = _shortLabel;
11916            pss = _pss;
11917            id = _id;
11918            hasActivities = false;
11919        }
11920    }
11921
11922    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
11923            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
11924        if (sort && !isCompact) {
11925            Collections.sort(items, new Comparator<MemItem>() {
11926                @Override
11927                public int compare(MemItem lhs, MemItem rhs) {
11928                    if (lhs.pss < rhs.pss) {
11929                        return 1;
11930                    } else if (lhs.pss > rhs.pss) {
11931                        return -1;
11932                    }
11933                    return 0;
11934                }
11935            });
11936        }
11937
11938        for (int i=0; i<items.size(); i++) {
11939            MemItem mi = items.get(i);
11940            if (!isCompact) {
11941                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
11942            } else if (mi.isProc) {
11943                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
11944                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
11945                pw.println(mi.hasActivities ? ",a" : ",e");
11946            } else {
11947                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
11948                pw.println(mi.pss);
11949            }
11950            if (mi.subitems != null) {
11951                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
11952                        true, isCompact);
11953            }
11954        }
11955    }
11956
11957    // These are in KB.
11958    static final long[] DUMP_MEM_BUCKETS = new long[] {
11959        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
11960        120*1024, 160*1024, 200*1024,
11961        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
11962        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
11963    };
11964
11965    static final void appendMemBucket(StringBuilder out, long memKB, String label,
11966            boolean stackLike) {
11967        int start = label.lastIndexOf('.');
11968        if (start >= 0) start++;
11969        else start = 0;
11970        int end = label.length();
11971        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
11972            if (DUMP_MEM_BUCKETS[i] >= memKB) {
11973                long bucket = DUMP_MEM_BUCKETS[i]/1024;
11974                out.append(bucket);
11975                out.append(stackLike ? "MB." : "MB ");
11976                out.append(label, start, end);
11977                return;
11978            }
11979        }
11980        out.append(memKB/1024);
11981        out.append(stackLike ? "MB." : "MB ");
11982        out.append(label, start, end);
11983    }
11984
11985    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
11986            ProcessList.NATIVE_ADJ,
11987            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
11988            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
11989            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
11990            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
11991            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
11992    };
11993    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
11994            "Native",
11995            "System", "Persistent", "Foreground",
11996            "Visible", "Perceptible",
11997            "Heavy Weight", "Backup",
11998            "A Services", "Home",
11999            "Previous", "B Services", "Cached"
12000    };
12001    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12002            "native",
12003            "sys", "pers", "fore",
12004            "vis", "percept",
12005            "heavy", "backup",
12006            "servicea", "home",
12007            "prev", "serviceb", "cached"
12008    };
12009
12010    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12011            long realtime, boolean isCheckinRequest, boolean isCompact) {
12012        if (isCheckinRequest || isCompact) {
12013            // short checkin version
12014            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12015        } else {
12016            pw.println("Applications Memory Usage (kB):");
12017            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12018        }
12019    }
12020
12021    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12022            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12023        boolean dumpDetails = false;
12024        boolean dumpFullDetails = false;
12025        boolean dumpDalvik = false;
12026        boolean oomOnly = false;
12027        boolean isCompact = false;
12028        boolean localOnly = false;
12029
12030        int opti = 0;
12031        while (opti < args.length) {
12032            String opt = args[opti];
12033            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12034                break;
12035            }
12036            opti++;
12037            if ("-a".equals(opt)) {
12038                dumpDetails = true;
12039                dumpFullDetails = true;
12040                dumpDalvik = true;
12041            } else if ("-d".equals(opt)) {
12042                dumpDalvik = true;
12043            } else if ("-c".equals(opt)) {
12044                isCompact = true;
12045            } else if ("--oom".equals(opt)) {
12046                oomOnly = true;
12047            } else if ("--local".equals(opt)) {
12048                localOnly = true;
12049            } else if ("-h".equals(opt)) {
12050                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12051                pw.println("  -a: include all available information for each process.");
12052                pw.println("  -d: include dalvik details when dumping process details.");
12053                pw.println("  -c: dump in a compact machine-parseable representation.");
12054                pw.println("  --oom: only show processes organized by oom adj.");
12055                pw.println("  --local: only collect details locally, don't call process.");
12056                pw.println("If [process] is specified it can be the name or ");
12057                pw.println("pid of a specific process to dump.");
12058                return;
12059            } else {
12060                pw.println("Unknown argument: " + opt + "; use -h for help");
12061            }
12062        }
12063
12064        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12065        long uptime = SystemClock.uptimeMillis();
12066        long realtime = SystemClock.elapsedRealtime();
12067        final long[] tmpLong = new long[1];
12068
12069        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12070        if (procs == null) {
12071            // No Java processes.  Maybe they want to print a native process.
12072            if (args != null && args.length > opti
12073                    && args[opti].charAt(0) != '-') {
12074                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12075                        = new ArrayList<ProcessCpuTracker.Stats>();
12076                updateCpuStatsNow();
12077                int findPid = -1;
12078                try {
12079                    findPid = Integer.parseInt(args[opti]);
12080                } catch (NumberFormatException e) {
12081                }
12082                synchronized (mProcessCpuThread) {
12083                    final int N = mProcessCpuTracker.countStats();
12084                    for (int i=0; i<N; i++) {
12085                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12086                        if (st.pid == findPid || (st.baseName != null
12087                                && st.baseName.equals(args[opti]))) {
12088                            nativeProcs.add(st);
12089                        }
12090                    }
12091                }
12092                if (nativeProcs.size() > 0) {
12093                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12094                            isCompact);
12095                    Debug.MemoryInfo mi = null;
12096                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12097                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12098                        final int pid = r.pid;
12099                        if (!isCheckinRequest && dumpDetails) {
12100                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12101                        }
12102                        if (mi == null) {
12103                            mi = new Debug.MemoryInfo();
12104                        }
12105                        if (dumpDetails || (!brief && !oomOnly)) {
12106                            Debug.getMemoryInfo(pid, mi);
12107                        } else {
12108                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12109                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12110                        }
12111                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12112                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12113                        if (isCheckinRequest) {
12114                            pw.println();
12115                        }
12116                    }
12117                    return;
12118                }
12119            }
12120            pw.println("No process found for: " + args[opti]);
12121            return;
12122        }
12123
12124        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12125            dumpDetails = true;
12126        }
12127
12128        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12129
12130        String[] innerArgs = new String[args.length-opti];
12131        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12132
12133        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12134        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12135        long nativePss=0, dalvikPss=0, otherPss=0;
12136        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12137
12138        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12139        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12140                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12141
12142        long totalPss = 0;
12143        long cachedPss = 0;
12144
12145        Debug.MemoryInfo mi = null;
12146        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12147            final ProcessRecord r = procs.get(i);
12148            final IApplicationThread thread;
12149            final int pid;
12150            final int oomAdj;
12151            final boolean hasActivities;
12152            synchronized (this) {
12153                thread = r.thread;
12154                pid = r.pid;
12155                oomAdj = r.getSetAdjWithServices();
12156                hasActivities = r.activities.size() > 0;
12157            }
12158            if (thread != null) {
12159                if (!isCheckinRequest && dumpDetails) {
12160                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12161                }
12162                if (mi == null) {
12163                    mi = new Debug.MemoryInfo();
12164                }
12165                if (dumpDetails || (!brief && !oomOnly)) {
12166                    Debug.getMemoryInfo(pid, mi);
12167                } else {
12168                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12169                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12170                }
12171                if (dumpDetails) {
12172                    if (localOnly) {
12173                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12174                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12175                        if (isCheckinRequest) {
12176                            pw.println();
12177                        }
12178                    } else {
12179                        try {
12180                            pw.flush();
12181                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12182                                    dumpDalvik, innerArgs);
12183                        } catch (RemoteException e) {
12184                            if (!isCheckinRequest) {
12185                                pw.println("Got RemoteException!");
12186                                pw.flush();
12187                            }
12188                        }
12189                    }
12190                }
12191
12192                final long myTotalPss = mi.getTotalPss();
12193                final long myTotalUss = mi.getTotalUss();
12194
12195                synchronized (this) {
12196                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12197                        // Record this for posterity if the process has been stable.
12198                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12199                    }
12200                }
12201
12202                if (!isCheckinRequest && mi != null) {
12203                    totalPss += myTotalPss;
12204                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12205                            (hasActivities ? " / activities)" : ")"),
12206                            r.processName, myTotalPss, pid, hasActivities);
12207                    procMems.add(pssItem);
12208                    procMemsMap.put(pid, pssItem);
12209
12210                    nativePss += mi.nativePss;
12211                    dalvikPss += mi.dalvikPss;
12212                    otherPss += mi.otherPss;
12213                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12214                        long mem = mi.getOtherPss(j);
12215                        miscPss[j] += mem;
12216                        otherPss -= mem;
12217                    }
12218
12219                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12220                        cachedPss += myTotalPss;
12221                    }
12222
12223                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12224                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12225                                || oomIndex == (oomPss.length-1)) {
12226                            oomPss[oomIndex] += myTotalPss;
12227                            if (oomProcs[oomIndex] == null) {
12228                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12229                            }
12230                            oomProcs[oomIndex].add(pssItem);
12231                            break;
12232                        }
12233                    }
12234                }
12235            }
12236        }
12237
12238        if (!isCheckinRequest && procs.size() > 1) {
12239            // If we are showing aggregations, also look for native processes to
12240            // include so that our aggregations are more accurate.
12241            updateCpuStatsNow();
12242            synchronized (mProcessCpuThread) {
12243                final int N = mProcessCpuTracker.countStats();
12244                for (int i=0; i<N; i++) {
12245                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12246                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12247                        if (mi == null) {
12248                            mi = new Debug.MemoryInfo();
12249                        }
12250                        if (!brief && !oomOnly) {
12251                            Debug.getMemoryInfo(st.pid, mi);
12252                        } else {
12253                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12254                            mi.nativePrivateDirty = (int)tmpLong[0];
12255                        }
12256
12257                        final long myTotalPss = mi.getTotalPss();
12258                        totalPss += myTotalPss;
12259
12260                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12261                                st.name, myTotalPss, st.pid, false);
12262                        procMems.add(pssItem);
12263
12264                        nativePss += mi.nativePss;
12265                        dalvikPss += mi.dalvikPss;
12266                        otherPss += mi.otherPss;
12267                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12268                            long mem = mi.getOtherPss(j);
12269                            miscPss[j] += mem;
12270                            otherPss -= mem;
12271                        }
12272                        oomPss[0] += myTotalPss;
12273                        if (oomProcs[0] == null) {
12274                            oomProcs[0] = new ArrayList<MemItem>();
12275                        }
12276                        oomProcs[0].add(pssItem);
12277                    }
12278                }
12279            }
12280
12281            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12282
12283            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12284            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12285            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12286            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12287                String label = Debug.MemoryInfo.getOtherLabel(j);
12288                catMems.add(new MemItem(label, label, miscPss[j], j));
12289            }
12290
12291            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12292            for (int j=0; j<oomPss.length; j++) {
12293                if (oomPss[j] != 0) {
12294                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12295                            : DUMP_MEM_OOM_LABEL[j];
12296                    MemItem item = new MemItem(label, label, oomPss[j],
12297                            DUMP_MEM_OOM_ADJ[j]);
12298                    item.subitems = oomProcs[j];
12299                    oomMems.add(item);
12300                }
12301            }
12302
12303            if (!brief && !oomOnly && !isCompact) {
12304                pw.println();
12305                pw.println("Total PSS by process:");
12306                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12307                pw.println();
12308            }
12309            if (!isCompact) {
12310                pw.println("Total PSS by OOM adjustment:");
12311            }
12312            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12313            if (!brief && !oomOnly) {
12314                PrintWriter out = categoryPw != null ? categoryPw : pw;
12315                if (!isCompact) {
12316                    out.println();
12317                    out.println("Total PSS by category:");
12318                }
12319                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12320            }
12321            if (!isCompact) {
12322                pw.println();
12323            }
12324            MemInfoReader memInfo = new MemInfoReader();
12325            memInfo.readMemInfo();
12326            if (!brief) {
12327                if (!isCompact) {
12328                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12329                    pw.print(" kB (status ");
12330                    switch (mLastMemoryLevel) {
12331                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12332                            pw.println("normal)");
12333                            break;
12334                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12335                            pw.println("moderate)");
12336                            break;
12337                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12338                            pw.println("low)");
12339                            break;
12340                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12341                            pw.println("critical)");
12342                            break;
12343                        default:
12344                            pw.print(mLastMemoryLevel);
12345                            pw.println(")");
12346                            break;
12347                    }
12348                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12349                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12350                            pw.print(cachedPss); pw.print(" cached pss + ");
12351                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12352                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12353                } else {
12354                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12355                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12356                            + memInfo.getFreeSizeKb()); pw.print(",");
12357                    pw.println(totalPss - cachedPss);
12358                }
12359            }
12360            if (!isCompact) {
12361                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12362                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12363                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12364                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12365                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12366                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12367                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12368                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12369                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12370                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12371                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12372            }
12373            if (!brief) {
12374                if (memInfo.getZramTotalSizeKb() != 0) {
12375                    if (!isCompact) {
12376                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12377                                pw.print(" kB physical used for ");
12378                                pw.print(memInfo.getSwapTotalSizeKb()
12379                                        - memInfo.getSwapFreeSizeKb());
12380                                pw.print(" kB in swap (");
12381                                pw.print(memInfo.getSwapTotalSizeKb());
12382                                pw.println(" kB total swap)");
12383                    } else {
12384                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12385                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12386                                pw.println(memInfo.getSwapFreeSizeKb());
12387                    }
12388                }
12389                final int[] SINGLE_LONG_FORMAT = new int[] {
12390                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12391                };
12392                long[] longOut = new long[1];
12393                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12394                        SINGLE_LONG_FORMAT, null, longOut, null);
12395                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12396                longOut[0] = 0;
12397                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12398                        SINGLE_LONG_FORMAT, null, longOut, null);
12399                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12400                longOut[0] = 0;
12401                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12402                        SINGLE_LONG_FORMAT, null, longOut, null);
12403                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12404                longOut[0] = 0;
12405                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12406                        SINGLE_LONG_FORMAT, null, longOut, null);
12407                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12408                if (!isCompact) {
12409                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12410                        pw.print("      KSM: "); pw.print(sharing);
12411                                pw.print(" kB saved from shared ");
12412                                pw.print(shared); pw.println(" kB");
12413                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12414                                pw.print(voltile); pw.println(" kB volatile");
12415                    }
12416                    pw.print("   Tuning: ");
12417                    pw.print(ActivityManager.staticGetMemoryClass());
12418                    pw.print(" (large ");
12419                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12420                    pw.print("), oom ");
12421                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12422                    pw.print(" kB");
12423                    pw.print(", restore limit ");
12424                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12425                    pw.print(" kB");
12426                    if (ActivityManager.isLowRamDeviceStatic()) {
12427                        pw.print(" (low-ram)");
12428                    }
12429                    if (ActivityManager.isHighEndGfx()) {
12430                        pw.print(" (high-end-gfx)");
12431                    }
12432                    pw.println();
12433                } else {
12434                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12435                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12436                    pw.println(voltile);
12437                    pw.print("tuning,");
12438                    pw.print(ActivityManager.staticGetMemoryClass());
12439                    pw.print(',');
12440                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12441                    pw.print(',');
12442                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12443                    if (ActivityManager.isLowRamDeviceStatic()) {
12444                        pw.print(",low-ram");
12445                    }
12446                    if (ActivityManager.isHighEndGfx()) {
12447                        pw.print(",high-end-gfx");
12448                    }
12449                    pw.println();
12450                }
12451            }
12452        }
12453    }
12454
12455    /**
12456     * Searches array of arguments for the specified string
12457     * @param args array of argument strings
12458     * @param value value to search for
12459     * @return true if the value is contained in the array
12460     */
12461    private static boolean scanArgs(String[] args, String value) {
12462        if (args != null) {
12463            for (String arg : args) {
12464                if (value.equals(arg)) {
12465                    return true;
12466                }
12467            }
12468        }
12469        return false;
12470    }
12471
12472    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12473            ContentProviderRecord cpr, boolean always) {
12474        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12475
12476        if (!inLaunching || always) {
12477            synchronized (cpr) {
12478                cpr.launchingApp = null;
12479                cpr.notifyAll();
12480            }
12481            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12482            String names[] = cpr.info.authority.split(";");
12483            for (int j = 0; j < names.length; j++) {
12484                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12485            }
12486        }
12487
12488        for (int i=0; i<cpr.connections.size(); i++) {
12489            ContentProviderConnection conn = cpr.connections.get(i);
12490            if (conn.waiting) {
12491                // If this connection is waiting for the provider, then we don't
12492                // need to mess with its process unless we are always removing
12493                // or for some reason the provider is not currently launching.
12494                if (inLaunching && !always) {
12495                    continue;
12496                }
12497            }
12498            ProcessRecord capp = conn.client;
12499            conn.dead = true;
12500            if (conn.stableCount > 0) {
12501                if (!capp.persistent && capp.thread != null
12502                        && capp.pid != 0
12503                        && capp.pid != MY_PID) {
12504                    killUnneededProcessLocked(capp, "depends on provider "
12505                            + cpr.name.flattenToShortString()
12506                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12507                }
12508            } else if (capp.thread != null && conn.provider.provider != null) {
12509                try {
12510                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12511                } catch (RemoteException e) {
12512                }
12513                // In the protocol here, we don't expect the client to correctly
12514                // clean up this connection, we'll just remove it.
12515                cpr.connections.remove(i);
12516                conn.client.conProviders.remove(conn);
12517            }
12518        }
12519
12520        if (inLaunching && always) {
12521            mLaunchingProviders.remove(cpr);
12522        }
12523        return inLaunching;
12524    }
12525
12526    /**
12527     * Main code for cleaning up a process when it has gone away.  This is
12528     * called both as a result of the process dying, or directly when stopping
12529     * a process when running in single process mode.
12530     */
12531    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12532            boolean restarting, boolean allowRestart, int index) {
12533        if (index >= 0) {
12534            removeLruProcessLocked(app);
12535            ProcessList.remove(app.pid);
12536        }
12537
12538        mProcessesToGc.remove(app);
12539        mPendingPssProcesses.remove(app);
12540
12541        // Dismiss any open dialogs.
12542        if (app.crashDialog != null && !app.forceCrashReport) {
12543            app.crashDialog.dismiss();
12544            app.crashDialog = null;
12545        }
12546        if (app.anrDialog != null) {
12547            app.anrDialog.dismiss();
12548            app.anrDialog = null;
12549        }
12550        if (app.waitDialog != null) {
12551            app.waitDialog.dismiss();
12552            app.waitDialog = null;
12553        }
12554
12555        app.crashing = false;
12556        app.notResponding = false;
12557
12558        app.resetPackageList(mProcessStats);
12559        app.unlinkDeathRecipient();
12560        app.makeInactive(mProcessStats);
12561        app.forcingToForeground = null;
12562        updateProcessForegroundLocked(app, false, false);
12563        app.foregroundActivities = false;
12564        app.hasShownUi = false;
12565        app.treatLikeActivity = false;
12566        app.hasAboveClient = false;
12567
12568        mServices.killServicesLocked(app, allowRestart);
12569
12570        boolean restart = false;
12571
12572        // Remove published content providers.
12573        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12574            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12575            final boolean always = app.bad || !allowRestart;
12576            if (removeDyingProviderLocked(app, cpr, always) || always) {
12577                // We left the provider in the launching list, need to
12578                // restart it.
12579                restart = true;
12580            }
12581
12582            cpr.provider = null;
12583            cpr.proc = null;
12584        }
12585        app.pubProviders.clear();
12586
12587        // Take care of any launching providers waiting for this process.
12588        if (checkAppInLaunchingProvidersLocked(app, false)) {
12589            restart = true;
12590        }
12591
12592        // Unregister from connected content providers.
12593        if (!app.conProviders.isEmpty()) {
12594            for (int i=0; i<app.conProviders.size(); i++) {
12595                ContentProviderConnection conn = app.conProviders.get(i);
12596                conn.provider.connections.remove(conn);
12597            }
12598            app.conProviders.clear();
12599        }
12600
12601        // At this point there may be remaining entries in mLaunchingProviders
12602        // where we were the only one waiting, so they are no longer of use.
12603        // Look for these and clean up if found.
12604        // XXX Commented out for now.  Trying to figure out a way to reproduce
12605        // the actual situation to identify what is actually going on.
12606        if (false) {
12607            for (int i=0; i<mLaunchingProviders.size(); i++) {
12608                ContentProviderRecord cpr = (ContentProviderRecord)
12609                        mLaunchingProviders.get(i);
12610                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12611                    synchronized (cpr) {
12612                        cpr.launchingApp = null;
12613                        cpr.notifyAll();
12614                    }
12615                }
12616            }
12617        }
12618
12619        skipCurrentReceiverLocked(app);
12620
12621        // Unregister any receivers.
12622        for (int i=app.receivers.size()-1; i>=0; i--) {
12623            removeReceiverLocked(app.receivers.valueAt(i));
12624        }
12625        app.receivers.clear();
12626
12627        // If the app is undergoing backup, tell the backup manager about it
12628        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12629            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12630                    + mBackupTarget.appInfo + " died during backup");
12631            try {
12632                IBackupManager bm = IBackupManager.Stub.asInterface(
12633                        ServiceManager.getService(Context.BACKUP_SERVICE));
12634                bm.agentDisconnected(app.info.packageName);
12635            } catch (RemoteException e) {
12636                // can't happen; backup manager is local
12637            }
12638        }
12639
12640        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12641            ProcessChangeItem item = mPendingProcessChanges.get(i);
12642            if (item.pid == app.pid) {
12643                mPendingProcessChanges.remove(i);
12644                mAvailProcessChanges.add(item);
12645            }
12646        }
12647        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12648
12649        // If the caller is restarting this app, then leave it in its
12650        // current lists and let the caller take care of it.
12651        if (restarting) {
12652            return;
12653        }
12654
12655        if (!app.persistent || app.isolated) {
12656            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12657                    "Removing non-persistent process during cleanup: " + app);
12658            mProcessNames.remove(app.processName, app.uid);
12659            mIsolatedProcesses.remove(app.uid);
12660            if (mHeavyWeightProcess == app) {
12661                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12662                        mHeavyWeightProcess.userId, 0));
12663                mHeavyWeightProcess = null;
12664            }
12665        } else if (!app.removed) {
12666            // This app is persistent, so we need to keep its record around.
12667            // If it is not already on the pending app list, add it there
12668            // and start a new process for it.
12669            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12670                mPersistentStartingProcesses.add(app);
12671                restart = true;
12672            }
12673        }
12674        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12675                "Clean-up removing on hold: " + app);
12676        mProcessesOnHold.remove(app);
12677
12678        if (app == mHomeProcess) {
12679            mHomeProcess = null;
12680        }
12681        if (app == mPreviousProcess) {
12682            mPreviousProcess = null;
12683        }
12684
12685        if (restart && !app.isolated) {
12686            // We have components that still need to be running in the
12687            // process, so re-launch it.
12688            mProcessNames.put(app.processName, app.uid, app);
12689            startProcessLocked(app, "restart", app.processName);
12690        } else if (app.pid > 0 && app.pid != MY_PID) {
12691            // Goodbye!
12692            boolean removed;
12693            synchronized (mPidsSelfLocked) {
12694                mPidsSelfLocked.remove(app.pid);
12695                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12696            }
12697            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
12698                    app.processName, app.info.uid);
12699            if (app.isolated) {
12700                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
12701            }
12702            app.setPid(0);
12703        }
12704    }
12705
12706    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12707        // Look through the content providers we are waiting to have launched,
12708        // and if any run in this process then either schedule a restart of
12709        // the process or kill the client waiting for it if this process has
12710        // gone bad.
12711        int NL = mLaunchingProviders.size();
12712        boolean restart = false;
12713        for (int i=0; i<NL; i++) {
12714            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12715            if (cpr.launchingApp == app) {
12716                if (!alwaysBad && !app.bad) {
12717                    restart = true;
12718                } else {
12719                    removeDyingProviderLocked(app, cpr, true);
12720                    // cpr should have been removed from mLaunchingProviders
12721                    NL = mLaunchingProviders.size();
12722                    i--;
12723                }
12724            }
12725        }
12726        return restart;
12727    }
12728
12729    // =========================================================
12730    // SERVICES
12731    // =========================================================
12732
12733    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12734            int flags) {
12735        enforceNotIsolatedCaller("getServices");
12736        synchronized (this) {
12737            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12738        }
12739    }
12740
12741    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12742        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12743        synchronized (this) {
12744            return mServices.getRunningServiceControlPanelLocked(name);
12745        }
12746    }
12747
12748    public ComponentName startService(IApplicationThread caller, Intent service,
12749            String resolvedType, int userId) {
12750        enforceNotIsolatedCaller("startService");
12751        // Refuse possible leaked file descriptors
12752        if (service != null && service.hasFileDescriptors() == true) {
12753            throw new IllegalArgumentException("File descriptors passed in Intent");
12754        }
12755
12756        if (DEBUG_SERVICE)
12757            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
12758        synchronized(this) {
12759            final int callingPid = Binder.getCallingPid();
12760            final int callingUid = Binder.getCallingUid();
12761            final long origId = Binder.clearCallingIdentity();
12762            ComponentName res = mServices.startServiceLocked(caller, service,
12763                    resolvedType, callingPid, callingUid, userId);
12764            Binder.restoreCallingIdentity(origId);
12765            return res;
12766        }
12767    }
12768
12769    ComponentName startServiceInPackage(int uid,
12770            Intent service, String resolvedType, int userId) {
12771        synchronized(this) {
12772            if (DEBUG_SERVICE)
12773                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
12774            final long origId = Binder.clearCallingIdentity();
12775            ComponentName res = mServices.startServiceLocked(null, service,
12776                    resolvedType, -1, uid, userId);
12777            Binder.restoreCallingIdentity(origId);
12778            return res;
12779        }
12780    }
12781
12782    public int stopService(IApplicationThread caller, Intent service,
12783            String resolvedType, int userId) {
12784        enforceNotIsolatedCaller("stopService");
12785        // Refuse possible leaked file descriptors
12786        if (service != null && service.hasFileDescriptors() == true) {
12787            throw new IllegalArgumentException("File descriptors passed in Intent");
12788        }
12789
12790        synchronized(this) {
12791            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
12792        }
12793    }
12794
12795    public IBinder peekService(Intent service, String resolvedType) {
12796        enforceNotIsolatedCaller("peekService");
12797        // Refuse possible leaked file descriptors
12798        if (service != null && service.hasFileDescriptors() == true) {
12799            throw new IllegalArgumentException("File descriptors passed in Intent");
12800        }
12801        synchronized(this) {
12802            return mServices.peekServiceLocked(service, resolvedType);
12803        }
12804    }
12805
12806    public boolean stopServiceToken(ComponentName className, IBinder token,
12807            int startId) {
12808        synchronized(this) {
12809            return mServices.stopServiceTokenLocked(className, token, startId);
12810        }
12811    }
12812
12813    public void setServiceForeground(ComponentName className, IBinder token,
12814            int id, Notification notification, boolean removeNotification) {
12815        synchronized(this) {
12816            mServices.setServiceForegroundLocked(className, token, id, notification,
12817                    removeNotification);
12818        }
12819    }
12820
12821    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
12822            boolean requireFull, String name, String callerPackage) {
12823        final int callingUserId = UserHandle.getUserId(callingUid);
12824        if (callingUserId != userId) {
12825            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
12826                if ((requireFull || checkComponentPermission(
12827                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12828                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
12829                        && checkComponentPermission(
12830                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
12831                                callingPid, callingUid, -1, true)
12832                                != PackageManager.PERMISSION_GRANTED) {
12833                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
12834                        // In this case, they would like to just execute as their
12835                        // owner user instead of failing.
12836                        userId = callingUserId;
12837                    } else {
12838                        StringBuilder builder = new StringBuilder(128);
12839                        builder.append("Permission Denial: ");
12840                        builder.append(name);
12841                        if (callerPackage != null) {
12842                            builder.append(" from ");
12843                            builder.append(callerPackage);
12844                        }
12845                        builder.append(" asks to run as user ");
12846                        builder.append(userId);
12847                        builder.append(" but is calling from user ");
12848                        builder.append(UserHandle.getUserId(callingUid));
12849                        builder.append("; this requires ");
12850                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
12851                        if (!requireFull) {
12852                            builder.append(" or ");
12853                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
12854                        }
12855                        String msg = builder.toString();
12856                        Slog.w(TAG, msg);
12857                        throw new SecurityException(msg);
12858                    }
12859                }
12860            }
12861            if (userId == UserHandle.USER_CURRENT
12862                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
12863                // Note that we may be accessing this outside of a lock...
12864                // shouldn't be a big deal, if this is being called outside
12865                // of a locked context there is intrinsically a race with
12866                // the value the caller will receive and someone else changing it.
12867                userId = mCurrentUserId;
12868            }
12869            if (!allowAll && userId < 0) {
12870                throw new IllegalArgumentException(
12871                        "Call does not support special user #" + userId);
12872            }
12873        }
12874        return userId;
12875    }
12876
12877    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
12878            String className, int flags) {
12879        boolean result = false;
12880        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
12881            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
12882                if (ActivityManager.checkUidPermission(
12883                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12884                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
12885                    ComponentName comp = new ComponentName(aInfo.packageName, className);
12886                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
12887                            + " requests FLAG_SINGLE_USER, but app does not hold "
12888                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
12889                    Slog.w(TAG, msg);
12890                    throw new SecurityException(msg);
12891                }
12892                result = true;
12893            }
12894        } else if (componentProcessName == aInfo.packageName) {
12895            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
12896        } else if ("system".equals(componentProcessName)) {
12897            result = true;
12898        }
12899        if (DEBUG_MU) {
12900            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
12901                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
12902        }
12903        return result;
12904    }
12905
12906    public int bindService(IApplicationThread caller, IBinder token,
12907            Intent service, String resolvedType,
12908            IServiceConnection connection, int flags, int userId) {
12909        enforceNotIsolatedCaller("bindService");
12910        // Refuse possible leaked file descriptors
12911        if (service != null && service.hasFileDescriptors() == true) {
12912            throw new IllegalArgumentException("File descriptors passed in Intent");
12913        }
12914
12915        synchronized(this) {
12916            return mServices.bindServiceLocked(caller, token, service, resolvedType,
12917                    connection, flags, userId);
12918        }
12919    }
12920
12921    public boolean unbindService(IServiceConnection connection) {
12922        synchronized (this) {
12923            return mServices.unbindServiceLocked(connection);
12924        }
12925    }
12926
12927    public void publishService(IBinder token, Intent intent, IBinder service) {
12928        // Refuse possible leaked file descriptors
12929        if (intent != null && intent.hasFileDescriptors() == true) {
12930            throw new IllegalArgumentException("File descriptors passed in Intent");
12931        }
12932
12933        synchronized(this) {
12934            if (!(token instanceof ServiceRecord)) {
12935                throw new IllegalArgumentException("Invalid service token");
12936            }
12937            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
12938        }
12939    }
12940
12941    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
12942        // Refuse possible leaked file descriptors
12943        if (intent != null && intent.hasFileDescriptors() == true) {
12944            throw new IllegalArgumentException("File descriptors passed in Intent");
12945        }
12946
12947        synchronized(this) {
12948            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
12949        }
12950    }
12951
12952    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
12953        synchronized(this) {
12954            if (!(token instanceof ServiceRecord)) {
12955                throw new IllegalArgumentException("Invalid service token");
12956            }
12957            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
12958        }
12959    }
12960
12961    // =========================================================
12962    // BACKUP AND RESTORE
12963    // =========================================================
12964
12965    // Cause the target app to be launched if necessary and its backup agent
12966    // instantiated.  The backup agent will invoke backupAgentCreated() on the
12967    // activity manager to announce its creation.
12968    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
12969        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
12970        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
12971
12972        synchronized(this) {
12973            // !!! TODO: currently no check here that we're already bound
12974            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
12975            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12976            synchronized (stats) {
12977                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
12978            }
12979
12980            // Backup agent is now in use, its package can't be stopped.
12981            try {
12982                AppGlobals.getPackageManager().setPackageStoppedState(
12983                        app.packageName, false, UserHandle.getUserId(app.uid));
12984            } catch (RemoteException e) {
12985            } catch (IllegalArgumentException e) {
12986                Slog.w(TAG, "Failed trying to unstop package "
12987                        + app.packageName + ": " + e);
12988            }
12989
12990            BackupRecord r = new BackupRecord(ss, app, backupMode);
12991            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
12992                    ? new ComponentName(app.packageName, app.backupAgentName)
12993                    : new ComponentName("android", "FullBackupAgent");
12994            // startProcessLocked() returns existing proc's record if it's already running
12995            ProcessRecord proc = startProcessLocked(app.processName, app,
12996                    false, 0, "backup", hostingName, false, false, false);
12997            if (proc == null) {
12998                Slog.e(TAG, "Unable to start backup agent process " + r);
12999                return false;
13000            }
13001
13002            r.app = proc;
13003            mBackupTarget = r;
13004            mBackupAppName = app.packageName;
13005
13006            // Try not to kill the process during backup
13007            updateOomAdjLocked(proc);
13008
13009            // If the process is already attached, schedule the creation of the backup agent now.
13010            // If it is not yet live, this will be done when it attaches to the framework.
13011            if (proc.thread != null) {
13012                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13013                try {
13014                    proc.thread.scheduleCreateBackupAgent(app,
13015                            compatibilityInfoForPackageLocked(app), backupMode);
13016                } catch (RemoteException e) {
13017                    // Will time out on the backup manager side
13018                }
13019            } else {
13020                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13021            }
13022            // Invariants: at this point, the target app process exists and the application
13023            // is either already running or in the process of coming up.  mBackupTarget and
13024            // mBackupAppName describe the app, so that when it binds back to the AM we
13025            // know that it's scheduled for a backup-agent operation.
13026        }
13027
13028        return true;
13029    }
13030
13031    @Override
13032    public void clearPendingBackup() {
13033        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13034        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13035
13036        synchronized (this) {
13037            mBackupTarget = null;
13038            mBackupAppName = null;
13039        }
13040    }
13041
13042    // A backup agent has just come up
13043    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13044        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13045                + " = " + agent);
13046
13047        synchronized(this) {
13048            if (!agentPackageName.equals(mBackupAppName)) {
13049                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13050                return;
13051            }
13052        }
13053
13054        long oldIdent = Binder.clearCallingIdentity();
13055        try {
13056            IBackupManager bm = IBackupManager.Stub.asInterface(
13057                    ServiceManager.getService(Context.BACKUP_SERVICE));
13058            bm.agentConnected(agentPackageName, agent);
13059        } catch (RemoteException e) {
13060            // can't happen; the backup manager service is local
13061        } catch (Exception e) {
13062            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13063            e.printStackTrace();
13064        } finally {
13065            Binder.restoreCallingIdentity(oldIdent);
13066        }
13067    }
13068
13069    // done with this agent
13070    public void unbindBackupAgent(ApplicationInfo appInfo) {
13071        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13072        if (appInfo == null) {
13073            Slog.w(TAG, "unbind backup agent for null app");
13074            return;
13075        }
13076
13077        synchronized(this) {
13078            try {
13079                if (mBackupAppName == null) {
13080                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13081                    return;
13082                }
13083
13084                if (!mBackupAppName.equals(appInfo.packageName)) {
13085                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13086                    return;
13087                }
13088
13089                // Not backing this app up any more; reset its OOM adjustment
13090                final ProcessRecord proc = mBackupTarget.app;
13091                updateOomAdjLocked(proc);
13092
13093                // If the app crashed during backup, 'thread' will be null here
13094                if (proc.thread != null) {
13095                    try {
13096                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13097                                compatibilityInfoForPackageLocked(appInfo));
13098                    } catch (Exception e) {
13099                        Slog.e(TAG, "Exception when unbinding backup agent:");
13100                        e.printStackTrace();
13101                    }
13102                }
13103            } finally {
13104                mBackupTarget = null;
13105                mBackupAppName = null;
13106            }
13107        }
13108    }
13109    // =========================================================
13110    // BROADCASTS
13111    // =========================================================
13112
13113    private final List getStickiesLocked(String action, IntentFilter filter,
13114            List cur, int userId) {
13115        final ContentResolver resolver = mContext.getContentResolver();
13116        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13117        if (stickies == null) {
13118            return cur;
13119        }
13120        final ArrayList<Intent> list = stickies.get(action);
13121        if (list == null) {
13122            return cur;
13123        }
13124        int N = list.size();
13125        for (int i=0; i<N; i++) {
13126            Intent intent = list.get(i);
13127            if (filter.match(resolver, intent, true, TAG) >= 0) {
13128                if (cur == null) {
13129                    cur = new ArrayList<Intent>();
13130                }
13131                cur.add(intent);
13132            }
13133        }
13134        return cur;
13135    }
13136
13137    boolean isPendingBroadcastProcessLocked(int pid) {
13138        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13139                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13140    }
13141
13142    void skipPendingBroadcastLocked(int pid) {
13143            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13144            for (BroadcastQueue queue : mBroadcastQueues) {
13145                queue.skipPendingBroadcastLocked(pid);
13146            }
13147    }
13148
13149    // The app just attached; send any pending broadcasts that it should receive
13150    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13151        boolean didSomething = false;
13152        for (BroadcastQueue queue : mBroadcastQueues) {
13153            didSomething |= queue.sendPendingBroadcastsLocked(app);
13154        }
13155        return didSomething;
13156    }
13157
13158    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13159            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13160        enforceNotIsolatedCaller("registerReceiver");
13161        int callingUid;
13162        int callingPid;
13163        synchronized(this) {
13164            ProcessRecord callerApp = null;
13165            if (caller != null) {
13166                callerApp = getRecordForAppLocked(caller);
13167                if (callerApp == null) {
13168                    throw new SecurityException(
13169                            "Unable to find app for caller " + caller
13170                            + " (pid=" + Binder.getCallingPid()
13171                            + ") when registering receiver " + receiver);
13172                }
13173                if (callerApp.info.uid != Process.SYSTEM_UID &&
13174                        !callerApp.pkgList.containsKey(callerPackage) &&
13175                        !"android".equals(callerPackage)) {
13176                    throw new SecurityException("Given caller package " + callerPackage
13177                            + " is not running in process " + callerApp);
13178                }
13179                callingUid = callerApp.info.uid;
13180                callingPid = callerApp.pid;
13181            } else {
13182                callerPackage = null;
13183                callingUid = Binder.getCallingUid();
13184                callingPid = Binder.getCallingPid();
13185            }
13186
13187            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13188                    true, true, "registerReceiver", callerPackage);
13189
13190            List allSticky = null;
13191
13192            // Look for any matching sticky broadcasts...
13193            Iterator actions = filter.actionsIterator();
13194            if (actions != null) {
13195                while (actions.hasNext()) {
13196                    String action = (String)actions.next();
13197                    allSticky = getStickiesLocked(action, filter, allSticky,
13198                            UserHandle.USER_ALL);
13199                    allSticky = getStickiesLocked(action, filter, allSticky,
13200                            UserHandle.getUserId(callingUid));
13201                }
13202            } else {
13203                allSticky = getStickiesLocked(null, filter, allSticky,
13204                        UserHandle.USER_ALL);
13205                allSticky = getStickiesLocked(null, filter, allSticky,
13206                        UserHandle.getUserId(callingUid));
13207            }
13208
13209            // The first sticky in the list is returned directly back to
13210            // the client.
13211            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13212
13213            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13214                    + ": " + sticky);
13215
13216            if (receiver == null) {
13217                return sticky;
13218            }
13219
13220            ReceiverList rl
13221                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13222            if (rl == null) {
13223                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13224                        userId, receiver);
13225                if (rl.app != null) {
13226                    rl.app.receivers.add(rl);
13227                } else {
13228                    try {
13229                        receiver.asBinder().linkToDeath(rl, 0);
13230                    } catch (RemoteException e) {
13231                        return sticky;
13232                    }
13233                    rl.linkedToDeath = true;
13234                }
13235                mRegisteredReceivers.put(receiver.asBinder(), rl);
13236            } else if (rl.uid != callingUid) {
13237                throw new IllegalArgumentException(
13238                        "Receiver requested to register for uid " + callingUid
13239                        + " was previously registered for uid " + rl.uid);
13240            } else if (rl.pid != callingPid) {
13241                throw new IllegalArgumentException(
13242                        "Receiver requested to register for pid " + callingPid
13243                        + " was previously registered for pid " + rl.pid);
13244            } else if (rl.userId != userId) {
13245                throw new IllegalArgumentException(
13246                        "Receiver requested to register for user " + userId
13247                        + " was previously registered for user " + rl.userId);
13248            }
13249            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13250                    permission, callingUid, userId);
13251            rl.add(bf);
13252            if (!bf.debugCheck()) {
13253                Slog.w(TAG, "==> For Dynamic broadast");
13254            }
13255            mReceiverResolver.addFilter(bf);
13256
13257            // Enqueue broadcasts for all existing stickies that match
13258            // this filter.
13259            if (allSticky != null) {
13260                ArrayList receivers = new ArrayList();
13261                receivers.add(bf);
13262
13263                int N = allSticky.size();
13264                for (int i=0; i<N; i++) {
13265                    Intent intent = (Intent)allSticky.get(i);
13266                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13267                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13268                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13269                            null, null, false, true, true, -1);
13270                    queue.enqueueParallelBroadcastLocked(r);
13271                    queue.scheduleBroadcastsLocked();
13272                }
13273            }
13274
13275            return sticky;
13276        }
13277    }
13278
13279    public void unregisterReceiver(IIntentReceiver receiver) {
13280        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13281
13282        final long origId = Binder.clearCallingIdentity();
13283        try {
13284            boolean doTrim = false;
13285
13286            synchronized(this) {
13287                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13288                if (rl != null) {
13289                    if (rl.curBroadcast != null) {
13290                        BroadcastRecord r = rl.curBroadcast;
13291                        final boolean doNext = finishReceiverLocked(
13292                                receiver.asBinder(), r.resultCode, r.resultData,
13293                                r.resultExtras, r.resultAbort);
13294                        if (doNext) {
13295                            doTrim = true;
13296                            r.queue.processNextBroadcast(false);
13297                        }
13298                    }
13299
13300                    if (rl.app != null) {
13301                        rl.app.receivers.remove(rl);
13302                    }
13303                    removeReceiverLocked(rl);
13304                    if (rl.linkedToDeath) {
13305                        rl.linkedToDeath = false;
13306                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13307                    }
13308                }
13309            }
13310
13311            // If we actually concluded any broadcasts, we might now be able
13312            // to trim the recipients' apps from our working set
13313            if (doTrim) {
13314                trimApplications();
13315                return;
13316            }
13317
13318        } finally {
13319            Binder.restoreCallingIdentity(origId);
13320        }
13321    }
13322
13323    void removeReceiverLocked(ReceiverList rl) {
13324        mRegisteredReceivers.remove(rl.receiver.asBinder());
13325        int N = rl.size();
13326        for (int i=0; i<N; i++) {
13327            mReceiverResolver.removeFilter(rl.get(i));
13328        }
13329    }
13330
13331    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13332        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13333            ProcessRecord r = mLruProcesses.get(i);
13334            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13335                try {
13336                    r.thread.dispatchPackageBroadcast(cmd, packages);
13337                } catch (RemoteException ex) {
13338                }
13339            }
13340        }
13341    }
13342
13343    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13344            int[] users) {
13345        List<ResolveInfo> receivers = null;
13346        try {
13347            HashSet<ComponentName> singleUserReceivers = null;
13348            boolean scannedFirstReceivers = false;
13349            for (int user : users) {
13350                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13351                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13352                if (user != 0 && newReceivers != null) {
13353                    // If this is not the primary user, we need to check for
13354                    // any receivers that should be filtered out.
13355                    for (int i=0; i<newReceivers.size(); i++) {
13356                        ResolveInfo ri = newReceivers.get(i);
13357                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13358                            newReceivers.remove(i);
13359                            i--;
13360                        }
13361                    }
13362                }
13363                if (newReceivers != null && newReceivers.size() == 0) {
13364                    newReceivers = null;
13365                }
13366                if (receivers == null) {
13367                    receivers = newReceivers;
13368                } else if (newReceivers != null) {
13369                    // We need to concatenate the additional receivers
13370                    // found with what we have do far.  This would be easy,
13371                    // but we also need to de-dup any receivers that are
13372                    // singleUser.
13373                    if (!scannedFirstReceivers) {
13374                        // Collect any single user receivers we had already retrieved.
13375                        scannedFirstReceivers = true;
13376                        for (int i=0; i<receivers.size(); i++) {
13377                            ResolveInfo ri = receivers.get(i);
13378                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13379                                ComponentName cn = new ComponentName(
13380                                        ri.activityInfo.packageName, ri.activityInfo.name);
13381                                if (singleUserReceivers == null) {
13382                                    singleUserReceivers = new HashSet<ComponentName>();
13383                                }
13384                                singleUserReceivers.add(cn);
13385                            }
13386                        }
13387                    }
13388                    // Add the new results to the existing results, tracking
13389                    // and de-dupping single user receivers.
13390                    for (int i=0; i<newReceivers.size(); i++) {
13391                        ResolveInfo ri = newReceivers.get(i);
13392                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13393                            ComponentName cn = new ComponentName(
13394                                    ri.activityInfo.packageName, ri.activityInfo.name);
13395                            if (singleUserReceivers == null) {
13396                                singleUserReceivers = new HashSet<ComponentName>();
13397                            }
13398                            if (!singleUserReceivers.contains(cn)) {
13399                                singleUserReceivers.add(cn);
13400                                receivers.add(ri);
13401                            }
13402                        } else {
13403                            receivers.add(ri);
13404                        }
13405                    }
13406                }
13407            }
13408        } catch (RemoteException ex) {
13409            // pm is in same process, this will never happen.
13410        }
13411        return receivers;
13412    }
13413
13414    private final int broadcastIntentLocked(ProcessRecord callerApp,
13415            String callerPackage, Intent intent, String resolvedType,
13416            IIntentReceiver resultTo, int resultCode, String resultData,
13417            Bundle map, String requiredPermission, int appOp,
13418            boolean ordered, boolean sticky, int callingPid, int callingUid,
13419            int userId) {
13420        intent = new Intent(intent);
13421
13422        // By default broadcasts do not go to stopped apps.
13423        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13424
13425        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13426            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13427            + " ordered=" + ordered + " userid=" + userId);
13428        if ((resultTo != null) && !ordered) {
13429            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13430        }
13431
13432        userId = handleIncomingUser(callingPid, callingUid, userId,
13433                true, false, "broadcast", callerPackage);
13434
13435        // Make sure that the user who is receiving this broadcast is started.
13436        // If not, we will just skip it.
13437        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13438            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13439                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13440                Slog.w(TAG, "Skipping broadcast of " + intent
13441                        + ": user " + userId + " is stopped");
13442                return ActivityManager.BROADCAST_SUCCESS;
13443            }
13444        }
13445
13446        /*
13447         * Prevent non-system code (defined here to be non-persistent
13448         * processes) from sending protected broadcasts.
13449         */
13450        int callingAppId = UserHandle.getAppId(callingUid);
13451        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13452            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13453            callingUid == 0) {
13454            // Always okay.
13455        } else if (callerApp == null || !callerApp.persistent) {
13456            try {
13457                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13458                        intent.getAction())) {
13459                    String msg = "Permission Denial: not allowed to send broadcast "
13460                            + intent.getAction() + " from pid="
13461                            + callingPid + ", uid=" + callingUid;
13462                    Slog.w(TAG, msg);
13463                    throw new SecurityException(msg);
13464                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13465                    // Special case for compatibility: we don't want apps to send this,
13466                    // but historically it has not been protected and apps may be using it
13467                    // to poke their own app widget.  So, instead of making it protected,
13468                    // just limit it to the caller.
13469                    if (callerApp == null) {
13470                        String msg = "Permission Denial: not allowed to send broadcast "
13471                                + intent.getAction() + " from unknown caller.";
13472                        Slog.w(TAG, msg);
13473                        throw new SecurityException(msg);
13474                    } else if (intent.getComponent() != null) {
13475                        // They are good enough to send to an explicit component...  verify
13476                        // it is being sent to the calling app.
13477                        if (!intent.getComponent().getPackageName().equals(
13478                                callerApp.info.packageName)) {
13479                            String msg = "Permission Denial: not allowed to send broadcast "
13480                                    + intent.getAction() + " to "
13481                                    + intent.getComponent().getPackageName() + " from "
13482                                    + callerApp.info.packageName;
13483                            Slog.w(TAG, msg);
13484                            throw new SecurityException(msg);
13485                        }
13486                    } else {
13487                        // Limit broadcast to their own package.
13488                        intent.setPackage(callerApp.info.packageName);
13489                    }
13490                }
13491            } catch (RemoteException e) {
13492                Slog.w(TAG, "Remote exception", e);
13493                return ActivityManager.BROADCAST_SUCCESS;
13494            }
13495        }
13496
13497        // Handle special intents: if this broadcast is from the package
13498        // manager about a package being removed, we need to remove all of
13499        // its activities from the history stack.
13500        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13501                intent.getAction());
13502        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13503                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13504                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13505                || uidRemoved) {
13506            if (checkComponentPermission(
13507                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13508                    callingPid, callingUid, -1, true)
13509                    == PackageManager.PERMISSION_GRANTED) {
13510                if (uidRemoved) {
13511                    final Bundle intentExtras = intent.getExtras();
13512                    final int uid = intentExtras != null
13513                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13514                    if (uid >= 0) {
13515                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13516                        synchronized (bs) {
13517                            bs.removeUidStatsLocked(uid);
13518                        }
13519                        mAppOpsService.uidRemoved(uid);
13520                    }
13521                } else {
13522                    // If resources are unavailable just force stop all
13523                    // those packages and flush the attribute cache as well.
13524                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13525                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13526                        if (list != null && (list.length > 0)) {
13527                            for (String pkg : list) {
13528                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13529                                        "storage unmount");
13530                            }
13531                            sendPackageBroadcastLocked(
13532                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13533                        }
13534                    } else {
13535                        Uri data = intent.getData();
13536                        String ssp;
13537                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13538                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13539                                    intent.getAction());
13540                            boolean fullUninstall = removed &&
13541                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13542                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13543                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13544                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13545                                        false, fullUninstall, userId,
13546                                        removed ? "pkg removed" : "pkg changed");
13547                            }
13548                            if (removed) {
13549                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13550                                        new String[] {ssp}, userId);
13551                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13552                                    mAppOpsService.packageRemoved(
13553                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13554
13555                                    // Remove all permissions granted from/to this package
13556                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13557                                }
13558                            }
13559                        }
13560                    }
13561                }
13562            } else {
13563                String msg = "Permission Denial: " + intent.getAction()
13564                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13565                        + ", uid=" + callingUid + ")"
13566                        + " requires "
13567                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13568                Slog.w(TAG, msg);
13569                throw new SecurityException(msg);
13570            }
13571
13572        // Special case for adding a package: by default turn on compatibility
13573        // mode.
13574        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13575            Uri data = intent.getData();
13576            String ssp;
13577            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13578                mCompatModePackages.handlePackageAddedLocked(ssp,
13579                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13580            }
13581        }
13582
13583        /*
13584         * If this is the time zone changed action, queue up a message that will reset the timezone
13585         * of all currently running processes. This message will get queued up before the broadcast
13586         * happens.
13587         */
13588        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13589            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13590        }
13591
13592        /*
13593         * If the user set the time, let all running processes know.
13594         */
13595        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
13596            final int is24Hour = intent.getBooleanExtra(
13597                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
13598            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
13599        }
13600
13601        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13602            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13603        }
13604
13605        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13606            ProxyProperties proxy = intent.getParcelableExtra("proxy");
13607            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13608        }
13609
13610        // Add to the sticky list if requested.
13611        if (sticky) {
13612            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13613                    callingPid, callingUid)
13614                    != PackageManager.PERMISSION_GRANTED) {
13615                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13616                        + callingPid + ", uid=" + callingUid
13617                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13618                Slog.w(TAG, msg);
13619                throw new SecurityException(msg);
13620            }
13621            if (requiredPermission != null) {
13622                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13623                        + " and enforce permission " + requiredPermission);
13624                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13625            }
13626            if (intent.getComponent() != null) {
13627                throw new SecurityException(
13628                        "Sticky broadcasts can't target a specific component");
13629            }
13630            // We use userId directly here, since the "all" target is maintained
13631            // as a separate set of sticky broadcasts.
13632            if (userId != UserHandle.USER_ALL) {
13633                // But first, if this is not a broadcast to all users, then
13634                // make sure it doesn't conflict with an existing broadcast to
13635                // all users.
13636                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13637                        UserHandle.USER_ALL);
13638                if (stickies != null) {
13639                    ArrayList<Intent> list = stickies.get(intent.getAction());
13640                    if (list != null) {
13641                        int N = list.size();
13642                        int i;
13643                        for (i=0; i<N; i++) {
13644                            if (intent.filterEquals(list.get(i))) {
13645                                throw new IllegalArgumentException(
13646                                        "Sticky broadcast " + intent + " for user "
13647                                        + userId + " conflicts with existing global broadcast");
13648                            }
13649                        }
13650                    }
13651                }
13652            }
13653            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13654            if (stickies == null) {
13655                stickies = new ArrayMap<String, ArrayList<Intent>>();
13656                mStickyBroadcasts.put(userId, stickies);
13657            }
13658            ArrayList<Intent> list = stickies.get(intent.getAction());
13659            if (list == null) {
13660                list = new ArrayList<Intent>();
13661                stickies.put(intent.getAction(), list);
13662            }
13663            int N = list.size();
13664            int i;
13665            for (i=0; i<N; i++) {
13666                if (intent.filterEquals(list.get(i))) {
13667                    // This sticky already exists, replace it.
13668                    list.set(i, new Intent(intent));
13669                    break;
13670                }
13671            }
13672            if (i >= N) {
13673                list.add(new Intent(intent));
13674            }
13675        }
13676
13677        int[] users;
13678        if (userId == UserHandle.USER_ALL) {
13679            // Caller wants broadcast to go to all started users.
13680            users = mStartedUserArray;
13681        } else {
13682            // Caller wants broadcast to go to one specific user.
13683            users = new int[] {userId};
13684        }
13685
13686        // Figure out who all will receive this broadcast.
13687        List receivers = null;
13688        List<BroadcastFilter> registeredReceivers = null;
13689        // Need to resolve the intent to interested receivers...
13690        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13691                 == 0) {
13692            receivers = collectReceiverComponents(intent, resolvedType, users);
13693        }
13694        if (intent.getComponent() == null) {
13695            registeredReceivers = mReceiverResolver.queryIntent(intent,
13696                    resolvedType, false, userId);
13697        }
13698
13699        final boolean replacePending =
13700                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13701
13702        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13703                + " replacePending=" + replacePending);
13704
13705        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13706        if (!ordered && NR > 0) {
13707            // If we are not serializing this broadcast, then send the
13708            // registered receivers separately so they don't wait for the
13709            // components to be launched.
13710            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13711            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13712                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13713                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13714                    ordered, sticky, false, userId);
13715            if (DEBUG_BROADCAST) Slog.v(
13716                    TAG, "Enqueueing parallel broadcast " + r);
13717            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13718            if (!replaced) {
13719                queue.enqueueParallelBroadcastLocked(r);
13720                queue.scheduleBroadcastsLocked();
13721            }
13722            registeredReceivers = null;
13723            NR = 0;
13724        }
13725
13726        // Merge into one list.
13727        int ir = 0;
13728        if (receivers != null) {
13729            // A special case for PACKAGE_ADDED: do not allow the package
13730            // being added to see this broadcast.  This prevents them from
13731            // using this as a back door to get run as soon as they are
13732            // installed.  Maybe in the future we want to have a special install
13733            // broadcast or such for apps, but we'd like to deliberately make
13734            // this decision.
13735            String skipPackages[] = null;
13736            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13737                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13738                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13739                Uri data = intent.getData();
13740                if (data != null) {
13741                    String pkgName = data.getSchemeSpecificPart();
13742                    if (pkgName != null) {
13743                        skipPackages = new String[] { pkgName };
13744                    }
13745                }
13746            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13747                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13748            }
13749            if (skipPackages != null && (skipPackages.length > 0)) {
13750                for (String skipPackage : skipPackages) {
13751                    if (skipPackage != null) {
13752                        int NT = receivers.size();
13753                        for (int it=0; it<NT; it++) {
13754                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
13755                            if (curt.activityInfo.packageName.equals(skipPackage)) {
13756                                receivers.remove(it);
13757                                it--;
13758                                NT--;
13759                            }
13760                        }
13761                    }
13762                }
13763            }
13764
13765            int NT = receivers != null ? receivers.size() : 0;
13766            int it = 0;
13767            ResolveInfo curt = null;
13768            BroadcastFilter curr = null;
13769            while (it < NT && ir < NR) {
13770                if (curt == null) {
13771                    curt = (ResolveInfo)receivers.get(it);
13772                }
13773                if (curr == null) {
13774                    curr = registeredReceivers.get(ir);
13775                }
13776                if (curr.getPriority() >= curt.priority) {
13777                    // Insert this broadcast record into the final list.
13778                    receivers.add(it, curr);
13779                    ir++;
13780                    curr = null;
13781                    it++;
13782                    NT++;
13783                } else {
13784                    // Skip to the next ResolveInfo in the final list.
13785                    it++;
13786                    curt = null;
13787                }
13788            }
13789        }
13790        while (ir < NR) {
13791            if (receivers == null) {
13792                receivers = new ArrayList();
13793            }
13794            receivers.add(registeredReceivers.get(ir));
13795            ir++;
13796        }
13797
13798        if ((receivers != null && receivers.size() > 0)
13799                || resultTo != null) {
13800            BroadcastQueue queue = broadcastQueueForIntent(intent);
13801            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13802                    callerPackage, callingPid, callingUid, resolvedType,
13803                    requiredPermission, appOp, receivers, resultTo, resultCode,
13804                    resultData, map, ordered, sticky, false, userId);
13805            if (DEBUG_BROADCAST) Slog.v(
13806                    TAG, "Enqueueing ordered broadcast " + r
13807                    + ": prev had " + queue.mOrderedBroadcasts.size());
13808            if (DEBUG_BROADCAST) {
13809                int seq = r.intent.getIntExtra("seq", -1);
13810                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
13811            }
13812            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
13813            if (!replaced) {
13814                queue.enqueueOrderedBroadcastLocked(r);
13815                queue.scheduleBroadcastsLocked();
13816            }
13817        }
13818
13819        return ActivityManager.BROADCAST_SUCCESS;
13820    }
13821
13822    final Intent verifyBroadcastLocked(Intent intent) {
13823        // Refuse possible leaked file descriptors
13824        if (intent != null && intent.hasFileDescriptors() == true) {
13825            throw new IllegalArgumentException("File descriptors passed in Intent");
13826        }
13827
13828        int flags = intent.getFlags();
13829
13830        if (!mProcessesReady) {
13831            // if the caller really truly claims to know what they're doing, go
13832            // ahead and allow the broadcast without launching any receivers
13833            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
13834                intent = new Intent(intent);
13835                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13836            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
13837                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
13838                        + " before boot completion");
13839                throw new IllegalStateException("Cannot broadcast before boot completed");
13840            }
13841        }
13842
13843        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
13844            throw new IllegalArgumentException(
13845                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
13846        }
13847
13848        return intent;
13849    }
13850
13851    public final int broadcastIntent(IApplicationThread caller,
13852            Intent intent, String resolvedType, IIntentReceiver resultTo,
13853            int resultCode, String resultData, Bundle map,
13854            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
13855        enforceNotIsolatedCaller("broadcastIntent");
13856        synchronized(this) {
13857            intent = verifyBroadcastLocked(intent);
13858
13859            final ProcessRecord callerApp = getRecordForAppLocked(caller);
13860            final int callingPid = Binder.getCallingPid();
13861            final int callingUid = Binder.getCallingUid();
13862            final long origId = Binder.clearCallingIdentity();
13863            int res = broadcastIntentLocked(callerApp,
13864                    callerApp != null ? callerApp.info.packageName : null,
13865                    intent, resolvedType, resultTo,
13866                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
13867                    callingPid, callingUid, userId);
13868            Binder.restoreCallingIdentity(origId);
13869            return res;
13870        }
13871    }
13872
13873    int broadcastIntentInPackage(String packageName, int uid,
13874            Intent intent, String resolvedType, IIntentReceiver resultTo,
13875            int resultCode, String resultData, Bundle map,
13876            String requiredPermission, boolean serialized, boolean sticky, int userId) {
13877        synchronized(this) {
13878            intent = verifyBroadcastLocked(intent);
13879
13880            final long origId = Binder.clearCallingIdentity();
13881            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
13882                    resultTo, resultCode, resultData, map, requiredPermission,
13883                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
13884            Binder.restoreCallingIdentity(origId);
13885            return res;
13886        }
13887    }
13888
13889    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
13890        // Refuse possible leaked file descriptors
13891        if (intent != null && intent.hasFileDescriptors() == true) {
13892            throw new IllegalArgumentException("File descriptors passed in Intent");
13893        }
13894
13895        userId = handleIncomingUser(Binder.getCallingPid(),
13896                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
13897
13898        synchronized(this) {
13899            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
13900                    != PackageManager.PERMISSION_GRANTED) {
13901                String msg = "Permission Denial: unbroadcastIntent() from pid="
13902                        + Binder.getCallingPid()
13903                        + ", uid=" + Binder.getCallingUid()
13904                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13905                Slog.w(TAG, msg);
13906                throw new SecurityException(msg);
13907            }
13908            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13909            if (stickies != null) {
13910                ArrayList<Intent> list = stickies.get(intent.getAction());
13911                if (list != null) {
13912                    int N = list.size();
13913                    int i;
13914                    for (i=0; i<N; i++) {
13915                        if (intent.filterEquals(list.get(i))) {
13916                            list.remove(i);
13917                            break;
13918                        }
13919                    }
13920                    if (list.size() <= 0) {
13921                        stickies.remove(intent.getAction());
13922                    }
13923                }
13924                if (stickies.size() <= 0) {
13925                    mStickyBroadcasts.remove(userId);
13926                }
13927            }
13928        }
13929    }
13930
13931    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
13932            String resultData, Bundle resultExtras, boolean resultAbort) {
13933        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
13934        if (r == null) {
13935            Slog.w(TAG, "finishReceiver called but not found on queue");
13936            return false;
13937        }
13938
13939        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
13940    }
13941
13942    void backgroundServicesFinishedLocked(int userId) {
13943        for (BroadcastQueue queue : mBroadcastQueues) {
13944            queue.backgroundServicesFinishedLocked(userId);
13945        }
13946    }
13947
13948    public void finishReceiver(IBinder who, int resultCode, String resultData,
13949            Bundle resultExtras, boolean resultAbort) {
13950        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
13951
13952        // Refuse possible leaked file descriptors
13953        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
13954            throw new IllegalArgumentException("File descriptors passed in Bundle");
13955        }
13956
13957        final long origId = Binder.clearCallingIdentity();
13958        try {
13959            boolean doNext = false;
13960            BroadcastRecord r;
13961
13962            synchronized(this) {
13963                r = broadcastRecordForReceiverLocked(who);
13964                if (r != null) {
13965                    doNext = r.queue.finishReceiverLocked(r, resultCode,
13966                        resultData, resultExtras, resultAbort, true);
13967                }
13968            }
13969
13970            if (doNext) {
13971                r.queue.processNextBroadcast(false);
13972            }
13973            trimApplications();
13974        } finally {
13975            Binder.restoreCallingIdentity(origId);
13976        }
13977    }
13978
13979    // =========================================================
13980    // INSTRUMENTATION
13981    // =========================================================
13982
13983    public boolean startInstrumentation(ComponentName className,
13984            String profileFile, int flags, Bundle arguments,
13985            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
13986            int userId) {
13987        enforceNotIsolatedCaller("startInstrumentation");
13988        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
13989                userId, false, true, "startInstrumentation", null);
13990        // Refuse possible leaked file descriptors
13991        if (arguments != null && arguments.hasFileDescriptors()) {
13992            throw new IllegalArgumentException("File descriptors passed in Bundle");
13993        }
13994
13995        synchronized(this) {
13996            InstrumentationInfo ii = null;
13997            ApplicationInfo ai = null;
13998            try {
13999                ii = mContext.getPackageManager().getInstrumentationInfo(
14000                    className, STOCK_PM_FLAGS);
14001                ai = AppGlobals.getPackageManager().getApplicationInfo(
14002                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14003            } catch (PackageManager.NameNotFoundException e) {
14004            } catch (RemoteException e) {
14005            }
14006            if (ii == null) {
14007                reportStartInstrumentationFailure(watcher, className,
14008                        "Unable to find instrumentation info for: " + className);
14009                return false;
14010            }
14011            if (ai == null) {
14012                reportStartInstrumentationFailure(watcher, className,
14013                        "Unable to find instrumentation target package: " + ii.targetPackage);
14014                return false;
14015            }
14016
14017            int match = mContext.getPackageManager().checkSignatures(
14018                    ii.targetPackage, ii.packageName);
14019            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14020                String msg = "Permission Denial: starting instrumentation "
14021                        + className + " from pid="
14022                        + Binder.getCallingPid()
14023                        + ", uid=" + Binder.getCallingPid()
14024                        + " not allowed because package " + ii.packageName
14025                        + " does not have a signature matching the target "
14026                        + ii.targetPackage;
14027                reportStartInstrumentationFailure(watcher, className, msg);
14028                throw new SecurityException(msg);
14029            }
14030
14031            final long origId = Binder.clearCallingIdentity();
14032            // Instrumentation can kill and relaunch even persistent processes
14033            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14034                    "start instr");
14035            ProcessRecord app = addAppLocked(ai, false);
14036            app.instrumentationClass = className;
14037            app.instrumentationInfo = ai;
14038            app.instrumentationProfileFile = profileFile;
14039            app.instrumentationArguments = arguments;
14040            app.instrumentationWatcher = watcher;
14041            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14042            app.instrumentationResultClass = className;
14043            Binder.restoreCallingIdentity(origId);
14044        }
14045
14046        return true;
14047    }
14048
14049    /**
14050     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14051     * error to the logs, but if somebody is watching, send the report there too.  This enables
14052     * the "am" command to report errors with more information.
14053     *
14054     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14055     * @param cn The component name of the instrumentation.
14056     * @param report The error report.
14057     */
14058    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14059            ComponentName cn, String report) {
14060        Slog.w(TAG, report);
14061        try {
14062            if (watcher != null) {
14063                Bundle results = new Bundle();
14064                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14065                results.putString("Error", report);
14066                watcher.instrumentationStatus(cn, -1, results);
14067            }
14068        } catch (RemoteException e) {
14069            Slog.w(TAG, e);
14070        }
14071    }
14072
14073    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14074        if (app.instrumentationWatcher != null) {
14075            try {
14076                // NOTE:  IInstrumentationWatcher *must* be oneway here
14077                app.instrumentationWatcher.instrumentationFinished(
14078                    app.instrumentationClass,
14079                    resultCode,
14080                    results);
14081            } catch (RemoteException e) {
14082            }
14083        }
14084        if (app.instrumentationUiAutomationConnection != null) {
14085            try {
14086                app.instrumentationUiAutomationConnection.shutdown();
14087            } catch (RemoteException re) {
14088                /* ignore */
14089            }
14090            // Only a UiAutomation can set this flag and now that
14091            // it is finished we make sure it is reset to its default.
14092            mUserIsMonkey = false;
14093        }
14094        app.instrumentationWatcher = null;
14095        app.instrumentationUiAutomationConnection = null;
14096        app.instrumentationClass = null;
14097        app.instrumentationInfo = null;
14098        app.instrumentationProfileFile = null;
14099        app.instrumentationArguments = null;
14100
14101        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14102                "finished inst");
14103    }
14104
14105    public void finishInstrumentation(IApplicationThread target,
14106            int resultCode, Bundle results) {
14107        int userId = UserHandle.getCallingUserId();
14108        // Refuse possible leaked file descriptors
14109        if (results != null && results.hasFileDescriptors()) {
14110            throw new IllegalArgumentException("File descriptors passed in Intent");
14111        }
14112
14113        synchronized(this) {
14114            ProcessRecord app = getRecordForAppLocked(target);
14115            if (app == null) {
14116                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14117                return;
14118            }
14119            final long origId = Binder.clearCallingIdentity();
14120            finishInstrumentationLocked(app, resultCode, results);
14121            Binder.restoreCallingIdentity(origId);
14122        }
14123    }
14124
14125    // =========================================================
14126    // CONFIGURATION
14127    // =========================================================
14128
14129    public ConfigurationInfo getDeviceConfigurationInfo() {
14130        ConfigurationInfo config = new ConfigurationInfo();
14131        synchronized (this) {
14132            config.reqTouchScreen = mConfiguration.touchscreen;
14133            config.reqKeyboardType = mConfiguration.keyboard;
14134            config.reqNavigation = mConfiguration.navigation;
14135            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14136                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14137                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14138            }
14139            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14140                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14141                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14142            }
14143            config.reqGlEsVersion = GL_ES_VERSION;
14144        }
14145        return config;
14146    }
14147
14148    ActivityStack getFocusedStack() {
14149        return mStackSupervisor.getFocusedStack();
14150    }
14151
14152    public Configuration getConfiguration() {
14153        Configuration ci;
14154        synchronized(this) {
14155            ci = new Configuration(mConfiguration);
14156        }
14157        return ci;
14158    }
14159
14160    public void updatePersistentConfiguration(Configuration values) {
14161        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14162                "updateConfiguration()");
14163        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14164                "updateConfiguration()");
14165        if (values == null) {
14166            throw new NullPointerException("Configuration must not be null");
14167        }
14168
14169        synchronized(this) {
14170            final long origId = Binder.clearCallingIdentity();
14171            updateConfigurationLocked(values, null, true, false);
14172            Binder.restoreCallingIdentity(origId);
14173        }
14174    }
14175
14176    public void updateConfiguration(Configuration values) {
14177        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14178                "updateConfiguration()");
14179
14180        synchronized(this) {
14181            if (values == null && mWindowManager != null) {
14182                // sentinel: fetch the current configuration from the window manager
14183                values = mWindowManager.computeNewConfiguration();
14184            }
14185
14186            if (mWindowManager != null) {
14187                mProcessList.applyDisplaySize(mWindowManager);
14188            }
14189
14190            final long origId = Binder.clearCallingIdentity();
14191            if (values != null) {
14192                Settings.System.clearConfiguration(values);
14193            }
14194            updateConfigurationLocked(values, null, false, false);
14195            Binder.restoreCallingIdentity(origId);
14196        }
14197    }
14198
14199    /**
14200     * Do either or both things: (1) change the current configuration, and (2)
14201     * make sure the given activity is running with the (now) current
14202     * configuration.  Returns true if the activity has been left running, or
14203     * false if <var>starting</var> is being destroyed to match the new
14204     * configuration.
14205     * @param persistent TODO
14206     */
14207    boolean updateConfigurationLocked(Configuration values,
14208            ActivityRecord starting, boolean persistent, boolean initLocale) {
14209        int changes = 0;
14210
14211        if (values != null) {
14212            Configuration newConfig = new Configuration(mConfiguration);
14213            changes = newConfig.updateFrom(values);
14214            if (changes != 0) {
14215                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14216                    Slog.i(TAG, "Updating configuration to: " + values);
14217                }
14218
14219                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14220
14221                if (values.locale != null && !initLocale) {
14222                    saveLocaleLocked(values.locale,
14223                                     !values.locale.equals(mConfiguration.locale),
14224                                     values.userSetLocale);
14225                }
14226
14227                mConfigurationSeq++;
14228                if (mConfigurationSeq <= 0) {
14229                    mConfigurationSeq = 1;
14230                }
14231                newConfig.seq = mConfigurationSeq;
14232                mConfiguration = newConfig;
14233                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14234
14235                final Configuration configCopy = new Configuration(mConfiguration);
14236
14237                // TODO: If our config changes, should we auto dismiss any currently
14238                // showing dialogs?
14239                mShowDialogs = shouldShowDialogs(newConfig);
14240
14241                AttributeCache ac = AttributeCache.instance();
14242                if (ac != null) {
14243                    ac.updateConfiguration(configCopy);
14244                }
14245
14246                // Make sure all resources in our process are updated
14247                // right now, so that anyone who is going to retrieve
14248                // resource values after we return will be sure to get
14249                // the new ones.  This is especially important during
14250                // boot, where the first config change needs to guarantee
14251                // all resources have that config before following boot
14252                // code is executed.
14253                mSystemThread.applyConfigurationToResources(configCopy);
14254
14255                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14256                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14257                    msg.obj = new Configuration(configCopy);
14258                    mHandler.sendMessage(msg);
14259                }
14260
14261                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14262                    ProcessRecord app = mLruProcesses.get(i);
14263                    try {
14264                        if (app.thread != null) {
14265                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14266                                    + app.processName + " new config " + mConfiguration);
14267                            app.thread.scheduleConfigurationChanged(configCopy);
14268                        }
14269                    } catch (Exception e) {
14270                    }
14271                }
14272                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14273                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14274                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14275                        | Intent.FLAG_RECEIVER_FOREGROUND);
14276                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14277                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14278                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14279                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14280                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14281                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14282                    broadcastIntentLocked(null, null, intent,
14283                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14284                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14285                }
14286            }
14287        }
14288
14289        boolean kept = true;
14290        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14291        // mainStack is null during startup.
14292        if (mainStack != null) {
14293            if (changes != 0 && starting == null) {
14294                // If the configuration changed, and the caller is not already
14295                // in the process of starting an activity, then find the top
14296                // activity to check if its configuration needs to change.
14297                starting = mainStack.topRunningActivityLocked(null);
14298            }
14299
14300            if (starting != null) {
14301                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14302                // And we need to make sure at this point that all other activities
14303                // are made visible with the correct configuration.
14304                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14305            }
14306        }
14307
14308        if (values != null && mWindowManager != null) {
14309            mWindowManager.setNewConfiguration(mConfiguration);
14310        }
14311
14312        return kept;
14313    }
14314
14315    /**
14316     * Decide based on the configuration whether we should shouw the ANR,
14317     * crash, etc dialogs.  The idea is that if there is no affordnace to
14318     * press the on-screen buttons, we shouldn't show the dialog.
14319     *
14320     * A thought: SystemUI might also want to get told about this, the Power
14321     * dialog / global actions also might want different behaviors.
14322     */
14323    private static final boolean shouldShowDialogs(Configuration config) {
14324        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14325                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14326    }
14327
14328    /**
14329     * Save the locale.  You must be inside a synchronized (this) block.
14330     */
14331    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14332        if(isDiff) {
14333            SystemProperties.set("user.language", l.getLanguage());
14334            SystemProperties.set("user.region", l.getCountry());
14335        }
14336
14337        if(isPersist) {
14338            SystemProperties.set("persist.sys.language", l.getLanguage());
14339            SystemProperties.set("persist.sys.country", l.getCountry());
14340            SystemProperties.set("persist.sys.localevar", l.getVariant());
14341        }
14342    }
14343
14344    @Override
14345    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14346        ActivityRecord srec = ActivityRecord.forToken(token);
14347        return srec != null && srec.task.affinity != null &&
14348                srec.task.affinity.equals(destAffinity);
14349    }
14350
14351    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14352            Intent resultData) {
14353
14354        synchronized (this) {
14355            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14356            if (stack != null) {
14357                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14358            }
14359            return false;
14360        }
14361    }
14362
14363    public int getLaunchedFromUid(IBinder activityToken) {
14364        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14365        if (srec == null) {
14366            return -1;
14367        }
14368        return srec.launchedFromUid;
14369    }
14370
14371    public String getLaunchedFromPackage(IBinder activityToken) {
14372        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14373        if (srec == null) {
14374            return null;
14375        }
14376        return srec.launchedFromPackage;
14377    }
14378
14379    // =========================================================
14380    // LIFETIME MANAGEMENT
14381    // =========================================================
14382
14383    // Returns which broadcast queue the app is the current [or imminent] receiver
14384    // on, or 'null' if the app is not an active broadcast recipient.
14385    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14386        BroadcastRecord r = app.curReceiver;
14387        if (r != null) {
14388            return r.queue;
14389        }
14390
14391        // It's not the current receiver, but it might be starting up to become one
14392        synchronized (this) {
14393            for (BroadcastQueue queue : mBroadcastQueues) {
14394                r = queue.mPendingBroadcast;
14395                if (r != null && r.curApp == app) {
14396                    // found it; report which queue it's in
14397                    return queue;
14398                }
14399            }
14400        }
14401
14402        return null;
14403    }
14404
14405    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14406            boolean doingAll, long now) {
14407        if (mAdjSeq == app.adjSeq) {
14408            // This adjustment has already been computed.
14409            return app.curRawAdj;
14410        }
14411
14412        if (app.thread == null) {
14413            app.adjSeq = mAdjSeq;
14414            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14415            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14416            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14417        }
14418
14419        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14420        app.adjSource = null;
14421        app.adjTarget = null;
14422        app.empty = false;
14423        app.cached = false;
14424
14425        final int activitiesSize = app.activities.size();
14426
14427        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14428            // The max adjustment doesn't allow this app to be anything
14429            // below foreground, so it is not worth doing work for it.
14430            app.adjType = "fixed";
14431            app.adjSeq = mAdjSeq;
14432            app.curRawAdj = app.maxAdj;
14433            app.foregroundActivities = false;
14434            app.keeping = true;
14435            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14436            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14437            // System process can do UI, and when they do we want to have
14438            // them trim their memory after the user leaves the UI.  To
14439            // facilitate this, here we need to determine whether or not it
14440            // is currently showing UI.
14441            app.systemNoUi = true;
14442            if (app == TOP_APP) {
14443                app.systemNoUi = false;
14444            } else if (activitiesSize > 0) {
14445                for (int j = 0; j < activitiesSize; j++) {
14446                    final ActivityRecord r = app.activities.get(j);
14447                    if (r.visible) {
14448                        app.systemNoUi = false;
14449                    }
14450                }
14451            }
14452            if (!app.systemNoUi) {
14453                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14454            }
14455            return (app.curAdj=app.maxAdj);
14456        }
14457
14458        app.keeping = false;
14459        app.systemNoUi = false;
14460
14461        // Determine the importance of the process, starting with most
14462        // important to least, and assign an appropriate OOM adjustment.
14463        int adj;
14464        int schedGroup;
14465        int procState;
14466        boolean foregroundActivities = false;
14467        boolean interesting = false;
14468        BroadcastQueue queue;
14469        if (app == TOP_APP) {
14470            // The last app on the list is the foreground app.
14471            adj = ProcessList.FOREGROUND_APP_ADJ;
14472            schedGroup = Process.THREAD_GROUP_DEFAULT;
14473            app.adjType = "top-activity";
14474            foregroundActivities = true;
14475            interesting = true;
14476            procState = ActivityManager.PROCESS_STATE_TOP;
14477        } else if (app.instrumentationClass != null) {
14478            // Don't want to kill running instrumentation.
14479            adj = ProcessList.FOREGROUND_APP_ADJ;
14480            schedGroup = Process.THREAD_GROUP_DEFAULT;
14481            app.adjType = "instrumentation";
14482            interesting = true;
14483            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14484        } else if ((queue = isReceivingBroadcast(app)) != null) {
14485            // An app that is currently receiving a broadcast also
14486            // counts as being in the foreground for OOM killer purposes.
14487            // It's placed in a sched group based on the nature of the
14488            // broadcast as reflected by which queue it's active in.
14489            adj = ProcessList.FOREGROUND_APP_ADJ;
14490            schedGroup = (queue == mFgBroadcastQueue)
14491                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14492            app.adjType = "broadcast";
14493            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14494        } else if (app.executingServices.size() > 0) {
14495            // An app that is currently executing a service callback also
14496            // counts as being in the foreground.
14497            adj = ProcessList.FOREGROUND_APP_ADJ;
14498            schedGroup = app.execServicesFg ?
14499                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14500            app.adjType = "exec-service";
14501            procState = ActivityManager.PROCESS_STATE_SERVICE;
14502            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14503        } else {
14504            // As far as we know the process is empty.  We may change our mind later.
14505            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14506            // At this point we don't actually know the adjustment.  Use the cached adj
14507            // value that the caller wants us to.
14508            adj = cachedAdj;
14509            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14510            app.cached = true;
14511            app.empty = true;
14512            app.adjType = "cch-empty";
14513        }
14514
14515        // Examine all activities if not already foreground.
14516        if (!foregroundActivities && activitiesSize > 0) {
14517            for (int j = 0; j < activitiesSize; j++) {
14518                final ActivityRecord r = app.activities.get(j);
14519                if (r.app != app) {
14520                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14521                            + app + "?!?");
14522                    continue;
14523                }
14524                if (r.visible) {
14525                    // App has a visible activity; only upgrade adjustment.
14526                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14527                        adj = ProcessList.VISIBLE_APP_ADJ;
14528                        app.adjType = "visible";
14529                    }
14530                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14531                        procState = ActivityManager.PROCESS_STATE_TOP;
14532                    }
14533                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14534                    app.cached = false;
14535                    app.empty = false;
14536                    foregroundActivities = true;
14537                    break;
14538                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14539                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14540                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14541                        app.adjType = "pausing";
14542                    }
14543                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14544                        procState = ActivityManager.PROCESS_STATE_TOP;
14545                    }
14546                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14547                    app.cached = false;
14548                    app.empty = false;
14549                    foregroundActivities = true;
14550                } else if (r.state == ActivityState.STOPPING) {
14551                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14552                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14553                        app.adjType = "stopping";
14554                    }
14555                    // For the process state, we will at this point consider the
14556                    // process to be cached.  It will be cached either as an activity
14557                    // or empty depending on whether the activity is finishing.  We do
14558                    // this so that we can treat the process as cached for purposes of
14559                    // memory trimming (determing current memory level, trim command to
14560                    // send to process) since there can be an arbitrary number of stopping
14561                    // processes and they should soon all go into the cached state.
14562                    if (!r.finishing) {
14563                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14564                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14565                        }
14566                    }
14567                    app.cached = false;
14568                    app.empty = false;
14569                    foregroundActivities = true;
14570                } else {
14571                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14572                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14573                        app.adjType = "cch-act";
14574                    }
14575                }
14576            }
14577        }
14578
14579        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14580            if (app.foregroundServices) {
14581                // The user is aware of this app, so make it visible.
14582                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14583                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14584                app.cached = false;
14585                app.adjType = "fg-service";
14586                schedGroup = Process.THREAD_GROUP_DEFAULT;
14587            } else if (app.forcingToForeground != null) {
14588                // The user is aware of this app, so make it visible.
14589                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14590                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14591                app.cached = false;
14592                app.adjType = "force-fg";
14593                app.adjSource = app.forcingToForeground;
14594                schedGroup = Process.THREAD_GROUP_DEFAULT;
14595            }
14596        }
14597
14598        if (app.foregroundServices) {
14599            interesting = true;
14600        }
14601
14602        if (app == mHeavyWeightProcess) {
14603            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14604                // We don't want to kill the current heavy-weight process.
14605                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14606                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14607                app.cached = false;
14608                app.adjType = "heavy";
14609            }
14610            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14611                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14612            }
14613        }
14614
14615        if (app == mHomeProcess) {
14616            if (adj > ProcessList.HOME_APP_ADJ) {
14617                // This process is hosting what we currently consider to be the
14618                // home app, so we don't want to let it go into the background.
14619                adj = ProcessList.HOME_APP_ADJ;
14620                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14621                app.cached = false;
14622                app.adjType = "home";
14623            }
14624            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14625                procState = ActivityManager.PROCESS_STATE_HOME;
14626            }
14627        }
14628
14629        if (app == mPreviousProcess && app.activities.size() > 0) {
14630            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14631                // This was the previous process that showed UI to the user.
14632                // We want to try to keep it around more aggressively, to give
14633                // a good experience around switching between two apps.
14634                adj = ProcessList.PREVIOUS_APP_ADJ;
14635                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14636                app.cached = false;
14637                app.adjType = "previous";
14638            }
14639            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14640                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14641            }
14642        }
14643
14644        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14645                + " reason=" + app.adjType);
14646
14647        // By default, we use the computed adjustment.  It may be changed if
14648        // there are applications dependent on our services or providers, but
14649        // this gives us a baseline and makes sure we don't get into an
14650        // infinite recursion.
14651        app.adjSeq = mAdjSeq;
14652        app.curRawAdj = adj;
14653        app.hasStartedServices = false;
14654
14655        if (mBackupTarget != null && app == mBackupTarget.app) {
14656            // If possible we want to avoid killing apps while they're being backed up
14657            if (adj > ProcessList.BACKUP_APP_ADJ) {
14658                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14659                adj = ProcessList.BACKUP_APP_ADJ;
14660                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14661                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14662                }
14663                app.adjType = "backup";
14664                app.cached = false;
14665            }
14666            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14667                procState = ActivityManager.PROCESS_STATE_BACKUP;
14668            }
14669        }
14670
14671        boolean mayBeTop = false;
14672
14673        for (int is = app.services.size()-1;
14674                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14675                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14676                        || procState > ActivityManager.PROCESS_STATE_TOP);
14677                is--) {
14678            ServiceRecord s = app.services.valueAt(is);
14679            if (s.startRequested) {
14680                app.hasStartedServices = true;
14681                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14682                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14683                }
14684                if (app.hasShownUi && app != mHomeProcess) {
14685                    // If this process has shown some UI, let it immediately
14686                    // go to the LRU list because it may be pretty heavy with
14687                    // UI stuff.  We'll tag it with a label just to help
14688                    // debug and understand what is going on.
14689                    if (adj > ProcessList.SERVICE_ADJ) {
14690                        app.adjType = "cch-started-ui-services";
14691                    }
14692                } else {
14693                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14694                        // This service has seen some activity within
14695                        // recent memory, so we will keep its process ahead
14696                        // of the background processes.
14697                        if (adj > ProcessList.SERVICE_ADJ) {
14698                            adj = ProcessList.SERVICE_ADJ;
14699                            app.adjType = "started-services";
14700                            app.cached = false;
14701                        }
14702                    }
14703                    // If we have let the service slide into the background
14704                    // state, still have some text describing what it is doing
14705                    // even though the service no longer has an impact.
14706                    if (adj > ProcessList.SERVICE_ADJ) {
14707                        app.adjType = "cch-started-services";
14708                    }
14709                }
14710                // Don't kill this process because it is doing work; it
14711                // has said it is doing work.
14712                app.keeping = true;
14713            }
14714            for (int conni = s.connections.size()-1;
14715                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14716                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14717                            || procState > ActivityManager.PROCESS_STATE_TOP);
14718                    conni--) {
14719                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14720                for (int i = 0;
14721                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14722                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14723                                || procState > ActivityManager.PROCESS_STATE_TOP);
14724                        i++) {
14725                    // XXX should compute this based on the max of
14726                    // all connected clients.
14727                    ConnectionRecord cr = clist.get(i);
14728                    if (cr.binding.client == app) {
14729                        // Binding to ourself is not interesting.
14730                        continue;
14731                    }
14732                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14733                        ProcessRecord client = cr.binding.client;
14734                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14735                                TOP_APP, doingAll, now);
14736                        int clientProcState = client.curProcState;
14737                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14738                            // If the other app is cached for any reason, for purposes here
14739                            // we are going to consider it empty.  The specific cached state
14740                            // doesn't propagate except under certain conditions.
14741                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14742                        }
14743                        String adjType = null;
14744                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14745                            // Not doing bind OOM management, so treat
14746                            // this guy more like a started service.
14747                            if (app.hasShownUi && app != mHomeProcess) {
14748                                // If this process has shown some UI, let it immediately
14749                                // go to the LRU list because it may be pretty heavy with
14750                                // UI stuff.  We'll tag it with a label just to help
14751                                // debug and understand what is going on.
14752                                if (adj > clientAdj) {
14753                                    adjType = "cch-bound-ui-services";
14754                                }
14755                                app.cached = false;
14756                                clientAdj = adj;
14757                                clientProcState = procState;
14758                            } else {
14759                                if (now >= (s.lastActivity
14760                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14761                                    // This service has not seen activity within
14762                                    // recent memory, so allow it to drop to the
14763                                    // LRU list if there is no other reason to keep
14764                                    // it around.  We'll also tag it with a label just
14765                                    // to help debug and undertand what is going on.
14766                                    if (adj > clientAdj) {
14767                                        adjType = "cch-bound-services";
14768                                    }
14769                                    clientAdj = adj;
14770                                }
14771                            }
14772                        }
14773                        if (adj > clientAdj) {
14774                            // If this process has recently shown UI, and
14775                            // the process that is binding to it is less
14776                            // important than being visible, then we don't
14777                            // care about the binding as much as we care
14778                            // about letting this process get into the LRU
14779                            // list to be killed and restarted if needed for
14780                            // memory.
14781                            if (app.hasShownUi && app != mHomeProcess
14782                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14783                                adjType = "cch-bound-ui-services";
14784                            } else {
14785                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14786                                        |Context.BIND_IMPORTANT)) != 0) {
14787                                    adj = clientAdj;
14788                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14789                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14790                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14791                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14792                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
14793                                    adj = clientAdj;
14794                                } else {
14795                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14796                                        adj = ProcessList.VISIBLE_APP_ADJ;
14797                                    }
14798                                }
14799                                if (!client.cached) {
14800                                    app.cached = false;
14801                                }
14802                                if (client.keeping) {
14803                                    app.keeping = true;
14804                                }
14805                                adjType = "service";
14806                            }
14807                        }
14808                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14809                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14810                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14811                            }
14812                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14813                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14814                                    // Special handling of clients who are in the top state.
14815                                    // We *may* want to consider this process to be in the
14816                                    // top state as well, but only if there is not another
14817                                    // reason for it to be running.  Being on the top is a
14818                                    // special state, meaning you are specifically running
14819                                    // for the current top app.  If the process is already
14820                                    // running in the background for some other reason, it
14821                                    // is more important to continue considering it to be
14822                                    // in the background state.
14823                                    mayBeTop = true;
14824                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14825                                } else {
14826                                    // Special handling for above-top states (persistent
14827                                    // processes).  These should not bring the current process
14828                                    // into the top state, since they are not on top.  Instead
14829                                    // give them the best state after that.
14830                                    clientProcState =
14831                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14832                                }
14833                            }
14834                        } else {
14835                            if (clientProcState <
14836                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14837                                clientProcState =
14838                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14839                            }
14840                        }
14841                        if (procState > clientProcState) {
14842                            procState = clientProcState;
14843                        }
14844                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
14845                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
14846                            app.pendingUiClean = true;
14847                        }
14848                        if (adjType != null) {
14849                            app.adjType = adjType;
14850                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14851                                    .REASON_SERVICE_IN_USE;
14852                            app.adjSource = cr.binding.client;
14853                            app.adjSourceOom = clientAdj;
14854                            app.adjTarget = s.name;
14855                        }
14856                    }
14857                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
14858                        app.treatLikeActivity = true;
14859                    }
14860                    final ActivityRecord a = cr.activity;
14861                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
14862                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
14863                                (a.visible || a.state == ActivityState.RESUMED
14864                                 || a.state == ActivityState.PAUSING)) {
14865                            adj = ProcessList.FOREGROUND_APP_ADJ;
14866                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14867                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14868                            }
14869                            app.cached = false;
14870                            app.adjType = "service";
14871                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14872                                    .REASON_SERVICE_IN_USE;
14873                            app.adjSource = a;
14874                            app.adjSourceOom = adj;
14875                            app.adjTarget = s.name;
14876                        }
14877                    }
14878                }
14879            }
14880        }
14881
14882        for (int provi = app.pubProviders.size()-1;
14883                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14884                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14885                        || procState > ActivityManager.PROCESS_STATE_TOP);
14886                provi--) {
14887            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
14888            for (int i = cpr.connections.size()-1;
14889                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14890                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14891                            || procState > ActivityManager.PROCESS_STATE_TOP);
14892                    i--) {
14893                ContentProviderConnection conn = cpr.connections.get(i);
14894                ProcessRecord client = conn.client;
14895                if (client == app) {
14896                    // Being our own client is not interesting.
14897                    continue;
14898                }
14899                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
14900                int clientProcState = client.curProcState;
14901                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14902                    // If the other app is cached for any reason, for purposes here
14903                    // we are going to consider it empty.
14904                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14905                }
14906                if (adj > clientAdj) {
14907                    if (app.hasShownUi && app != mHomeProcess
14908                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14909                        app.adjType = "cch-ui-provider";
14910                    } else {
14911                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
14912                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
14913                        app.adjType = "provider";
14914                    }
14915                    app.cached &= client.cached;
14916                    app.keeping |= client.keeping;
14917                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14918                            .REASON_PROVIDER_IN_USE;
14919                    app.adjSource = client;
14920                    app.adjSourceOom = clientAdj;
14921                    app.adjTarget = cpr.name;
14922                }
14923                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14924                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14925                        // Special handling of clients who are in the top state.
14926                        // We *may* want to consider this process to be in the
14927                        // top state as well, but only if there is not another
14928                        // reason for it to be running.  Being on the top is a
14929                        // special state, meaning you are specifically running
14930                        // for the current top app.  If the process is already
14931                        // running in the background for some other reason, it
14932                        // is more important to continue considering it to be
14933                        // in the background state.
14934                        mayBeTop = true;
14935                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14936                    } else {
14937                        // Special handling for above-top states (persistent
14938                        // processes).  These should not bring the current process
14939                        // into the top state, since they are not on top.  Instead
14940                        // give them the best state after that.
14941                        clientProcState =
14942                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14943                    }
14944                }
14945                if (procState > clientProcState) {
14946                    procState = clientProcState;
14947                }
14948                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14949                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14950                }
14951            }
14952            // If the provider has external (non-framework) process
14953            // dependencies, ensure that its adjustment is at least
14954            // FOREGROUND_APP_ADJ.
14955            if (cpr.hasExternalProcessHandles()) {
14956                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
14957                    adj = ProcessList.FOREGROUND_APP_ADJ;
14958                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14959                    app.cached = false;
14960                    app.keeping = true;
14961                    app.adjType = "provider";
14962                    app.adjTarget = cpr.name;
14963                }
14964                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
14965                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14966                }
14967            }
14968        }
14969
14970        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
14971            // A client of one of our services or providers is in the top state.  We
14972            // *may* want to be in the top state, but not if we are already running in
14973            // the background for some other reason.  For the decision here, we are going
14974            // to pick out a few specific states that we want to remain in when a client
14975            // is top (states that tend to be longer-term) and otherwise allow it to go
14976            // to the top state.
14977            switch (procState) {
14978                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
14979                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
14980                case ActivityManager.PROCESS_STATE_SERVICE:
14981                    // These all are longer-term states, so pull them up to the top
14982                    // of the background states, but not all the way to the top state.
14983                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14984                    break;
14985                default:
14986                    // Otherwise, top is a better choice, so take it.
14987                    procState = ActivityManager.PROCESS_STATE_TOP;
14988                    break;
14989            }
14990        }
14991
14992        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
14993            if (app.hasClientActivities) {
14994                // This is a cached process, but with client activities.  Mark it so.
14995                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
14996                app.adjType = "cch-client-act";
14997            } else if (app.treatLikeActivity) {
14998                // This is a cached process, but somebody wants us to treat it like it has
14999                // an activity, okay!
15000                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15001                app.adjType = "cch-as-act";
15002            }
15003        }
15004
15005        if (adj == ProcessList.SERVICE_ADJ) {
15006            if (doingAll) {
15007                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15008                mNewNumServiceProcs++;
15009                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15010                if (!app.serviceb) {
15011                    // This service isn't far enough down on the LRU list to
15012                    // normally be a B service, but if we are low on RAM and it
15013                    // is large we want to force it down since we would prefer to
15014                    // keep launcher over it.
15015                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15016                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15017                        app.serviceHighRam = true;
15018                        app.serviceb = true;
15019                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15020                    } else {
15021                        mNewNumAServiceProcs++;
15022                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15023                    }
15024                } else {
15025                    app.serviceHighRam = false;
15026                }
15027            }
15028            if (app.serviceb) {
15029                adj = ProcessList.SERVICE_B_ADJ;
15030            }
15031        }
15032
15033        app.curRawAdj = adj;
15034
15035        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15036        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15037        if (adj > app.maxAdj) {
15038            adj = app.maxAdj;
15039            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15040                schedGroup = Process.THREAD_GROUP_DEFAULT;
15041            }
15042        }
15043        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15044            app.keeping = true;
15045        }
15046
15047        // Do final modification to adj.  Everything we do between here and applying
15048        // the final setAdj must be done in this function, because we will also use
15049        // it when computing the final cached adj later.  Note that we don't need to
15050        // worry about this for max adj above, since max adj will always be used to
15051        // keep it out of the cached vaues.
15052        adj = app.modifyRawOomAdj(adj);
15053
15054        app.curProcState = procState;
15055
15056        int importance = app.memImportance;
15057        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
15058            app.curAdj = adj;
15059            app.curSchedGroup = schedGroup;
15060            if (!interesting) {
15061                // For this reporting, if there is not something explicitly
15062                // interesting in this process then we will push it to the
15063                // background importance.
15064                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
15065            } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
15066                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
15067            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
15068                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
15069            } else if (adj >= ProcessList.HOME_APP_ADJ) {
15070                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
15071            } else if (adj >= ProcessList.SERVICE_ADJ) {
15072                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
15073            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15074                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
15075            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
15076                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
15077            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
15078                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
15079            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
15080                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
15081            } else {
15082                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
15083            }
15084        }
15085
15086        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
15087        if (foregroundActivities != app.foregroundActivities) {
15088            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15089        }
15090        if (changes != 0) {
15091            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15092            app.memImportance = importance;
15093            app.foregroundActivities = foregroundActivities;
15094            int i = mPendingProcessChanges.size()-1;
15095            ProcessChangeItem item = null;
15096            while (i >= 0) {
15097                item = mPendingProcessChanges.get(i);
15098                if (item.pid == app.pid) {
15099                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15100                    break;
15101                }
15102                i--;
15103            }
15104            if (i < 0) {
15105                // No existing item in pending changes; need a new one.
15106                final int NA = mAvailProcessChanges.size();
15107                if (NA > 0) {
15108                    item = mAvailProcessChanges.remove(NA-1);
15109                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15110                } else {
15111                    item = new ProcessChangeItem();
15112                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15113                }
15114                item.changes = 0;
15115                item.pid = app.pid;
15116                item.uid = app.info.uid;
15117                if (mPendingProcessChanges.size() == 0) {
15118                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15119                            "*** Enqueueing dispatch processes changed!");
15120                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15121                }
15122                mPendingProcessChanges.add(item);
15123            }
15124            item.changes |= changes;
15125            item.importance = importance;
15126            item.foregroundActivities = foregroundActivities;
15127            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
15128                    + Integer.toHexString(System.identityHashCode(item))
15129                    + " " + app.toShortString() + ": changes=" + item.changes
15130                    + " importance=" + item.importance
15131                    + " foreground=" + item.foregroundActivities
15132                    + " type=" + app.adjType + " source=" + app.adjSource
15133                    + " target=" + app.adjTarget);
15134        }
15135
15136        return app.curRawAdj;
15137    }
15138
15139    /**
15140     * Schedule PSS collection of a process.
15141     */
15142    void requestPssLocked(ProcessRecord proc, int procState) {
15143        if (mPendingPssProcesses.contains(proc)) {
15144            return;
15145        }
15146        if (mPendingPssProcesses.size() == 0) {
15147            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15148        }
15149        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15150        proc.pssProcState = procState;
15151        mPendingPssProcesses.add(proc);
15152    }
15153
15154    /**
15155     * Schedule PSS collection of all processes.
15156     */
15157    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15158        if (!always) {
15159            if (now < (mLastFullPssTime +
15160                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15161                return;
15162            }
15163        }
15164        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15165        mLastFullPssTime = now;
15166        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15167        mPendingPssProcesses.clear();
15168        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15169            ProcessRecord app = mLruProcesses.get(i);
15170            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15171                app.pssProcState = app.setProcState;
15172                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15173                        mSleeping, now);
15174                mPendingPssProcesses.add(app);
15175            }
15176        }
15177        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15178    }
15179
15180    /**
15181     * Ask a given process to GC right now.
15182     */
15183    final void performAppGcLocked(ProcessRecord app) {
15184        try {
15185            app.lastRequestedGc = SystemClock.uptimeMillis();
15186            if (app.thread != null) {
15187                if (app.reportLowMemory) {
15188                    app.reportLowMemory = false;
15189                    app.thread.scheduleLowMemory();
15190                } else {
15191                    app.thread.processInBackground();
15192                }
15193            }
15194        } catch (Exception e) {
15195            // whatever.
15196        }
15197    }
15198
15199    /**
15200     * Returns true if things are idle enough to perform GCs.
15201     */
15202    private final boolean canGcNowLocked() {
15203        boolean processingBroadcasts = false;
15204        for (BroadcastQueue q : mBroadcastQueues) {
15205            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15206                processingBroadcasts = true;
15207            }
15208        }
15209        return !processingBroadcasts
15210                && (mSleeping || mStackSupervisor.allResumedActivitiesIdle());
15211    }
15212
15213    /**
15214     * Perform GCs on all processes that are waiting for it, but only
15215     * if things are idle.
15216     */
15217    final void performAppGcsLocked() {
15218        final int N = mProcessesToGc.size();
15219        if (N <= 0) {
15220            return;
15221        }
15222        if (canGcNowLocked()) {
15223            while (mProcessesToGc.size() > 0) {
15224                ProcessRecord proc = mProcessesToGc.remove(0);
15225                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15226                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15227                            <= SystemClock.uptimeMillis()) {
15228                        // To avoid spamming the system, we will GC processes one
15229                        // at a time, waiting a few seconds between each.
15230                        performAppGcLocked(proc);
15231                        scheduleAppGcsLocked();
15232                        return;
15233                    } else {
15234                        // It hasn't been long enough since we last GCed this
15235                        // process...  put it in the list to wait for its time.
15236                        addProcessToGcListLocked(proc);
15237                        break;
15238                    }
15239                }
15240            }
15241
15242            scheduleAppGcsLocked();
15243        }
15244    }
15245
15246    /**
15247     * If all looks good, perform GCs on all processes waiting for them.
15248     */
15249    final void performAppGcsIfAppropriateLocked() {
15250        if (canGcNowLocked()) {
15251            performAppGcsLocked();
15252            return;
15253        }
15254        // Still not idle, wait some more.
15255        scheduleAppGcsLocked();
15256    }
15257
15258    /**
15259     * Schedule the execution of all pending app GCs.
15260     */
15261    final void scheduleAppGcsLocked() {
15262        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15263
15264        if (mProcessesToGc.size() > 0) {
15265            // Schedule a GC for the time to the next process.
15266            ProcessRecord proc = mProcessesToGc.get(0);
15267            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15268
15269            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15270            long now = SystemClock.uptimeMillis();
15271            if (when < (now+GC_TIMEOUT)) {
15272                when = now + GC_TIMEOUT;
15273            }
15274            mHandler.sendMessageAtTime(msg, when);
15275        }
15276    }
15277
15278    /**
15279     * Add a process to the array of processes waiting to be GCed.  Keeps the
15280     * list in sorted order by the last GC time.  The process can't already be
15281     * on the list.
15282     */
15283    final void addProcessToGcListLocked(ProcessRecord proc) {
15284        boolean added = false;
15285        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15286            if (mProcessesToGc.get(i).lastRequestedGc <
15287                    proc.lastRequestedGc) {
15288                added = true;
15289                mProcessesToGc.add(i+1, proc);
15290                break;
15291            }
15292        }
15293        if (!added) {
15294            mProcessesToGc.add(0, proc);
15295        }
15296    }
15297
15298    /**
15299     * Set up to ask a process to GC itself.  This will either do it
15300     * immediately, or put it on the list of processes to gc the next
15301     * time things are idle.
15302     */
15303    final void scheduleAppGcLocked(ProcessRecord app) {
15304        long now = SystemClock.uptimeMillis();
15305        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15306            return;
15307        }
15308        if (!mProcessesToGc.contains(app)) {
15309            addProcessToGcListLocked(app);
15310            scheduleAppGcsLocked();
15311        }
15312    }
15313
15314    final void checkExcessivePowerUsageLocked(boolean doKills) {
15315        updateCpuStatsNow();
15316
15317        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15318        boolean doWakeKills = doKills;
15319        boolean doCpuKills = doKills;
15320        if (mLastPowerCheckRealtime == 0) {
15321            doWakeKills = false;
15322        }
15323        if (mLastPowerCheckUptime == 0) {
15324            doCpuKills = false;
15325        }
15326        if (stats.isScreenOn()) {
15327            doWakeKills = false;
15328        }
15329        final long curRealtime = SystemClock.elapsedRealtime();
15330        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15331        final long curUptime = SystemClock.uptimeMillis();
15332        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15333        mLastPowerCheckRealtime = curRealtime;
15334        mLastPowerCheckUptime = curUptime;
15335        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15336            doWakeKills = false;
15337        }
15338        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15339            doCpuKills = false;
15340        }
15341        int i = mLruProcesses.size();
15342        while (i > 0) {
15343            i--;
15344            ProcessRecord app = mLruProcesses.get(i);
15345            if (!app.keeping) {
15346                long wtime;
15347                synchronized (stats) {
15348                    wtime = stats.getProcessWakeTime(app.info.uid,
15349                            app.pid, curRealtime);
15350                }
15351                long wtimeUsed = wtime - app.lastWakeTime;
15352                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15353                if (DEBUG_POWER) {
15354                    StringBuilder sb = new StringBuilder(128);
15355                    sb.append("Wake for ");
15356                    app.toShortString(sb);
15357                    sb.append(": over ");
15358                    TimeUtils.formatDuration(realtimeSince, sb);
15359                    sb.append(" used ");
15360                    TimeUtils.formatDuration(wtimeUsed, sb);
15361                    sb.append(" (");
15362                    sb.append((wtimeUsed*100)/realtimeSince);
15363                    sb.append("%)");
15364                    Slog.i(TAG, sb.toString());
15365                    sb.setLength(0);
15366                    sb.append("CPU for ");
15367                    app.toShortString(sb);
15368                    sb.append(": over ");
15369                    TimeUtils.formatDuration(uptimeSince, sb);
15370                    sb.append(" used ");
15371                    TimeUtils.formatDuration(cputimeUsed, sb);
15372                    sb.append(" (");
15373                    sb.append((cputimeUsed*100)/uptimeSince);
15374                    sb.append("%)");
15375                    Slog.i(TAG, sb.toString());
15376                }
15377                // If a process has held a wake lock for more
15378                // than 50% of the time during this period,
15379                // that sounds bad.  Kill!
15380                if (doWakeKills && realtimeSince > 0
15381                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15382                    synchronized (stats) {
15383                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15384                                realtimeSince, wtimeUsed);
15385                    }
15386                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15387                            + " during " + realtimeSince);
15388                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15389                } else if (doCpuKills && uptimeSince > 0
15390                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15391                    synchronized (stats) {
15392                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15393                                uptimeSince, cputimeUsed);
15394                    }
15395                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15396                            + " during " + uptimeSince);
15397                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15398                } else {
15399                    app.lastWakeTime = wtime;
15400                    app.lastCpuTime = app.curCpuTime;
15401                }
15402            }
15403        }
15404    }
15405
15406    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15407            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15408        boolean success = true;
15409
15410        if (app.curRawAdj != app.setRawAdj) {
15411            if (wasKeeping && !app.keeping) {
15412                // This app is no longer something we want to keep.  Note
15413                // its current wake lock time to later know to kill it if
15414                // it is not behaving well.
15415                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15416                synchronized (stats) {
15417                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15418                            app.pid, SystemClock.elapsedRealtime());
15419                }
15420                app.lastCpuTime = app.curCpuTime;
15421            }
15422
15423            app.setRawAdj = app.curRawAdj;
15424        }
15425
15426        if (app.curAdj != app.setAdj) {
15427            ProcessList.setOomAdj(app.pid, app.curAdj);
15428            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15429                TAG, "Set " + app.pid + " " + app.processName +
15430                " adj " + app.curAdj + ": " + app.adjType);
15431            app.setAdj = app.curAdj;
15432        }
15433
15434        if (app.setSchedGroup != app.curSchedGroup) {
15435            app.setSchedGroup = app.curSchedGroup;
15436            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15437                    "Setting process group of " + app.processName
15438                    + " to " + app.curSchedGroup);
15439            if (app.waitingToKill != null &&
15440                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15441                killUnneededProcessLocked(app, app.waitingToKill);
15442                success = false;
15443            } else {
15444                if (true) {
15445                    long oldId = Binder.clearCallingIdentity();
15446                    try {
15447                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15448                    } catch (Exception e) {
15449                        Slog.w(TAG, "Failed setting process group of " + app.pid
15450                                + " to " + app.curSchedGroup);
15451                        e.printStackTrace();
15452                    } finally {
15453                        Binder.restoreCallingIdentity(oldId);
15454                    }
15455                } else {
15456                    if (app.thread != null) {
15457                        try {
15458                            app.thread.setSchedulingGroup(app.curSchedGroup);
15459                        } catch (RemoteException e) {
15460                        }
15461                    }
15462                }
15463                Process.setSwappiness(app.pid,
15464                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15465            }
15466        }
15467        if (app.repProcState != app.curProcState) {
15468            app.repProcState = app.curProcState;
15469            if (!reportingProcessState && app.thread != null) {
15470                try {
15471                    if (false) {
15472                        //RuntimeException h = new RuntimeException("here");
15473                        Slog.i(TAG, "Sending new process state " + app.repProcState
15474                                + " to " + app /*, h*/);
15475                    }
15476                    app.thread.setProcessState(app.repProcState);
15477                } catch (RemoteException e) {
15478                }
15479            }
15480        }
15481        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15482                app.setProcState)) {
15483            app.lastStateTime = now;
15484            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15485                    mSleeping, now);
15486            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15487                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15488                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15489                    + (app.nextPssTime-now) + ": " + app);
15490        } else {
15491            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15492                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15493                requestPssLocked(app, app.setProcState);
15494                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15495                        mSleeping, now);
15496            } else if (false && DEBUG_PSS) {
15497                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15498            }
15499        }
15500        if (app.setProcState != app.curProcState) {
15501            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15502                    "Proc state change of " + app.processName
15503                    + " to " + app.curProcState);
15504            app.setProcState = app.curProcState;
15505            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15506                app.notCachedSinceIdle = false;
15507            }
15508            if (!doingAll) {
15509                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15510            } else {
15511                app.procStateChanged = true;
15512            }
15513        }
15514        return success;
15515    }
15516
15517    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15518        if (proc.thread != null && proc.baseProcessTracker != null) {
15519            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15520        }
15521    }
15522
15523    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15524            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15525        if (app.thread == null) {
15526            return false;
15527        }
15528
15529        final boolean wasKeeping = app.keeping;
15530
15531        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15532
15533        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll,
15534                reportingProcessState, now);
15535    }
15536
15537    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15538            boolean oomAdj) {
15539        if (isForeground != proc.foregroundServices) {
15540            proc.foregroundServices = isForeground;
15541            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15542                    proc.info.uid);
15543            if (isForeground) {
15544                if (curProcs == null) {
15545                    curProcs = new ArrayList<ProcessRecord>();
15546                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15547                }
15548                if (!curProcs.contains(proc)) {
15549                    curProcs.add(proc);
15550                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15551                            proc.info.packageName, proc.info.uid);
15552                }
15553            } else {
15554                if (curProcs != null) {
15555                    if (curProcs.remove(proc)) {
15556                        mBatteryStatsService.noteEvent(
15557                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15558                                proc.info.packageName, proc.info.uid);
15559                        if (curProcs.size() <= 0) {
15560                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15561                        }
15562                    }
15563                }
15564            }
15565            if (oomAdj) {
15566                updateOomAdjLocked();
15567            }
15568        }
15569    }
15570
15571    private final ActivityRecord resumedAppLocked() {
15572        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15573        String pkg;
15574        int uid;
15575        if (act != null) {
15576            pkg = act.packageName;
15577            uid = act.info.applicationInfo.uid;
15578        } else {
15579            pkg = null;
15580            uid = -1;
15581        }
15582        // Has the UID or resumed package name changed?
15583        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15584                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15585            if (mCurResumedPackage != null) {
15586                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15587                        mCurResumedPackage, mCurResumedUid);
15588            }
15589            mCurResumedPackage = pkg;
15590            mCurResumedUid = uid;
15591            if (mCurResumedPackage != null) {
15592                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15593                        mCurResumedPackage, mCurResumedUid);
15594            }
15595        }
15596        return act;
15597    }
15598
15599    final boolean updateOomAdjLocked(ProcessRecord app) {
15600        return updateOomAdjLocked(app, false);
15601    }
15602
15603    final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) {
15604        final ActivityRecord TOP_ACT = resumedAppLocked();
15605        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15606        final boolean wasCached = app.cached;
15607
15608        mAdjSeq++;
15609
15610        // This is the desired cached adjusment we want to tell it to use.
15611        // If our app is currently cached, we know it, and that is it.  Otherwise,
15612        // we don't know it yet, and it needs to now be cached we will then
15613        // need to do a complete oom adj.
15614        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15615                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15616        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState,
15617                SystemClock.uptimeMillis());
15618        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15619            // Changed to/from cached state, so apps after it in the LRU
15620            // list may also be changed.
15621            updateOomAdjLocked();
15622        }
15623        return success;
15624    }
15625
15626    final void updateOomAdjLocked() {
15627        final ActivityRecord TOP_ACT = resumedAppLocked();
15628        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15629        final long now = SystemClock.uptimeMillis();
15630        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15631        final int N = mLruProcesses.size();
15632
15633        if (false) {
15634            RuntimeException e = new RuntimeException();
15635            e.fillInStackTrace();
15636            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15637        }
15638
15639        mAdjSeq++;
15640        mNewNumServiceProcs = 0;
15641        mNewNumAServiceProcs = 0;
15642
15643        final int emptyProcessLimit;
15644        final int cachedProcessLimit;
15645        if (mProcessLimit <= 0) {
15646            emptyProcessLimit = cachedProcessLimit = 0;
15647        } else if (mProcessLimit == 1) {
15648            emptyProcessLimit = 1;
15649            cachedProcessLimit = 0;
15650        } else {
15651            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15652            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15653        }
15654
15655        // Let's determine how many processes we have running vs.
15656        // how many slots we have for background processes; we may want
15657        // to put multiple processes in a slot of there are enough of
15658        // them.
15659        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15660                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15661        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15662        if (numEmptyProcs > cachedProcessLimit) {
15663            // If there are more empty processes than our limit on cached
15664            // processes, then use the cached process limit for the factor.
15665            // This ensures that the really old empty processes get pushed
15666            // down to the bottom, so if we are running low on memory we will
15667            // have a better chance at keeping around more cached processes
15668            // instead of a gazillion empty processes.
15669            numEmptyProcs = cachedProcessLimit;
15670        }
15671        int emptyFactor = numEmptyProcs/numSlots;
15672        if (emptyFactor < 1) emptyFactor = 1;
15673        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15674        if (cachedFactor < 1) cachedFactor = 1;
15675        int stepCached = 0;
15676        int stepEmpty = 0;
15677        int numCached = 0;
15678        int numEmpty = 0;
15679        int numTrimming = 0;
15680
15681        mNumNonCachedProcs = 0;
15682        mNumCachedHiddenProcs = 0;
15683
15684        // First update the OOM adjustment for each of the
15685        // application processes based on their current state.
15686        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15687        int nextCachedAdj = curCachedAdj+1;
15688        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15689        int nextEmptyAdj = curEmptyAdj+2;
15690        for (int i=N-1; i>=0; i--) {
15691            ProcessRecord app = mLruProcesses.get(i);
15692            if (!app.killedByAm && app.thread != null) {
15693                app.procStateChanged = false;
15694                final boolean wasKeeping = app.keeping;
15695                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15696
15697                // If we haven't yet assigned the final cached adj
15698                // to the process, do that now.
15699                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15700                    switch (app.curProcState) {
15701                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15702                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15703                            // This process is a cached process holding activities...
15704                            // assign it the next cached value for that type, and then
15705                            // step that cached level.
15706                            app.curRawAdj = curCachedAdj;
15707                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15708                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15709                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15710                                    + ")");
15711                            if (curCachedAdj != nextCachedAdj) {
15712                                stepCached++;
15713                                if (stepCached >= cachedFactor) {
15714                                    stepCached = 0;
15715                                    curCachedAdj = nextCachedAdj;
15716                                    nextCachedAdj += 2;
15717                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15718                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15719                                    }
15720                                }
15721                            }
15722                            break;
15723                        default:
15724                            // For everything else, assign next empty cached process
15725                            // level and bump that up.  Note that this means that
15726                            // long-running services that have dropped down to the
15727                            // cached level will be treated as empty (since their process
15728                            // state is still as a service), which is what we want.
15729                            app.curRawAdj = curEmptyAdj;
15730                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15731                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15732                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15733                                    + ")");
15734                            if (curEmptyAdj != nextEmptyAdj) {
15735                                stepEmpty++;
15736                                if (stepEmpty >= emptyFactor) {
15737                                    stepEmpty = 0;
15738                                    curEmptyAdj = nextEmptyAdj;
15739                                    nextEmptyAdj += 2;
15740                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15741                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15742                                    }
15743                                }
15744                            }
15745                            break;
15746                    }
15747                }
15748
15749                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now);
15750
15751                // Count the number of process types.
15752                switch (app.curProcState) {
15753                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15754                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15755                        mNumCachedHiddenProcs++;
15756                        numCached++;
15757                        if (numCached > cachedProcessLimit) {
15758                            killUnneededProcessLocked(app, "cached #" + numCached);
15759                        }
15760                        break;
15761                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15762                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15763                                && app.lastActivityTime < oldTime) {
15764                            killUnneededProcessLocked(app, "empty for "
15765                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15766                                    / 1000) + "s");
15767                        } else {
15768                            numEmpty++;
15769                            if (numEmpty > emptyProcessLimit) {
15770                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15771                            }
15772                        }
15773                        break;
15774                    default:
15775                        mNumNonCachedProcs++;
15776                        break;
15777                }
15778
15779                if (app.isolated && app.services.size() <= 0) {
15780                    // If this is an isolated process, and there are no
15781                    // services running in it, then the process is no longer
15782                    // needed.  We agressively kill these because we can by
15783                    // definition not re-use the same process again, and it is
15784                    // good to avoid having whatever code was running in them
15785                    // left sitting around after no longer needed.
15786                    killUnneededProcessLocked(app, "isolated not needed");
15787                }
15788
15789                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15790                        && !app.killedByAm) {
15791                    numTrimming++;
15792                }
15793            }
15794        }
15795
15796        mNumServiceProcs = mNewNumServiceProcs;
15797
15798        // Now determine the memory trimming level of background processes.
15799        // Unfortunately we need to start at the back of the list to do this
15800        // properly.  We only do this if the number of background apps we
15801        // are managing to keep around is less than half the maximum we desire;
15802        // if we are keeping a good number around, we'll let them use whatever
15803        // memory they want.
15804        final int numCachedAndEmpty = numCached + numEmpty;
15805        int memFactor;
15806        if (numCached <= ProcessList.TRIM_CACHED_APPS
15807                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
15808            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
15809                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
15810            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
15811                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
15812            } else {
15813                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
15814            }
15815        } else {
15816            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
15817        }
15818        // We always allow the memory level to go up (better).  We only allow it to go
15819        // down if we are in a state where that is allowed, *and* the total number of processes
15820        // has gone down since last time.
15821        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
15822                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
15823                + " last=" + mLastNumProcesses);
15824        if (memFactor > mLastMemoryLevel) {
15825            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
15826                memFactor = mLastMemoryLevel;
15827                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
15828            }
15829        }
15830        mLastMemoryLevel = memFactor;
15831        mLastNumProcesses = mLruProcesses.size();
15832        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now);
15833        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
15834        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
15835            if (mLowRamStartTime == 0) {
15836                mLowRamStartTime = now;
15837            }
15838            int step = 0;
15839            int fgTrimLevel;
15840            switch (memFactor) {
15841                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15842                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
15843                    break;
15844                case ProcessStats.ADJ_MEM_FACTOR_LOW:
15845                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
15846                    break;
15847                default:
15848                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
15849                    break;
15850            }
15851            int factor = numTrimming/3;
15852            int minFactor = 2;
15853            if (mHomeProcess != null) minFactor++;
15854            if (mPreviousProcess != null) minFactor++;
15855            if (factor < minFactor) factor = minFactor;
15856            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
15857            for (int i=N-1; i>=0; i--) {
15858                ProcessRecord app = mLruProcesses.get(i);
15859                if (allChanged || app.procStateChanged) {
15860                    setProcessTrackerState(app, trackerMemFactor, now);
15861                    app.procStateChanged = false;
15862                }
15863                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15864                        && !app.killedByAm) {
15865                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
15866                        try {
15867                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15868                                    "Trimming memory of " + app.processName
15869                                    + " to " + curLevel);
15870                            app.thread.scheduleTrimMemory(curLevel);
15871                        } catch (RemoteException e) {
15872                        }
15873                        if (false) {
15874                            // For now we won't do this; our memory trimming seems
15875                            // to be good enough at this point that destroying
15876                            // activities causes more harm than good.
15877                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
15878                                    && app != mHomeProcess && app != mPreviousProcess) {
15879                                // Need to do this on its own message because the stack may not
15880                                // be in a consistent state at this point.
15881                                // For these apps we will also finish their activities
15882                                // to help them free memory.
15883                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
15884                            }
15885                        }
15886                    }
15887                    app.trimMemoryLevel = curLevel;
15888                    step++;
15889                    if (step >= factor) {
15890                        step = 0;
15891                        switch (curLevel) {
15892                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
15893                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
15894                                break;
15895                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
15896                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15897                                break;
15898                        }
15899                    }
15900                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15901                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
15902                            && app.thread != null) {
15903                        try {
15904                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15905                                    "Trimming memory of heavy-weight " + app.processName
15906                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15907                            app.thread.scheduleTrimMemory(
15908                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15909                        } catch (RemoteException e) {
15910                        }
15911                    }
15912                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15913                } else {
15914                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15915                            || app.systemNoUi) && app.pendingUiClean) {
15916                        // If this application is now in the background and it
15917                        // had done UI, then give it the special trim level to
15918                        // have it free UI resources.
15919                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
15920                        if (app.trimMemoryLevel < level && app.thread != null) {
15921                            try {
15922                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15923                                        "Trimming memory of bg-ui " + app.processName
15924                                        + " to " + level);
15925                                app.thread.scheduleTrimMemory(level);
15926                            } catch (RemoteException e) {
15927                            }
15928                        }
15929                        app.pendingUiClean = false;
15930                    }
15931                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
15932                        try {
15933                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15934                                    "Trimming memory of fg " + app.processName
15935                                    + " to " + fgTrimLevel);
15936                            app.thread.scheduleTrimMemory(fgTrimLevel);
15937                        } catch (RemoteException e) {
15938                        }
15939                    }
15940                    app.trimMemoryLevel = fgTrimLevel;
15941                }
15942            }
15943        } else {
15944            if (mLowRamStartTime != 0) {
15945                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
15946                mLowRamStartTime = 0;
15947            }
15948            for (int i=N-1; i>=0; i--) {
15949                ProcessRecord app = mLruProcesses.get(i);
15950                if (allChanged || app.procStateChanged) {
15951                    setProcessTrackerState(app, trackerMemFactor, now);
15952                    app.procStateChanged = false;
15953                }
15954                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15955                        || app.systemNoUi) && app.pendingUiClean) {
15956                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
15957                            && app.thread != null) {
15958                        try {
15959                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15960                                    "Trimming memory of ui hidden " + app.processName
15961                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15962                            app.thread.scheduleTrimMemory(
15963                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15964                        } catch (RemoteException e) {
15965                        }
15966                    }
15967                    app.pendingUiClean = false;
15968                }
15969                app.trimMemoryLevel = 0;
15970            }
15971        }
15972
15973        if (mAlwaysFinishActivities) {
15974            // Need to do this on its own message because the stack may not
15975            // be in a consistent state at this point.
15976            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
15977        }
15978
15979        if (allChanged) {
15980            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
15981        }
15982
15983        if (mProcessStats.shouldWriteNowLocked(now)) {
15984            mHandler.post(new Runnable() {
15985                @Override public void run() {
15986                    synchronized (ActivityManagerService.this) {
15987                        mProcessStats.writeStateAsyncLocked();
15988                    }
15989                }
15990            });
15991        }
15992
15993        if (DEBUG_OOM_ADJ) {
15994            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
15995        }
15996    }
15997
15998    final void trimApplications() {
15999        synchronized (this) {
16000            int i;
16001
16002            // First remove any unused application processes whose package
16003            // has been removed.
16004            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16005                final ProcessRecord app = mRemovedProcesses.get(i);
16006                if (app.activities.size() == 0
16007                        && app.curReceiver == null && app.services.size() == 0) {
16008                    Slog.i(
16009                        TAG, "Exiting empty application process "
16010                        + app.processName + " ("
16011                        + (app.thread != null ? app.thread.asBinder() : null)
16012                        + ")\n");
16013                    if (app.pid > 0 && app.pid != MY_PID) {
16014                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16015                                app.processName, app.setAdj, "empty");
16016                        app.killedByAm = true;
16017                        Process.killProcessQuiet(app.pid);
16018                    } else {
16019                        try {
16020                            app.thread.scheduleExit();
16021                        } catch (Exception e) {
16022                            // Ignore exceptions.
16023                        }
16024                    }
16025                    cleanUpApplicationRecordLocked(app, false, true, -1);
16026                    mRemovedProcesses.remove(i);
16027
16028                    if (app.persistent) {
16029                        if (app.persistent) {
16030                            addAppLocked(app.info, false);
16031                        }
16032                    }
16033                }
16034            }
16035
16036            // Now update the oom adj for all processes.
16037            updateOomAdjLocked();
16038        }
16039    }
16040
16041    /** This method sends the specified signal to each of the persistent apps */
16042    public void signalPersistentProcesses(int sig) throws RemoteException {
16043        if (sig != Process.SIGNAL_USR1) {
16044            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16045        }
16046
16047        synchronized (this) {
16048            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16049                    != PackageManager.PERMISSION_GRANTED) {
16050                throw new SecurityException("Requires permission "
16051                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16052            }
16053
16054            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16055                ProcessRecord r = mLruProcesses.get(i);
16056                if (r.thread != null && r.persistent) {
16057                    Process.sendSignal(r.pid, sig);
16058                }
16059            }
16060        }
16061    }
16062
16063    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16064        if (proc == null || proc == mProfileProc) {
16065            proc = mProfileProc;
16066            path = mProfileFile;
16067            profileType = mProfileType;
16068            clearProfilerLocked();
16069        }
16070        if (proc == null) {
16071            return;
16072        }
16073        try {
16074            proc.thread.profilerControl(false, path, null, profileType);
16075        } catch (RemoteException e) {
16076            throw new IllegalStateException("Process disappeared");
16077        }
16078    }
16079
16080    private void clearProfilerLocked() {
16081        if (mProfileFd != null) {
16082            try {
16083                mProfileFd.close();
16084            } catch (IOException e) {
16085            }
16086        }
16087        mProfileApp = null;
16088        mProfileProc = null;
16089        mProfileFile = null;
16090        mProfileType = 0;
16091        mAutoStopProfiler = false;
16092    }
16093
16094    public boolean profileControl(String process, int userId, boolean start,
16095            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16096
16097        try {
16098            synchronized (this) {
16099                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16100                // its own permission.
16101                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16102                        != PackageManager.PERMISSION_GRANTED) {
16103                    throw new SecurityException("Requires permission "
16104                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16105                }
16106
16107                if (start && fd == null) {
16108                    throw new IllegalArgumentException("null fd");
16109                }
16110
16111                ProcessRecord proc = null;
16112                if (process != null) {
16113                    proc = findProcessLocked(process, userId, "profileControl");
16114                }
16115
16116                if (start && (proc == null || proc.thread == null)) {
16117                    throw new IllegalArgumentException("Unknown process: " + process);
16118                }
16119
16120                if (start) {
16121                    stopProfilerLocked(null, null, 0);
16122                    setProfileApp(proc.info, proc.processName, path, fd, false);
16123                    mProfileProc = proc;
16124                    mProfileType = profileType;
16125                    try {
16126                        fd = fd.dup();
16127                    } catch (IOException e) {
16128                        fd = null;
16129                    }
16130                    proc.thread.profilerControl(start, path, fd, profileType);
16131                    fd = null;
16132                    mProfileFd = null;
16133                } else {
16134                    stopProfilerLocked(proc, path, profileType);
16135                    if (fd != null) {
16136                        try {
16137                            fd.close();
16138                        } catch (IOException e) {
16139                        }
16140                    }
16141                }
16142
16143                return true;
16144            }
16145        } catch (RemoteException e) {
16146            throw new IllegalStateException("Process disappeared");
16147        } finally {
16148            if (fd != null) {
16149                try {
16150                    fd.close();
16151                } catch (IOException e) {
16152                }
16153            }
16154        }
16155    }
16156
16157    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16158        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16159                userId, true, true, callName, null);
16160        ProcessRecord proc = null;
16161        try {
16162            int pid = Integer.parseInt(process);
16163            synchronized (mPidsSelfLocked) {
16164                proc = mPidsSelfLocked.get(pid);
16165            }
16166        } catch (NumberFormatException e) {
16167        }
16168
16169        if (proc == null) {
16170            ArrayMap<String, SparseArray<ProcessRecord>> all
16171                    = mProcessNames.getMap();
16172            SparseArray<ProcessRecord> procs = all.get(process);
16173            if (procs != null && procs.size() > 0) {
16174                proc = procs.valueAt(0);
16175                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16176                    for (int i=1; i<procs.size(); i++) {
16177                        ProcessRecord thisProc = procs.valueAt(i);
16178                        if (thisProc.userId == userId) {
16179                            proc = thisProc;
16180                            break;
16181                        }
16182                    }
16183                }
16184            }
16185        }
16186
16187        return proc;
16188    }
16189
16190    public boolean dumpHeap(String process, int userId, boolean managed,
16191            String path, ParcelFileDescriptor fd) throws RemoteException {
16192
16193        try {
16194            synchronized (this) {
16195                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16196                // its own permission (same as profileControl).
16197                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16198                        != PackageManager.PERMISSION_GRANTED) {
16199                    throw new SecurityException("Requires permission "
16200                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16201                }
16202
16203                if (fd == null) {
16204                    throw new IllegalArgumentException("null fd");
16205                }
16206
16207                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16208                if (proc == null || proc.thread == null) {
16209                    throw new IllegalArgumentException("Unknown process: " + process);
16210                }
16211
16212                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16213                if (!isDebuggable) {
16214                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16215                        throw new SecurityException("Process not debuggable: " + proc);
16216                    }
16217                }
16218
16219                proc.thread.dumpHeap(managed, path, fd);
16220                fd = null;
16221                return true;
16222            }
16223        } catch (RemoteException e) {
16224            throw new IllegalStateException("Process disappeared");
16225        } finally {
16226            if (fd != null) {
16227                try {
16228                    fd.close();
16229                } catch (IOException e) {
16230                }
16231            }
16232        }
16233    }
16234
16235    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16236    public void monitor() {
16237        synchronized (this) { }
16238    }
16239
16240    void onCoreSettingsChange(Bundle settings) {
16241        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16242            ProcessRecord processRecord = mLruProcesses.get(i);
16243            try {
16244                if (processRecord.thread != null) {
16245                    processRecord.thread.setCoreSettings(settings);
16246                }
16247            } catch (RemoteException re) {
16248                /* ignore */
16249            }
16250        }
16251    }
16252
16253    // Multi-user methods
16254
16255    /**
16256     * Start user, if its not already running, but don't bring it to foreground.
16257     */
16258    @Override
16259    public boolean startUserInBackground(final int userId) {
16260        return startUser(userId, /* foreground */ false);
16261    }
16262
16263    /**
16264     * Refreshes the list of users related to the current user when either a
16265     * user switch happens or when a new related user is started in the
16266     * background.
16267     */
16268    private void updateRelatedUserIdsLocked() {
16269        final List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(mCurrentUserId);
16270        int[] relatedUserIds = new int[relatedUsers.size()]; // relatedUsers will not be null
16271        for (int i = 0; i < relatedUserIds.length; i++) {
16272            relatedUserIds[i] = relatedUsers.get(i).id;
16273        }
16274        mRelatedUserIds = relatedUserIds;
16275    }
16276
16277    @Override
16278    public boolean switchUser(final int userId) {
16279        return startUser(userId, /* foregound */ true);
16280    }
16281
16282    private boolean startUser(final int userId, boolean foreground) {
16283        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16284                != PackageManager.PERMISSION_GRANTED) {
16285            String msg = "Permission Denial: switchUser() from pid="
16286                    + Binder.getCallingPid()
16287                    + ", uid=" + Binder.getCallingUid()
16288                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16289            Slog.w(TAG, msg);
16290            throw new SecurityException(msg);
16291        }
16292
16293        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16294
16295        final long ident = Binder.clearCallingIdentity();
16296        try {
16297            synchronized (this) {
16298                final int oldUserId = mCurrentUserId;
16299                if (oldUserId == userId) {
16300                    return true;
16301                }
16302
16303                mStackSupervisor.setLockTaskModeLocked(null);
16304
16305                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16306                if (userInfo == null) {
16307                    Slog.w(TAG, "No user info for user #" + userId);
16308                    return false;
16309                }
16310
16311                if (foreground) {
16312                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16313                            R.anim.screen_user_enter);
16314                }
16315
16316                boolean needStart = false;
16317
16318                // If the user we are switching to is not currently started, then
16319                // we need to start it now.
16320                if (mStartedUsers.get(userId) == null) {
16321                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16322                    updateStartedUserArrayLocked();
16323                    needStart = true;
16324                }
16325
16326                final Integer userIdInt = Integer.valueOf(userId);
16327                mUserLru.remove(userIdInt);
16328                mUserLru.add(userIdInt);
16329
16330                if (foreground) {
16331                    mCurrentUserId = userId;
16332                    updateRelatedUserIdsLocked();
16333                    mWindowManager.setCurrentUser(userId, mRelatedUserIds);
16334                    // Once the internal notion of the active user has switched, we lock the device
16335                    // with the option to show the user switcher on the keyguard.
16336                    mWindowManager.lockNow(null);
16337                } else {
16338                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16339                    updateRelatedUserIdsLocked();
16340                    mWindowManager.updateRelatedUserIds(mRelatedUserIds);
16341                    mUserLru.remove(currentUserIdInt);
16342                    mUserLru.add(currentUserIdInt);
16343                }
16344
16345                final UserStartedState uss = mStartedUsers.get(userId);
16346
16347                // Make sure user is in the started state.  If it is currently
16348                // stopping, we need to knock that off.
16349                if (uss.mState == UserStartedState.STATE_STOPPING) {
16350                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16351                    // so we can just fairly silently bring the user back from
16352                    // the almost-dead.
16353                    uss.mState = UserStartedState.STATE_RUNNING;
16354                    updateStartedUserArrayLocked();
16355                    needStart = true;
16356                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16357                    // This means ACTION_SHUTDOWN has been sent, so we will
16358                    // need to treat this as a new boot of the user.
16359                    uss.mState = UserStartedState.STATE_BOOTING;
16360                    updateStartedUserArrayLocked();
16361                    needStart = true;
16362                }
16363
16364                if (foreground) {
16365                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16366                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16367                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16368                            oldUserId, userId, uss));
16369                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16370                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16371                }
16372
16373                if (needStart) {
16374                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16375                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16376                            | Intent.FLAG_RECEIVER_FOREGROUND);
16377                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16378                    broadcastIntentLocked(null, null, intent,
16379                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16380                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16381                }
16382
16383                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16384                    if (userId != 0) {
16385                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16386                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16387                        broadcastIntentLocked(null, null, intent, null,
16388                                new IIntentReceiver.Stub() {
16389                                    public void performReceive(Intent intent, int resultCode,
16390                                            String data, Bundle extras, boolean ordered,
16391                                            boolean sticky, int sendingUser) {
16392                                        userInitialized(uss, userId);
16393                                    }
16394                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16395                                true, false, MY_PID, Process.SYSTEM_UID,
16396                                userId);
16397                        uss.initializing = true;
16398                    } else {
16399                        getUserManagerLocked().makeInitialized(userInfo.id);
16400                    }
16401                }
16402
16403                if (foreground) {
16404                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16405                    if (homeInFront) {
16406                        startHomeActivityLocked(userId);
16407                    } else {
16408                        mStackSupervisor.resumeTopActivitiesLocked();
16409                    }
16410                    EventLogTags.writeAmSwitchUser(userId);
16411                    getUserManagerLocked().userForeground(userId);
16412                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16413                }
16414
16415                if (needStart) {
16416                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16417                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16418                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16419                    broadcastIntentLocked(null, null, intent,
16420                            null, new IIntentReceiver.Stub() {
16421                                @Override
16422                                public void performReceive(Intent intent, int resultCode, String data,
16423                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16424                                        throws RemoteException {
16425                                }
16426                            }, 0, null, null,
16427                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16428                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16429                }
16430            }
16431        } finally {
16432            Binder.restoreCallingIdentity(ident);
16433        }
16434
16435        return true;
16436    }
16437
16438    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16439        long ident = Binder.clearCallingIdentity();
16440        try {
16441            Intent intent;
16442            if (oldUserId >= 0) {
16443                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16444                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16445                        | Intent.FLAG_RECEIVER_FOREGROUND);
16446                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16447                broadcastIntentLocked(null, null, intent,
16448                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16449                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16450            }
16451            if (newUserId >= 0) {
16452                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16453                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16454                        | Intent.FLAG_RECEIVER_FOREGROUND);
16455                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16456                broadcastIntentLocked(null, null, intent,
16457                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16458                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16459                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16460                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16461                        | Intent.FLAG_RECEIVER_FOREGROUND);
16462                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16463                broadcastIntentLocked(null, null, intent,
16464                        null, null, 0, null, null,
16465                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16466                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16467            }
16468        } finally {
16469            Binder.restoreCallingIdentity(ident);
16470        }
16471    }
16472
16473    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16474            final int newUserId) {
16475        final int N = mUserSwitchObservers.beginBroadcast();
16476        if (N > 0) {
16477            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16478                int mCount = 0;
16479                @Override
16480                public void sendResult(Bundle data) throws RemoteException {
16481                    synchronized (ActivityManagerService.this) {
16482                        if (mCurUserSwitchCallback == this) {
16483                            mCount++;
16484                            if (mCount == N) {
16485                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16486                            }
16487                        }
16488                    }
16489                }
16490            };
16491            synchronized (this) {
16492                uss.switching = true;
16493                mCurUserSwitchCallback = callback;
16494            }
16495            for (int i=0; i<N; i++) {
16496                try {
16497                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16498                            newUserId, callback);
16499                } catch (RemoteException e) {
16500                }
16501            }
16502        } else {
16503            synchronized (this) {
16504                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16505            }
16506        }
16507        mUserSwitchObservers.finishBroadcast();
16508    }
16509
16510    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16511        synchronized (this) {
16512            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16513            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16514        }
16515    }
16516
16517    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16518        mCurUserSwitchCallback = null;
16519        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16520        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16521                oldUserId, newUserId, uss));
16522    }
16523
16524    void userInitialized(UserStartedState uss, int newUserId) {
16525        completeSwitchAndInitalize(uss, newUserId, true, false);
16526    }
16527
16528    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16529        completeSwitchAndInitalize(uss, newUserId, false, true);
16530    }
16531
16532    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16533            boolean clearInitializing, boolean clearSwitching) {
16534        boolean unfrozen = false;
16535        synchronized (this) {
16536            if (clearInitializing) {
16537                uss.initializing = false;
16538                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16539            }
16540            if (clearSwitching) {
16541                uss.switching = false;
16542            }
16543            if (!uss.switching && !uss.initializing) {
16544                mWindowManager.stopFreezingScreen();
16545                unfrozen = true;
16546            }
16547        }
16548        if (unfrozen) {
16549            final int N = mUserSwitchObservers.beginBroadcast();
16550            for (int i=0; i<N; i++) {
16551                try {
16552                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16553                } catch (RemoteException e) {
16554                }
16555            }
16556            mUserSwitchObservers.finishBroadcast();
16557        }
16558    }
16559
16560    void scheduleStartRelatedUsersLocked() {
16561        if (!mHandler.hasMessages(START_RELATED_USERS_MSG)) {
16562            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_RELATED_USERS_MSG),
16563                    DateUtils.SECOND_IN_MILLIS);
16564        }
16565    }
16566
16567    void startRelatedUsersLocked() {
16568        if (DEBUG_MU) Slog.i(TAG_MU, "startRelatedUsersLocked");
16569        List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(mCurrentUserId);
16570        List<UserInfo> toStart = new ArrayList<UserInfo>(relatedUsers.size());
16571        for (UserInfo relatedUser : relatedUsers) {
16572            if ((relatedUser.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED) {
16573                toStart.add(relatedUser);
16574            }
16575        }
16576        final int n = toStart.size();
16577        int i = 0;
16578        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
16579            startUserInBackground(toStart.get(i).id);
16580        }
16581        if (i < n) {
16582            Slog.w(TAG_MU, "More related users than MAX_RUNNING_USERS");
16583        }
16584    }
16585
16586    void finishUserSwitch(UserStartedState uss) {
16587        synchronized (this) {
16588            if (uss.mState == UserStartedState.STATE_BOOTING
16589                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16590                uss.mState = UserStartedState.STATE_RUNNING;
16591                final int userId = uss.mHandle.getIdentifier();
16592                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16593                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16594                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16595                broadcastIntentLocked(null, null, intent,
16596                        null, null, 0, null, null,
16597                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16598                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16599            }
16600
16601            startRelatedUsersLocked();
16602
16603            int num = mUserLru.size();
16604            int i = 0;
16605            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16606                Integer oldUserId = mUserLru.get(i);
16607                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16608                if (oldUss == null) {
16609                    // Shouldn't happen, but be sane if it does.
16610                    mUserLru.remove(i);
16611                    num--;
16612                    continue;
16613                }
16614                if (oldUss.mState == UserStartedState.STATE_STOPPING
16615                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16616                    // This user is already stopping, doesn't count.
16617                    num--;
16618                    i++;
16619                    continue;
16620                }
16621                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16622                    // Owner and current can't be stopped, but count as running.
16623                    i++;
16624                    continue;
16625                }
16626                // This is a user to be stopped.
16627                stopUserLocked(oldUserId, null);
16628                num--;
16629                i++;
16630            }
16631        }
16632    }
16633
16634    @Override
16635    public int stopUser(final int userId, final IStopUserCallback callback) {
16636        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16637                != PackageManager.PERMISSION_GRANTED) {
16638            String msg = "Permission Denial: switchUser() from pid="
16639                    + Binder.getCallingPid()
16640                    + ", uid=" + Binder.getCallingUid()
16641                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16642            Slog.w(TAG, msg);
16643            throw new SecurityException(msg);
16644        }
16645        if (userId <= 0) {
16646            throw new IllegalArgumentException("Can't stop primary user " + userId);
16647        }
16648        synchronized (this) {
16649            return stopUserLocked(userId, callback);
16650        }
16651    }
16652
16653    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16654        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
16655        if (mCurrentUserId == userId) {
16656            return ActivityManager.USER_OP_IS_CURRENT;
16657        }
16658
16659        final UserStartedState uss = mStartedUsers.get(userId);
16660        if (uss == null) {
16661            // User is not started, nothing to do...  but we do need to
16662            // callback if requested.
16663            if (callback != null) {
16664                mHandler.post(new Runnable() {
16665                    @Override
16666                    public void run() {
16667                        try {
16668                            callback.userStopped(userId);
16669                        } catch (RemoteException e) {
16670                        }
16671                    }
16672                });
16673            }
16674            return ActivityManager.USER_OP_SUCCESS;
16675        }
16676
16677        if (callback != null) {
16678            uss.mStopCallbacks.add(callback);
16679        }
16680
16681        if (uss.mState != UserStartedState.STATE_STOPPING
16682                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16683            uss.mState = UserStartedState.STATE_STOPPING;
16684            updateStartedUserArrayLocked();
16685
16686            long ident = Binder.clearCallingIdentity();
16687            try {
16688                // We are going to broadcast ACTION_USER_STOPPING and then
16689                // once that is done send a final ACTION_SHUTDOWN and then
16690                // stop the user.
16691                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16692                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16693                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16694                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16695                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16696                // This is the result receiver for the final shutdown broadcast.
16697                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16698                    @Override
16699                    public void performReceive(Intent intent, int resultCode, String data,
16700                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16701                        finishUserStop(uss);
16702                    }
16703                };
16704                // This is the result receiver for the initial stopping broadcast.
16705                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16706                    @Override
16707                    public void performReceive(Intent intent, int resultCode, String data,
16708                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16709                        // On to the next.
16710                        synchronized (ActivityManagerService.this) {
16711                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16712                                // Whoops, we are being started back up.  Abort, abort!
16713                                return;
16714                            }
16715                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16716                        }
16717                        broadcastIntentLocked(null, null, shutdownIntent,
16718                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16719                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16720                    }
16721                };
16722                // Kick things off.
16723                broadcastIntentLocked(null, null, stoppingIntent,
16724                        null, stoppingReceiver, 0, null, null,
16725                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16726                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16727            } finally {
16728                Binder.restoreCallingIdentity(ident);
16729            }
16730        }
16731
16732        return ActivityManager.USER_OP_SUCCESS;
16733    }
16734
16735    void finishUserStop(UserStartedState uss) {
16736        final int userId = uss.mHandle.getIdentifier();
16737        boolean stopped;
16738        ArrayList<IStopUserCallback> callbacks;
16739        synchronized (this) {
16740            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16741            if (mStartedUsers.get(userId) != uss) {
16742                stopped = false;
16743            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16744                stopped = false;
16745            } else {
16746                stopped = true;
16747                // User can no longer run.
16748                mStartedUsers.remove(userId);
16749                mUserLru.remove(Integer.valueOf(userId));
16750                updateStartedUserArrayLocked();
16751
16752                // Clean up all state and processes associated with the user.
16753                // Kill all the processes for the user.
16754                forceStopUserLocked(userId, "finish user");
16755            }
16756        }
16757
16758        for (int i=0; i<callbacks.size(); i++) {
16759            try {
16760                if (stopped) callbacks.get(i).userStopped(userId);
16761                else callbacks.get(i).userStopAborted(userId);
16762            } catch (RemoteException e) {
16763            }
16764        }
16765
16766        mStackSupervisor.removeUserLocked(userId);
16767    }
16768
16769    @Override
16770    public UserInfo getCurrentUser() {
16771        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16772                != PackageManager.PERMISSION_GRANTED) && (
16773                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16774                != PackageManager.PERMISSION_GRANTED)) {
16775            String msg = "Permission Denial: getCurrentUser() from pid="
16776                    + Binder.getCallingPid()
16777                    + ", uid=" + Binder.getCallingUid()
16778                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16779            Slog.w(TAG, msg);
16780            throw new SecurityException(msg);
16781        }
16782        synchronized (this) {
16783            return getUserManagerLocked().getUserInfo(mCurrentUserId);
16784        }
16785    }
16786
16787    int getCurrentUserIdLocked() {
16788        return mCurrentUserId;
16789    }
16790
16791    @Override
16792    public boolean isUserRunning(int userId, boolean orStopped) {
16793        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16794                != PackageManager.PERMISSION_GRANTED) {
16795            String msg = "Permission Denial: isUserRunning() from pid="
16796                    + Binder.getCallingPid()
16797                    + ", uid=" + Binder.getCallingUid()
16798                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16799            Slog.w(TAG, msg);
16800            throw new SecurityException(msg);
16801        }
16802        synchronized (this) {
16803            return isUserRunningLocked(userId, orStopped);
16804        }
16805    }
16806
16807    boolean isUserRunningLocked(int userId, boolean orStopped) {
16808        UserStartedState state = mStartedUsers.get(userId);
16809        if (state == null) {
16810            return false;
16811        }
16812        if (orStopped) {
16813            return true;
16814        }
16815        return state.mState != UserStartedState.STATE_STOPPING
16816                && state.mState != UserStartedState.STATE_SHUTDOWN;
16817    }
16818
16819    @Override
16820    public int[] getRunningUserIds() {
16821        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16822                != PackageManager.PERMISSION_GRANTED) {
16823            String msg = "Permission Denial: isUserRunning() from pid="
16824                    + Binder.getCallingPid()
16825                    + ", uid=" + Binder.getCallingUid()
16826                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16827            Slog.w(TAG, msg);
16828            throw new SecurityException(msg);
16829        }
16830        synchronized (this) {
16831            return mStartedUserArray;
16832        }
16833    }
16834
16835    private void updateStartedUserArrayLocked() {
16836        int num = 0;
16837        for (int i=0; i<mStartedUsers.size();  i++) {
16838            UserStartedState uss = mStartedUsers.valueAt(i);
16839            // This list does not include stopping users.
16840            if (uss.mState != UserStartedState.STATE_STOPPING
16841                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16842                num++;
16843            }
16844        }
16845        mStartedUserArray = new int[num];
16846        num = 0;
16847        for (int i=0; i<mStartedUsers.size();  i++) {
16848            UserStartedState uss = mStartedUsers.valueAt(i);
16849            if (uss.mState != UserStartedState.STATE_STOPPING
16850                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16851                mStartedUserArray[num] = mStartedUsers.keyAt(i);
16852                num++;
16853            }
16854        }
16855    }
16856
16857    @Override
16858    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
16859        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16860                != PackageManager.PERMISSION_GRANTED) {
16861            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
16862                    + Binder.getCallingPid()
16863                    + ", uid=" + Binder.getCallingUid()
16864                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16865            Slog.w(TAG, msg);
16866            throw new SecurityException(msg);
16867        }
16868
16869        mUserSwitchObservers.register(observer);
16870    }
16871
16872    @Override
16873    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
16874        mUserSwitchObservers.unregister(observer);
16875    }
16876
16877    private boolean userExists(int userId) {
16878        if (userId == 0) {
16879            return true;
16880        }
16881        UserManagerService ums = getUserManagerLocked();
16882        return ums != null ? (ums.getUserInfo(userId) != null) : false;
16883    }
16884
16885    int[] getUsersLocked() {
16886        UserManagerService ums = getUserManagerLocked();
16887        return ums != null ? ums.getUserIds() : new int[] { 0 };
16888    }
16889
16890    UserManagerService getUserManagerLocked() {
16891        if (mUserManager == null) {
16892            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
16893            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
16894        }
16895        return mUserManager;
16896    }
16897
16898    private int applyUserId(int uid, int userId) {
16899        return UserHandle.getUid(userId, uid);
16900    }
16901
16902    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
16903        if (info == null) return null;
16904        ApplicationInfo newInfo = new ApplicationInfo(info);
16905        newInfo.uid = applyUserId(info.uid, userId);
16906        newInfo.dataDir = USER_DATA_DIR + userId + "/"
16907                + info.packageName;
16908        return newInfo;
16909    }
16910
16911    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
16912        if (aInfo == null
16913                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
16914            return aInfo;
16915        }
16916
16917        ActivityInfo info = new ActivityInfo(aInfo);
16918        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
16919        return info;
16920    }
16921}
16922