ActivityManagerService.java revision d00f47402cb886a43a3448128bdcd9dd2f348a2a
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        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2319        if (!activityChange && hasActivity) {
2320            // The process has activties, so we are only going to allow activity-based
2321            // adjustments move it.  It should be kept in the front of the list with other
2322            // processes that have activities, and we don't want those to change their
2323            // order except due to activity operations.
2324            return;
2325        }
2326
2327        mLruSeq++;
2328        final long now = SystemClock.uptimeMillis();
2329        app.lastActivityTime = now;
2330
2331        // First a quick reject: if the app is already at the position we will
2332        // put it, then there is nothing to do.
2333        if (hasActivity) {
2334            final int N = mLruProcesses.size();
2335            if (N > 0 && mLruProcesses.get(N-1) == app) {
2336                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2337                return;
2338            }
2339        } else {
2340            if (mLruProcessServiceStart > 0
2341                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2342                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2343                return;
2344            }
2345        }
2346
2347        int lrui = mLruProcesses.lastIndexOf(app);
2348
2349        if (app.persistent && lrui >= 0) {
2350            // We don't care about the position of persistent processes, as long as
2351            // they are in the list.
2352            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2353            return;
2354        }
2355
2356        /* In progress: compute new position first, so we can avoid doing work
2357           if the process is not actually going to move.  Not yet working.
2358        int addIndex;
2359        int nextIndex;
2360        boolean inActivity = false, inService = false;
2361        if (hasActivity) {
2362            // Process has activities, put it at the very tipsy-top.
2363            addIndex = mLruProcesses.size();
2364            nextIndex = mLruProcessServiceStart;
2365            inActivity = true;
2366        } else if (hasService) {
2367            // Process has services, put it at the top of the service list.
2368            addIndex = mLruProcessActivityStart;
2369            nextIndex = mLruProcessServiceStart;
2370            inActivity = true;
2371            inService = true;
2372        } else  {
2373            // Process not otherwise of interest, it goes to the top of the non-service area.
2374            addIndex = mLruProcessServiceStart;
2375            if (client != null) {
2376                int clientIndex = mLruProcesses.lastIndexOf(client);
2377                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2378                        + app);
2379                if (clientIndex >= 0 && addIndex > clientIndex) {
2380                    addIndex = clientIndex;
2381                }
2382            }
2383            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2384        }
2385
2386        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2387                + mLruProcessActivityStart + "): " + app);
2388        */
2389
2390        if (lrui >= 0) {
2391            if (lrui < mLruProcessActivityStart) {
2392                mLruProcessActivityStart--;
2393            }
2394            if (lrui < mLruProcessServiceStart) {
2395                mLruProcessServiceStart--;
2396            }
2397            /*
2398            if (addIndex > lrui) {
2399                addIndex--;
2400            }
2401            if (nextIndex > lrui) {
2402                nextIndex--;
2403            }
2404            */
2405            mLruProcesses.remove(lrui);
2406        }
2407
2408        /*
2409        mLruProcesses.add(addIndex, app);
2410        if (inActivity) {
2411            mLruProcessActivityStart++;
2412        }
2413        if (inService) {
2414            mLruProcessActivityStart++;
2415        }
2416        */
2417
2418        int nextIndex;
2419        if (hasActivity) {
2420            final int N = mLruProcesses.size();
2421            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2422                // Process doesn't have activities, but has clients with
2423                // activities...  move it up, but one below the top (the top
2424                // should always have a real activity).
2425                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2426                mLruProcesses.add(N-1, app);
2427                // To keep it from spamming the LRU list (by making a bunch of clients),
2428                // we will push down any other entries owned by the app.
2429                final int uid = app.info.uid;
2430                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2431                    ProcessRecord subProc = mLruProcesses.get(i);
2432                    if (subProc.info.uid == uid) {
2433                        // We want to push this one down the list.  If the process after
2434                        // it is for the same uid, however, don't do so, because we don't
2435                        // want them internally to be re-ordered.
2436                        if (mLruProcesses.get(i-1).info.uid != uid) {
2437                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2438                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2439                            ProcessRecord tmp = mLruProcesses.get(i);
2440                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2441                            mLruProcesses.set(i-1, tmp);
2442                            i--;
2443                        }
2444                    } else {
2445                        // A gap, we can stop here.
2446                        break;
2447                    }
2448                }
2449            } else {
2450                // Process has activities, put it at the very tipsy-top.
2451                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2452                mLruProcesses.add(app);
2453            }
2454            nextIndex = mLruProcessServiceStart;
2455        } else if (hasService) {
2456            // Process has services, put it at the top of the service list.
2457            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2458            mLruProcesses.add(mLruProcessActivityStart, app);
2459            nextIndex = mLruProcessServiceStart;
2460            mLruProcessActivityStart++;
2461        } else  {
2462            // Process not otherwise of interest, it goes to the top of the non-service area.
2463            int index = mLruProcessServiceStart;
2464            if (client != null) {
2465                // If there is a client, don't allow the process to be moved up higher
2466                // in the list than that client.
2467                int clientIndex = mLruProcesses.lastIndexOf(client);
2468                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2469                        + " when updating " + app);
2470                if (clientIndex <= lrui) {
2471                    // Don't allow the client index restriction to push it down farther in the
2472                    // list than it already is.
2473                    clientIndex = lrui;
2474                }
2475                if (clientIndex >= 0 && index > clientIndex) {
2476                    index = clientIndex;
2477                }
2478            }
2479            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2480            mLruProcesses.add(index, app);
2481            nextIndex = index-1;
2482            mLruProcessActivityStart++;
2483            mLruProcessServiceStart++;
2484        }
2485
2486        // If the app is currently using a content provider or service,
2487        // bump those processes as well.
2488        for (int j=app.connections.size()-1; j>=0; j--) {
2489            ConnectionRecord cr = app.connections.valueAt(j);
2490            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2491                    && cr.binding.service.app != null
2492                    && cr.binding.service.app.lruSeq != mLruSeq
2493                    && !cr.binding.service.app.persistent) {
2494                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2495                        "service connection", cr, app);
2496            }
2497        }
2498        for (int j=app.conProviders.size()-1; j>=0; j--) {
2499            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2500            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2501                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2502                        "provider reference", cpr, app);
2503            }
2504        }
2505    }
2506
2507    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2508        if (uid == Process.SYSTEM_UID) {
2509            // The system gets to run in any process.  If there are multiple
2510            // processes with the same uid, just pick the first (this
2511            // should never happen).
2512            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2513            if (procs == null) return null;
2514            final int N = procs.size();
2515            for (int i = 0; i < N; i++) {
2516                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2517            }
2518        }
2519        ProcessRecord proc = mProcessNames.get(processName, uid);
2520        if (false && proc != null && !keepIfLarge
2521                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2522                && proc.lastCachedPss >= 4000) {
2523            // Turn this condition on to cause killing to happen regularly, for testing.
2524            if (proc.baseProcessTracker != null) {
2525                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2526            }
2527            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2528                    + "k from cached");
2529        } else if (proc != null && !keepIfLarge
2530                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2531                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2532            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2533            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2534                if (proc.baseProcessTracker != null) {
2535                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2536                }
2537                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2538                        + "k from cached");
2539            }
2540        }
2541        return proc;
2542    }
2543
2544    void ensurePackageDexOpt(String packageName) {
2545        IPackageManager pm = AppGlobals.getPackageManager();
2546        try {
2547            if (pm.performDexOpt(packageName)) {
2548                mDidDexOpt = true;
2549            }
2550        } catch (RemoteException e) {
2551        }
2552    }
2553
2554    boolean isNextTransitionForward() {
2555        int transit = mWindowManager.getPendingAppTransition();
2556        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2557                || transit == AppTransition.TRANSIT_TASK_OPEN
2558                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2559    }
2560
2561    final ProcessRecord startProcessLocked(String processName,
2562            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2563            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2564            boolean isolated, boolean keepIfLarge) {
2565        ProcessRecord app;
2566        if (!isolated) {
2567            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2568        } else {
2569            // If this is an isolated process, it can't re-use an existing process.
2570            app = null;
2571        }
2572        // We don't have to do anything more if:
2573        // (1) There is an existing application record; and
2574        // (2) The caller doesn't think it is dead, OR there is no thread
2575        //     object attached to it so we know it couldn't have crashed; and
2576        // (3) There is a pid assigned to it, so it is either starting or
2577        //     already running.
2578        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2579                + " app=" + app + " knownToBeDead=" + knownToBeDead
2580                + " thread=" + (app != null ? app.thread : null)
2581                + " pid=" + (app != null ? app.pid : -1));
2582        if (app != null && app.pid > 0) {
2583            if (!knownToBeDead || app.thread == null) {
2584                // We already have the app running, or are waiting for it to
2585                // come up (we have a pid but not yet its thread), so keep it.
2586                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2587                // If this is a new package in the process, add the package to the list
2588                app.addPackage(info.packageName, mProcessStats);
2589                return app;
2590            }
2591
2592            // An application record is attached to a previous process,
2593            // clean it up now.
2594            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2595            handleAppDiedLocked(app, true, true);
2596        }
2597
2598        String hostingNameStr = hostingName != null
2599                ? hostingName.flattenToShortString() : null;
2600
2601        if (!isolated) {
2602            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2603                // If we are in the background, then check to see if this process
2604                // is bad.  If so, we will just silently fail.
2605                if (mBadProcesses.get(info.processName, info.uid) != null) {
2606                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2607                            + "/" + info.processName);
2608                    return null;
2609                }
2610            } else {
2611                // When the user is explicitly starting a process, then clear its
2612                // crash count so that we won't make it bad until they see at
2613                // least one crash dialog again, and make the process good again
2614                // if it had been bad.
2615                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2616                        + "/" + info.processName);
2617                mProcessCrashTimes.remove(info.processName, info.uid);
2618                if (mBadProcesses.get(info.processName, info.uid) != null) {
2619                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2620                            UserHandle.getUserId(info.uid), info.uid,
2621                            info.processName);
2622                    mBadProcesses.remove(info.processName, info.uid);
2623                    if (app != null) {
2624                        app.bad = false;
2625                    }
2626                }
2627            }
2628        }
2629
2630        if (app == null) {
2631            app = newProcessRecordLocked(info, processName, isolated);
2632            if (app == null) {
2633                Slog.w(TAG, "Failed making new process record for "
2634                        + processName + "/" + info.uid + " isolated=" + isolated);
2635                return null;
2636            }
2637            mProcessNames.put(processName, app.uid, app);
2638            if (isolated) {
2639                mIsolatedProcesses.put(app.uid, app);
2640            }
2641        } else {
2642            // If this is a new package in the process, add the package to the list
2643            app.addPackage(info.packageName, mProcessStats);
2644        }
2645
2646        // If the system is not ready yet, then hold off on starting this
2647        // process until it is.
2648        if (!mProcessesReady
2649                && !isAllowedWhileBooting(info)
2650                && !allowWhileBooting) {
2651            if (!mProcessesOnHold.contains(app)) {
2652                mProcessesOnHold.add(app);
2653            }
2654            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2655            return app;
2656        }
2657
2658        startProcessLocked(app, hostingType, hostingNameStr);
2659        return (app.pid != 0) ? app : null;
2660    }
2661
2662    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2663        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2664    }
2665
2666    private final void startProcessLocked(ProcessRecord app,
2667            String hostingType, String hostingNameStr) {
2668        if (app.pid > 0 && app.pid != MY_PID) {
2669            synchronized (mPidsSelfLocked) {
2670                mPidsSelfLocked.remove(app.pid);
2671                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2672            }
2673            app.setPid(0);
2674        }
2675
2676        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2677                "startProcessLocked removing on hold: " + app);
2678        mProcessesOnHold.remove(app);
2679
2680        updateCpuStats();
2681
2682        try {
2683            int uid = app.uid;
2684
2685            int[] gids = null;
2686            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2687            if (!app.isolated) {
2688                int[] permGids = null;
2689                try {
2690                    final PackageManager pm = mContext.getPackageManager();
2691                    permGids = pm.getPackageGids(app.info.packageName);
2692
2693                    if (Environment.isExternalStorageEmulated()) {
2694                        if (pm.checkPermission(
2695                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2696                                app.info.packageName) == PERMISSION_GRANTED) {
2697                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2698                        } else {
2699                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2700                        }
2701                    }
2702                } catch (PackageManager.NameNotFoundException e) {
2703                    Slog.w(TAG, "Unable to retrieve gids", e);
2704                }
2705
2706                /*
2707                 * Add shared application GID so applications can share some
2708                 * resources like shared libraries
2709                 */
2710                if (permGids == null) {
2711                    gids = new int[1];
2712                } else {
2713                    gids = new int[permGids.length + 1];
2714                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2715                }
2716                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2717            }
2718            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2719                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2720                        && mTopComponent != null
2721                        && app.processName.equals(mTopComponent.getPackageName())) {
2722                    uid = 0;
2723                }
2724                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2725                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2726                    uid = 0;
2727                }
2728            }
2729            int debugFlags = 0;
2730            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2731                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2732                // Also turn on CheckJNI for debuggable apps. It's quite
2733                // awkward to turn on otherwise.
2734                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2735            }
2736            // Run the app in safe mode if its manifest requests so or the
2737            // system is booted in safe mode.
2738            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2739                Zygote.systemInSafeMode == true) {
2740                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2741            }
2742            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2743                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2744            }
2745            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2746                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2747            }
2748            if ("1".equals(SystemProperties.get("debug.assert"))) {
2749                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2750            }
2751
2752            // Start the process.  It will either succeed and return a result containing
2753            // the PID of the new process, or else throw a RuntimeException.
2754            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2755                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2756                    app.info.targetSdkVersion, app.info.seinfo, null);
2757
2758            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2759            synchronized (bs) {
2760                if (bs.isOnBattery()) {
2761                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2762                }
2763            }
2764
2765            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2766                    UserHandle.getUserId(uid), startResult.pid, uid,
2767                    app.processName, hostingType,
2768                    hostingNameStr != null ? hostingNameStr : "");
2769
2770            if (app.persistent) {
2771                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2772            }
2773
2774            StringBuilder buf = mStringBuilder;
2775            buf.setLength(0);
2776            buf.append("Start proc ");
2777            buf.append(app.processName);
2778            buf.append(" for ");
2779            buf.append(hostingType);
2780            if (hostingNameStr != null) {
2781                buf.append(" ");
2782                buf.append(hostingNameStr);
2783            }
2784            buf.append(": pid=");
2785            buf.append(startResult.pid);
2786            buf.append(" uid=");
2787            buf.append(uid);
2788            buf.append(" gids={");
2789            if (gids != null) {
2790                for (int gi=0; gi<gids.length; gi++) {
2791                    if (gi != 0) buf.append(", ");
2792                    buf.append(gids[gi]);
2793
2794                }
2795            }
2796            buf.append("}");
2797            Slog.i(TAG, buf.toString());
2798            app.setPid(startResult.pid);
2799            app.usingWrapper = startResult.usingWrapper;
2800            app.removed = false;
2801            synchronized (mPidsSelfLocked) {
2802                this.mPidsSelfLocked.put(startResult.pid, app);
2803                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2804                msg.obj = app;
2805                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2806                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2807            }
2808            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
2809                    app.processName, app.info.uid);
2810            if (app.isolated) {
2811                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2812            }
2813        } catch (RuntimeException e) {
2814            // XXX do better error recovery.
2815            app.setPid(0);
2816            Slog.e(TAG, "Failure starting process " + app.processName, e);
2817        }
2818    }
2819
2820    void updateUsageStats(ActivityRecord component, boolean resumed) {
2821        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
2822        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2823        if (resumed) {
2824            mUsageStatsService.noteResumeComponent(component.realActivity);
2825            synchronized (stats) {
2826                stats.noteActivityResumedLocked(component.app.uid);
2827            }
2828        } else {
2829            mUsageStatsService.notePauseComponent(component.realActivity);
2830            synchronized (stats) {
2831                stats.noteActivityPausedLocked(component.app.uid);
2832            }
2833        }
2834    }
2835
2836    Intent getHomeIntent() {
2837        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
2838        intent.setComponent(mTopComponent);
2839        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
2840            intent.addCategory(Intent.CATEGORY_HOME);
2841        }
2842        return intent;
2843    }
2844
2845    boolean startHomeActivityLocked(int userId) {
2846        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2847                && mTopAction == null) {
2848            // We are running in factory test mode, but unable to find
2849            // the factory test app, so just sit around displaying the
2850            // error message and don't try to start anything.
2851            return false;
2852        }
2853        Intent intent = getHomeIntent();
2854        ActivityInfo aInfo =
2855            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2856        if (aInfo != null) {
2857            intent.setComponent(new ComponentName(
2858                    aInfo.applicationInfo.packageName, aInfo.name));
2859            // Don't do this if the home app is currently being
2860            // instrumented.
2861            aInfo = new ActivityInfo(aInfo);
2862            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2863            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2864                    aInfo.applicationInfo.uid, true);
2865            if (app == null || app.instrumentationClass == null) {
2866                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2867                mStackSupervisor.startHomeActivity(intent, aInfo);
2868            }
2869        }
2870
2871        return true;
2872    }
2873
2874    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2875        ActivityInfo ai = null;
2876        ComponentName comp = intent.getComponent();
2877        try {
2878            if (comp != null) {
2879                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2880            } else {
2881                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2882                        intent,
2883                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2884                            flags, userId);
2885
2886                if (info != null) {
2887                    ai = info.activityInfo;
2888                }
2889            }
2890        } catch (RemoteException e) {
2891            // ignore
2892        }
2893
2894        return ai;
2895    }
2896
2897    /**
2898     * Starts the "new version setup screen" if appropriate.
2899     */
2900    void startSetupActivityLocked() {
2901        // Only do this once per boot.
2902        if (mCheckedForSetup) {
2903            return;
2904        }
2905
2906        // We will show this screen if the current one is a different
2907        // version than the last one shown, and we are not running in
2908        // low-level factory test mode.
2909        final ContentResolver resolver = mContext.getContentResolver();
2910        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
2911                Settings.Global.getInt(resolver,
2912                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
2913            mCheckedForSetup = true;
2914
2915            // See if we should be showing the platform update setup UI.
2916            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2917            List<ResolveInfo> ris = mContext.getPackageManager()
2918                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2919
2920            // We don't allow third party apps to replace this.
2921            ResolveInfo ri = null;
2922            for (int i=0; ris != null && i<ris.size(); i++) {
2923                if ((ris.get(i).activityInfo.applicationInfo.flags
2924                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2925                    ri = ris.get(i);
2926                    break;
2927                }
2928            }
2929
2930            if (ri != null) {
2931                String vers = ri.activityInfo.metaData != null
2932                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2933                        : null;
2934                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2935                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2936                            Intent.METADATA_SETUP_VERSION);
2937                }
2938                String lastVers = Settings.Secure.getString(
2939                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2940                if (vers != null && !vers.equals(lastVers)) {
2941                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2942                    intent.setComponent(new ComponentName(
2943                            ri.activityInfo.packageName, ri.activityInfo.name));
2944                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
2945                            null, null, 0, 0, 0, null, 0, null, false, null, null);
2946                }
2947            }
2948        }
2949    }
2950
2951    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2952        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2953    }
2954
2955    void enforceNotIsolatedCaller(String caller) {
2956        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2957            throw new SecurityException("Isolated process not allowed to call " + caller);
2958        }
2959    }
2960
2961    @Override
2962    public int getFrontActivityScreenCompatMode() {
2963        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2964        synchronized (this) {
2965            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2966        }
2967    }
2968
2969    @Override
2970    public void setFrontActivityScreenCompatMode(int mode) {
2971        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2972                "setFrontActivityScreenCompatMode");
2973        synchronized (this) {
2974            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2975        }
2976    }
2977
2978    @Override
2979    public int getPackageScreenCompatMode(String packageName) {
2980        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2981        synchronized (this) {
2982            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2983        }
2984    }
2985
2986    @Override
2987    public void setPackageScreenCompatMode(String packageName, int mode) {
2988        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2989                "setPackageScreenCompatMode");
2990        synchronized (this) {
2991            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2992        }
2993    }
2994
2995    @Override
2996    public boolean getPackageAskScreenCompat(String packageName) {
2997        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2998        synchronized (this) {
2999            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3000        }
3001    }
3002
3003    @Override
3004    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3005        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3006                "setPackageAskScreenCompat");
3007        synchronized (this) {
3008            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3009        }
3010    }
3011
3012    private void dispatchProcessesChanged() {
3013        int N;
3014        synchronized (this) {
3015            N = mPendingProcessChanges.size();
3016            if (mActiveProcessChanges.length < N) {
3017                mActiveProcessChanges = new ProcessChangeItem[N];
3018            }
3019            mPendingProcessChanges.toArray(mActiveProcessChanges);
3020            mAvailProcessChanges.addAll(mPendingProcessChanges);
3021            mPendingProcessChanges.clear();
3022            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3023        }
3024
3025        int i = mProcessObservers.beginBroadcast();
3026        while (i > 0) {
3027            i--;
3028            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3029            if (observer != null) {
3030                try {
3031                    for (int j=0; j<N; j++) {
3032                        ProcessChangeItem item = mActiveProcessChanges[j];
3033                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3034                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3035                                    + item.pid + " uid=" + item.uid + ": "
3036                                    + item.foregroundActivities);
3037                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3038                                    item.foregroundActivities);
3039                        }
3040                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
3041                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
3042                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
3043                            observer.onImportanceChanged(item.pid, item.uid,
3044                                    item.importance);
3045                        }
3046                    }
3047                } catch (RemoteException e) {
3048                }
3049            }
3050        }
3051        mProcessObservers.finishBroadcast();
3052    }
3053
3054    private void dispatchProcessDied(int pid, int uid) {
3055        int i = mProcessObservers.beginBroadcast();
3056        while (i > 0) {
3057            i--;
3058            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3059            if (observer != null) {
3060                try {
3061                    observer.onProcessDied(pid, uid);
3062                } catch (RemoteException e) {
3063                }
3064            }
3065        }
3066        mProcessObservers.finishBroadcast();
3067    }
3068
3069    final void doPendingActivityLaunchesLocked(boolean doResume) {
3070        final int N = mPendingActivityLaunches.size();
3071        if (N <= 0) {
3072            return;
3073        }
3074        for (int i=0; i<N; i++) {
3075            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3076            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags,
3077                    doResume && i == (N-1), null);
3078        }
3079        mPendingActivityLaunches.clear();
3080    }
3081
3082    @Override
3083    public final int startActivity(IApplicationThread caller, String callingPackage,
3084            Intent intent, String resolvedType, IBinder resultTo,
3085            String resultWho, int requestCode, int startFlags,
3086            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3087        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3088                resultWho, requestCode,
3089                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3090    }
3091
3092    @Override
3093    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3094            Intent intent, String resolvedType, IBinder resultTo,
3095            String resultWho, int requestCode, int startFlags,
3096            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3097        enforceNotIsolatedCaller("startActivity");
3098        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3099                false, true, "startActivity", null);
3100        // TODO: Switch to user app stacks here.
3101        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3102                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3103                null, null, options, userId, null);
3104    }
3105
3106    @Override
3107    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3108            Intent intent, String resolvedType, IBinder resultTo,
3109            String resultWho, int requestCode, int startFlags, String profileFile,
3110            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3111        enforceNotIsolatedCaller("startActivityAndWait");
3112        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3113                false, true, "startActivityAndWait", null);
3114        WaitResult res = new WaitResult();
3115        // TODO: Switch to user app stacks here.
3116        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3117                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3118                res, null, options, UserHandle.getCallingUserId(), null);
3119        return res;
3120    }
3121
3122    @Override
3123    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3124            Intent intent, String resolvedType, IBinder resultTo,
3125            String resultWho, int requestCode, int startFlags, Configuration config,
3126            Bundle options, int userId) {
3127        enforceNotIsolatedCaller("startActivityWithConfig");
3128        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3129                false, true, "startActivityWithConfig", null);
3130        // TODO: Switch to user app stacks here.
3131        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3132                resolvedType, resultTo, resultWho, requestCode, startFlags,
3133                null, null, null, config, options, userId, null);
3134        return ret;
3135    }
3136
3137    @Override
3138    public int startActivityIntentSender(IApplicationThread caller,
3139            IntentSender intent, Intent fillInIntent, String resolvedType,
3140            IBinder resultTo, String resultWho, int requestCode,
3141            int flagsMask, int flagsValues, Bundle options) {
3142        enforceNotIsolatedCaller("startActivityIntentSender");
3143        // Refuse possible leaked file descriptors
3144        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3145            throw new IllegalArgumentException("File descriptors passed in Intent");
3146        }
3147
3148        IIntentSender sender = intent.getTarget();
3149        if (!(sender instanceof PendingIntentRecord)) {
3150            throw new IllegalArgumentException("Bad PendingIntent object");
3151        }
3152
3153        PendingIntentRecord pir = (PendingIntentRecord)sender;
3154
3155        synchronized (this) {
3156            // If this is coming from the currently resumed activity, it is
3157            // effectively saying that app switches are allowed at this point.
3158            final ActivityStack stack = getFocusedStack();
3159            if (stack.mResumedActivity != null &&
3160                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3161                mAppSwitchesAllowedTime = 0;
3162            }
3163        }
3164        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3165                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3166        return ret;
3167    }
3168
3169    @Override
3170    public boolean startNextMatchingActivity(IBinder callingActivity,
3171            Intent intent, Bundle options) {
3172        // Refuse possible leaked file descriptors
3173        if (intent != null && intent.hasFileDescriptors() == true) {
3174            throw new IllegalArgumentException("File descriptors passed in Intent");
3175        }
3176
3177        synchronized (this) {
3178            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3179            if (r == null) {
3180                ActivityOptions.abort(options);
3181                return false;
3182            }
3183            if (r.app == null || r.app.thread == null) {
3184                // The caller is not running...  d'oh!
3185                ActivityOptions.abort(options);
3186                return false;
3187            }
3188            intent = new Intent(intent);
3189            // The caller is not allowed to change the data.
3190            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3191            // And we are resetting to find the next component...
3192            intent.setComponent(null);
3193
3194            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3195
3196            ActivityInfo aInfo = null;
3197            try {
3198                List<ResolveInfo> resolves =
3199                    AppGlobals.getPackageManager().queryIntentActivities(
3200                            intent, r.resolvedType,
3201                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3202                            UserHandle.getCallingUserId());
3203
3204                // Look for the original activity in the list...
3205                final int N = resolves != null ? resolves.size() : 0;
3206                for (int i=0; i<N; i++) {
3207                    ResolveInfo rInfo = resolves.get(i);
3208                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3209                            && rInfo.activityInfo.name.equals(r.info.name)) {
3210                        // We found the current one...  the next matching is
3211                        // after it.
3212                        i++;
3213                        if (i<N) {
3214                            aInfo = resolves.get(i).activityInfo;
3215                        }
3216                        if (debug) {
3217                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3218                                    + "/" + r.info.name);
3219                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3220                                    + "/" + aInfo.name);
3221                        }
3222                        break;
3223                    }
3224                }
3225            } catch (RemoteException e) {
3226            }
3227
3228            if (aInfo == null) {
3229                // Nobody who is next!
3230                ActivityOptions.abort(options);
3231                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3232                return false;
3233            }
3234
3235            intent.setComponent(new ComponentName(
3236                    aInfo.applicationInfo.packageName, aInfo.name));
3237            intent.setFlags(intent.getFlags()&~(
3238                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3239                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3240                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3241                    Intent.FLAG_ACTIVITY_NEW_TASK));
3242
3243            // Okay now we need to start the new activity, replacing the
3244            // currently running activity.  This is a little tricky because
3245            // we want to start the new one as if the current one is finished,
3246            // but not finish the current one first so that there is no flicker.
3247            // And thus...
3248            final boolean wasFinishing = r.finishing;
3249            r.finishing = true;
3250
3251            // Propagate reply information over to the new activity.
3252            final ActivityRecord resultTo = r.resultTo;
3253            final String resultWho = r.resultWho;
3254            final int requestCode = r.requestCode;
3255            r.resultTo = null;
3256            if (resultTo != null) {
3257                resultTo.removeResultsLocked(r, resultWho, requestCode);
3258            }
3259
3260            final long origId = Binder.clearCallingIdentity();
3261            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3262                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
3263                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3264                    options, false, null, null);
3265            Binder.restoreCallingIdentity(origId);
3266
3267            r.finishing = wasFinishing;
3268            if (res != ActivityManager.START_SUCCESS) {
3269                return false;
3270            }
3271            return true;
3272        }
3273    }
3274
3275    final int startActivityInPackage(int uid, String callingPackage,
3276            Intent intent, String resolvedType, IBinder resultTo,
3277            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3278                    IActivityContainer container) {
3279
3280        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3281                false, true, "startActivityInPackage", null);
3282
3283        // TODO: Switch to user app stacks here.
3284        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3285                resultTo, resultWho, requestCode, startFlags,
3286                null, null, null, null, options, userId, container);
3287        return ret;
3288    }
3289
3290    @Override
3291    public final int startActivities(IApplicationThread caller, String callingPackage,
3292            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3293            int userId) {
3294        enforceNotIsolatedCaller("startActivities");
3295        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3296                false, true, "startActivity", null);
3297        // TODO: Switch to user app stacks here.
3298        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3299                resolvedTypes, resultTo, options, userId);
3300        return ret;
3301    }
3302
3303    final int startActivitiesInPackage(int uid, String callingPackage,
3304            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3305            Bundle options, int userId) {
3306
3307        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3308                false, true, "startActivityInPackage", null);
3309        // TODO: Switch to user app stacks here.
3310        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3311                resultTo, options, userId);
3312        return ret;
3313    }
3314
3315    final void addRecentTaskLocked(TaskRecord task) {
3316        int N = mRecentTasks.size();
3317        // Quick case: check if the top-most recent task is the same.
3318        if (N > 0 && mRecentTasks.get(0) == task) {
3319            return;
3320        }
3321        // Remove any existing entries that are the same kind of task.
3322        final Intent intent = task.intent;
3323        final boolean document = intent != null && intent.isDocument();
3324        for (int i=0; i<N; i++) {
3325            TaskRecord tr = mRecentTasks.get(i);
3326            if (task != tr) {
3327                if (task.userId != tr.userId) {
3328                    continue;
3329                }
3330                final Intent trIntent = tr.intent;
3331                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3332                    (intent == null || !intent.filterEquals(trIntent))) {
3333                    continue;
3334                }
3335                if (document || trIntent != null && trIntent.isDocument()) {
3336                    // Document tasks do not match other tasks.
3337                    continue;
3338                }
3339            }
3340
3341            // Either task and tr are the same or, their affinities match or their intents match
3342            // and neither of them is a document.
3343            tr.disposeThumbnail();
3344            mRecentTasks.remove(i);
3345            i--;
3346            N--;
3347            if (task.intent == null) {
3348                // If the new recent task we are adding is not fully
3349                // specified, then replace it with the existing recent task.
3350                task = tr;
3351            }
3352        }
3353        if (N >= MAX_RECENT_TASKS) {
3354            mRecentTasks.remove(N-1).disposeThumbnail();
3355        }
3356        mRecentTasks.add(0, task);
3357    }
3358
3359    @Override
3360    public void reportActivityFullyDrawn(IBinder token) {
3361        synchronized (this) {
3362            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3363            if (r == null) {
3364                return;
3365            }
3366            r.reportFullyDrawnLocked();
3367        }
3368    }
3369
3370    @Override
3371    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3372        synchronized (this) {
3373            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3374            if (r == null) {
3375                return;
3376            }
3377            final long origId = Binder.clearCallingIdentity();
3378            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3379            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3380                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3381            if (config != null) {
3382                r.frozenBeforeDestroy = true;
3383                if (!updateConfigurationLocked(config, r, false, false)) {
3384                    mStackSupervisor.resumeTopActivitiesLocked();
3385                }
3386            }
3387            Binder.restoreCallingIdentity(origId);
3388        }
3389    }
3390
3391    @Override
3392    public int getRequestedOrientation(IBinder token) {
3393        synchronized (this) {
3394            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3395            if (r == null) {
3396                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3397            }
3398            return mWindowManager.getAppOrientation(r.appToken);
3399        }
3400    }
3401
3402    /**
3403     * This is the internal entry point for handling Activity.finish().
3404     *
3405     * @param token The Binder token referencing the Activity we want to finish.
3406     * @param resultCode Result code, if any, from this Activity.
3407     * @param resultData Result data (Intent), if any, from this Activity.
3408     *
3409     * @return Returns true if the activity successfully finished, or false if it is still running.
3410     */
3411    @Override
3412    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
3413        // Refuse possible leaked file descriptors
3414        if (resultData != null && resultData.hasFileDescriptors() == true) {
3415            throw new IllegalArgumentException("File descriptors passed in Intent");
3416        }
3417
3418        synchronized(this) {
3419            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3420            if (r == null) {
3421                return true;
3422            }
3423            if (mController != null) {
3424                // Find the first activity that is not finishing.
3425                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3426                if (next != null) {
3427                    // ask watcher if this is allowed
3428                    boolean resumeOK = true;
3429                    try {
3430                        resumeOK = mController.activityResuming(next.packageName);
3431                    } catch (RemoteException e) {
3432                        mController = null;
3433                        Watchdog.getInstance().setActivityController(null);
3434                    }
3435
3436                    if (!resumeOK) {
3437                        return false;
3438                    }
3439                }
3440            }
3441            final long origId = Binder.clearCallingIdentity();
3442            boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode,
3443                    resultData, "app-request", true);
3444            Binder.restoreCallingIdentity(origId);
3445            return res;
3446        }
3447    }
3448
3449    @Override
3450    public final void finishHeavyWeightApp() {
3451        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3452                != PackageManager.PERMISSION_GRANTED) {
3453            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3454                    + Binder.getCallingPid()
3455                    + ", uid=" + Binder.getCallingUid()
3456                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3457            Slog.w(TAG, msg);
3458            throw new SecurityException(msg);
3459        }
3460
3461        synchronized(this) {
3462            if (mHeavyWeightProcess == null) {
3463                return;
3464            }
3465
3466            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3467                    mHeavyWeightProcess.activities);
3468            for (int i=0; i<activities.size(); i++) {
3469                ActivityRecord r = activities.get(i);
3470                if (!r.finishing) {
3471                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3472                            null, "finish-heavy", true);
3473                }
3474            }
3475
3476            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3477                    mHeavyWeightProcess.userId, 0));
3478            mHeavyWeightProcess = null;
3479        }
3480    }
3481
3482    @Override
3483    public void crashApplication(int uid, int initialPid, String packageName,
3484            String message) {
3485        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3486                != PackageManager.PERMISSION_GRANTED) {
3487            String msg = "Permission Denial: crashApplication() from pid="
3488                    + Binder.getCallingPid()
3489                    + ", uid=" + Binder.getCallingUid()
3490                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3491            Slog.w(TAG, msg);
3492            throw new SecurityException(msg);
3493        }
3494
3495        synchronized(this) {
3496            ProcessRecord proc = null;
3497
3498            // Figure out which process to kill.  We don't trust that initialPid
3499            // still has any relation to current pids, so must scan through the
3500            // list.
3501            synchronized (mPidsSelfLocked) {
3502                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3503                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3504                    if (p.uid != uid) {
3505                        continue;
3506                    }
3507                    if (p.pid == initialPid) {
3508                        proc = p;
3509                        break;
3510                    }
3511                    if (p.pkgList.containsKey(packageName)) {
3512                        proc = p;
3513                    }
3514                }
3515            }
3516
3517            if (proc == null) {
3518                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3519                        + " initialPid=" + initialPid
3520                        + " packageName=" + packageName);
3521                return;
3522            }
3523
3524            if (proc.thread != null) {
3525                if (proc.pid == Process.myPid()) {
3526                    Log.w(TAG, "crashApplication: trying to crash self!");
3527                    return;
3528                }
3529                long ident = Binder.clearCallingIdentity();
3530                try {
3531                    proc.thread.scheduleCrash(message);
3532                } catch (RemoteException e) {
3533                }
3534                Binder.restoreCallingIdentity(ident);
3535            }
3536        }
3537    }
3538
3539    @Override
3540    public final void finishSubActivity(IBinder token, String resultWho,
3541            int requestCode) {
3542        synchronized(this) {
3543            final long origId = Binder.clearCallingIdentity();
3544            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3545            if (r != null) {
3546                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3547            }
3548            Binder.restoreCallingIdentity(origId);
3549        }
3550    }
3551
3552    @Override
3553    public boolean finishActivityAffinity(IBinder token) {
3554        synchronized(this) {
3555            final long origId = Binder.clearCallingIdentity();
3556            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3557            boolean res = false;
3558            if (r != null) {
3559                res = r.task.stack.finishActivityAffinityLocked(r);
3560            }
3561            Binder.restoreCallingIdentity(origId);
3562            return res;
3563        }
3564    }
3565
3566    @Override
3567    public boolean willActivityBeVisible(IBinder token) {
3568        synchronized(this) {
3569            ActivityStack stack = ActivityRecord.getStackLocked(token);
3570            if (stack != null) {
3571                return stack.willActivityBeVisibleLocked(token);
3572            }
3573            return false;
3574        }
3575    }
3576
3577    @Override
3578    public void overridePendingTransition(IBinder token, String packageName,
3579            int enterAnim, int exitAnim) {
3580        synchronized(this) {
3581            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3582            if (self == null) {
3583                return;
3584            }
3585
3586            final long origId = Binder.clearCallingIdentity();
3587
3588            if (self.state == ActivityState.RESUMED
3589                    || self.state == ActivityState.PAUSING) {
3590                mWindowManager.overridePendingAppTransition(packageName,
3591                        enterAnim, exitAnim, null);
3592            }
3593
3594            Binder.restoreCallingIdentity(origId);
3595        }
3596    }
3597
3598    /**
3599     * Main function for removing an existing process from the activity manager
3600     * as a result of that process going away.  Clears out all connections
3601     * to the process.
3602     */
3603    private final void handleAppDiedLocked(ProcessRecord app,
3604            boolean restarting, boolean allowRestart) {
3605        int pid = app.pid;
3606        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3607        if (!restarting) {
3608            removeLruProcessLocked(app);
3609            if (pid > 0) {
3610                ProcessList.remove(pid);
3611            }
3612        }
3613
3614        if (mProfileProc == app) {
3615            clearProfilerLocked();
3616        }
3617
3618        // Remove this application's activities from active lists.
3619        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3620
3621        app.activities.clear();
3622
3623        if (app.instrumentationClass != null) {
3624            Slog.w(TAG, "Crash of app " + app.processName
3625                  + " running instrumentation " + app.instrumentationClass);
3626            Bundle info = new Bundle();
3627            info.putString("shortMsg", "Process crashed.");
3628            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3629        }
3630
3631        if (!restarting) {
3632            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3633                // If there was nothing to resume, and we are not already
3634                // restarting this process, but there is a visible activity that
3635                // is hosted by the process...  then make sure all visible
3636                // activities are running, taking care of restarting this
3637                // process.
3638                if (hasVisibleActivities) {
3639                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3640                }
3641            }
3642        }
3643    }
3644
3645    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3646        IBinder threadBinder = thread.asBinder();
3647        // Find the application record.
3648        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3649            ProcessRecord rec = mLruProcesses.get(i);
3650            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3651                return i;
3652            }
3653        }
3654        return -1;
3655    }
3656
3657    final ProcessRecord getRecordForAppLocked(
3658            IApplicationThread thread) {
3659        if (thread == null) {
3660            return null;
3661        }
3662
3663        int appIndex = getLRURecordIndexForAppLocked(thread);
3664        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3665    }
3666
3667    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3668        // If there are no longer any background processes running,
3669        // and the app that died was not running instrumentation,
3670        // then tell everyone we are now low on memory.
3671        boolean haveBg = false;
3672        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3673            ProcessRecord rec = mLruProcesses.get(i);
3674            if (rec.thread != null
3675                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3676                haveBg = true;
3677                break;
3678            }
3679        }
3680
3681        if (!haveBg) {
3682            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3683            if (doReport) {
3684                long now = SystemClock.uptimeMillis();
3685                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3686                    doReport = false;
3687                } else {
3688                    mLastMemUsageReportTime = now;
3689                }
3690            }
3691            final ArrayList<ProcessMemInfo> memInfos
3692                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3693            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3694            long now = SystemClock.uptimeMillis();
3695            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3696                ProcessRecord rec = mLruProcesses.get(i);
3697                if (rec == dyingProc || rec.thread == null) {
3698                    continue;
3699                }
3700                if (doReport) {
3701                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3702                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3703                }
3704                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3705                    // The low memory report is overriding any current
3706                    // state for a GC request.  Make sure to do
3707                    // heavy/important/visible/foreground processes first.
3708                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3709                        rec.lastRequestedGc = 0;
3710                    } else {
3711                        rec.lastRequestedGc = rec.lastLowMemory;
3712                    }
3713                    rec.reportLowMemory = true;
3714                    rec.lastLowMemory = now;
3715                    mProcessesToGc.remove(rec);
3716                    addProcessToGcListLocked(rec);
3717                }
3718            }
3719            if (doReport) {
3720                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3721                mHandler.sendMessage(msg);
3722            }
3723            scheduleAppGcsLocked();
3724        }
3725    }
3726
3727    final void appDiedLocked(ProcessRecord app, int pid,
3728            IApplicationThread thread) {
3729
3730        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3731        synchronized (stats) {
3732            stats.noteProcessDiedLocked(app.info.uid, pid);
3733        }
3734
3735        // Clean up already done if the process has been re-started.
3736        if (app.pid == pid && app.thread != null &&
3737                app.thread.asBinder() == thread.asBinder()) {
3738            boolean doLowMem = app.instrumentationClass == null;
3739            boolean doOomAdj = doLowMem;
3740            if (!app.killedByAm) {
3741                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3742                        + ") has died.");
3743                mAllowLowerMemLevel = true;
3744            } else {
3745                // Note that we always want to do oom adj to update our state with the
3746                // new number of procs.
3747                mAllowLowerMemLevel = false;
3748                doLowMem = false;
3749            }
3750            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3751            if (DEBUG_CLEANUP) Slog.v(
3752                TAG, "Dying app: " + app + ", pid: " + pid
3753                + ", thread: " + thread.asBinder());
3754            handleAppDiedLocked(app, false, true);
3755
3756            if (doOomAdj) {
3757                updateOomAdjLocked();
3758            }
3759            if (doLowMem) {
3760                doLowMemReportIfNeededLocked(app);
3761            }
3762        } else if (app.pid != pid) {
3763            // A new process has already been started.
3764            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3765                    + ") has died and restarted (pid " + app.pid + ").");
3766            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3767        } else if (DEBUG_PROCESSES) {
3768            Slog.d(TAG, "Received spurious death notification for thread "
3769                    + thread.asBinder());
3770        }
3771    }
3772
3773    /**
3774     * If a stack trace dump file is configured, dump process stack traces.
3775     * @param clearTraces causes the dump file to be erased prior to the new
3776     *    traces being written, if true; when false, the new traces will be
3777     *    appended to any existing file content.
3778     * @param firstPids of dalvik VM processes to dump stack traces for first
3779     * @param lastPids of dalvik VM processes to dump stack traces for last
3780     * @param nativeProcs optional list of native process names to dump stack crawls
3781     * @return file containing stack traces, or null if no dump file is configured
3782     */
3783    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3784            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3785        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3786        if (tracesPath == null || tracesPath.length() == 0) {
3787            return null;
3788        }
3789
3790        File tracesFile = new File(tracesPath);
3791        try {
3792            File tracesDir = tracesFile.getParentFile();
3793            if (!tracesDir.exists()) {
3794                tracesFile.mkdirs();
3795                if (!SELinux.restorecon(tracesDir)) {
3796                    return null;
3797                }
3798            }
3799            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3800
3801            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3802            tracesFile.createNewFile();
3803            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3804        } catch (IOException e) {
3805            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3806            return null;
3807        }
3808
3809        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
3810        return tracesFile;
3811    }
3812
3813    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3814            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3815        // Use a FileObserver to detect when traces finish writing.
3816        // The order of traces is considered important to maintain for legibility.
3817        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3818            @Override
3819            public synchronized void onEvent(int event, String path) { notify(); }
3820        };
3821
3822        try {
3823            observer.startWatching();
3824
3825            // First collect all of the stacks of the most important pids.
3826            if (firstPids != null) {
3827                try {
3828                    int num = firstPids.size();
3829                    for (int i = 0; i < num; i++) {
3830                        synchronized (observer) {
3831                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3832                            observer.wait(200);  // Wait for write-close, give up after 200msec
3833                        }
3834                    }
3835                } catch (InterruptedException e) {
3836                    Log.wtf(TAG, e);
3837                }
3838            }
3839
3840            // Next collect the stacks of the native pids
3841            if (nativeProcs != null) {
3842                int[] pids = Process.getPidsForCommands(nativeProcs);
3843                if (pids != null) {
3844                    for (int pid : pids) {
3845                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3846                    }
3847                }
3848            }
3849
3850            // Lastly, measure CPU usage.
3851            if (processCpuTracker != null) {
3852                processCpuTracker.init();
3853                System.gc();
3854                processCpuTracker.update();
3855                try {
3856                    synchronized (processCpuTracker) {
3857                        processCpuTracker.wait(500); // measure over 1/2 second.
3858                    }
3859                } catch (InterruptedException e) {
3860                }
3861                processCpuTracker.update();
3862
3863                // We'll take the stack crawls of just the top apps using CPU.
3864                final int N = processCpuTracker.countWorkingStats();
3865                int numProcs = 0;
3866                for (int i=0; i<N && numProcs<5; i++) {
3867                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
3868                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3869                        numProcs++;
3870                        try {
3871                            synchronized (observer) {
3872                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3873                                observer.wait(200);  // Wait for write-close, give up after 200msec
3874                            }
3875                        } catch (InterruptedException e) {
3876                            Log.wtf(TAG, e);
3877                        }
3878
3879                    }
3880                }
3881            }
3882        } finally {
3883            observer.stopWatching();
3884        }
3885    }
3886
3887    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3888        if (true || IS_USER_BUILD) {
3889            return;
3890        }
3891        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3892        if (tracesPath == null || tracesPath.length() == 0) {
3893            return;
3894        }
3895
3896        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3897        StrictMode.allowThreadDiskWrites();
3898        try {
3899            final File tracesFile = new File(tracesPath);
3900            final File tracesDir = tracesFile.getParentFile();
3901            final File tracesTmp = new File(tracesDir, "__tmp__");
3902            try {
3903                if (!tracesDir.exists()) {
3904                    tracesFile.mkdirs();
3905                    if (!SELinux.restorecon(tracesDir.getPath())) {
3906                        return;
3907                    }
3908                }
3909                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3910
3911                if (tracesFile.exists()) {
3912                    tracesTmp.delete();
3913                    tracesFile.renameTo(tracesTmp);
3914                }
3915                StringBuilder sb = new StringBuilder();
3916                Time tobj = new Time();
3917                tobj.set(System.currentTimeMillis());
3918                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3919                sb.append(": ");
3920                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3921                sb.append(" since ");
3922                sb.append(msg);
3923                FileOutputStream fos = new FileOutputStream(tracesFile);
3924                fos.write(sb.toString().getBytes());
3925                if (app == null) {
3926                    fos.write("\n*** No application process!".getBytes());
3927                }
3928                fos.close();
3929                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3930            } catch (IOException e) {
3931                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3932                return;
3933            }
3934
3935            if (app != null) {
3936                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3937                firstPids.add(app.pid);
3938                dumpStackTraces(tracesPath, firstPids, null, null, null);
3939            }
3940
3941            File lastTracesFile = null;
3942            File curTracesFile = null;
3943            for (int i=9; i>=0; i--) {
3944                String name = String.format(Locale.US, "slow%02d.txt", i);
3945                curTracesFile = new File(tracesDir, name);
3946                if (curTracesFile.exists()) {
3947                    if (lastTracesFile != null) {
3948                        curTracesFile.renameTo(lastTracesFile);
3949                    } else {
3950                        curTracesFile.delete();
3951                    }
3952                }
3953                lastTracesFile = curTracesFile;
3954            }
3955            tracesFile.renameTo(curTracesFile);
3956            if (tracesTmp.exists()) {
3957                tracesTmp.renameTo(tracesFile);
3958            }
3959        } finally {
3960            StrictMode.setThreadPolicy(oldPolicy);
3961        }
3962    }
3963
3964    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3965            ActivityRecord parent, boolean aboveSystem, final String annotation) {
3966        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3967        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3968
3969        if (mController != null) {
3970            try {
3971                // 0 == continue, -1 = kill process immediately
3972                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3973                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3974            } catch (RemoteException e) {
3975                mController = null;
3976                Watchdog.getInstance().setActivityController(null);
3977            }
3978        }
3979
3980        long anrTime = SystemClock.uptimeMillis();
3981        if (MONITOR_CPU_USAGE) {
3982            updateCpuStatsNow();
3983        }
3984
3985        synchronized (this) {
3986            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3987            if (mShuttingDown) {
3988                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3989                return;
3990            } else if (app.notResponding) {
3991                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3992                return;
3993            } else if (app.crashing) {
3994                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3995                return;
3996            }
3997
3998            // In case we come through here for the same app before completing
3999            // this one, mark as anring now so we will bail out.
4000            app.notResponding = true;
4001
4002            // Log the ANR to the event log.
4003            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4004                    app.processName, app.info.flags, annotation);
4005
4006            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4007            firstPids.add(app.pid);
4008
4009            int parentPid = app.pid;
4010            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4011            if (parentPid != app.pid) firstPids.add(parentPid);
4012
4013            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4014
4015            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4016                ProcessRecord r = mLruProcesses.get(i);
4017                if (r != null && r.thread != null) {
4018                    int pid = r.pid;
4019                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4020                        if (r.persistent) {
4021                            firstPids.add(pid);
4022                        } else {
4023                            lastPids.put(pid, Boolean.TRUE);
4024                        }
4025                    }
4026                }
4027            }
4028        }
4029
4030        // Log the ANR to the main log.
4031        StringBuilder info = new StringBuilder();
4032        info.setLength(0);
4033        info.append("ANR in ").append(app.processName);
4034        if (activity != null && activity.shortComponentName != null) {
4035            info.append(" (").append(activity.shortComponentName).append(")");
4036        }
4037        info.append("\n");
4038        info.append("PID: ").append(app.pid).append("\n");
4039        if (annotation != null) {
4040            info.append("Reason: ").append(annotation).append("\n");
4041        }
4042        if (parent != null && parent != activity) {
4043            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4044        }
4045
4046        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4047
4048        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4049                NATIVE_STACKS_OF_INTEREST);
4050
4051        String cpuInfo = null;
4052        if (MONITOR_CPU_USAGE) {
4053            updateCpuStatsNow();
4054            synchronized (mProcessCpuThread) {
4055                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4056            }
4057            info.append(processCpuTracker.printCurrentLoad());
4058            info.append(cpuInfo);
4059        }
4060
4061        info.append(processCpuTracker.printCurrentState(anrTime));
4062
4063        Slog.e(TAG, info.toString());
4064        if (tracesFile == null) {
4065            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4066            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4067        }
4068
4069        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4070                cpuInfo, tracesFile, null);
4071
4072        if (mController != null) {
4073            try {
4074                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4075                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4076                if (res != 0) {
4077                    if (res < 0 && app.pid != MY_PID) {
4078                        Process.killProcess(app.pid);
4079                    } else {
4080                        synchronized (this) {
4081                            mServices.scheduleServiceTimeoutLocked(app);
4082                        }
4083                    }
4084                    return;
4085                }
4086            } catch (RemoteException e) {
4087                mController = null;
4088                Watchdog.getInstance().setActivityController(null);
4089            }
4090        }
4091
4092        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4093        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4094                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4095
4096        synchronized (this) {
4097            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4098                killUnneededProcessLocked(app, "background ANR");
4099                return;
4100            }
4101
4102            // Set the app's notResponding state, and look up the errorReportReceiver
4103            makeAppNotRespondingLocked(app,
4104                    activity != null ? activity.shortComponentName : null,
4105                    annotation != null ? "ANR " + annotation : "ANR",
4106                    info.toString());
4107
4108            // Bring up the infamous App Not Responding dialog
4109            Message msg = Message.obtain();
4110            HashMap<String, Object> map = new HashMap<String, Object>();
4111            msg.what = SHOW_NOT_RESPONDING_MSG;
4112            msg.obj = map;
4113            msg.arg1 = aboveSystem ? 1 : 0;
4114            map.put("app", app);
4115            if (activity != null) {
4116                map.put("activity", activity);
4117            }
4118
4119            mHandler.sendMessage(msg);
4120        }
4121    }
4122
4123    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4124        if (!mLaunchWarningShown) {
4125            mLaunchWarningShown = true;
4126            mHandler.post(new Runnable() {
4127                @Override
4128                public void run() {
4129                    synchronized (ActivityManagerService.this) {
4130                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4131                        d.show();
4132                        mHandler.postDelayed(new Runnable() {
4133                            @Override
4134                            public void run() {
4135                                synchronized (ActivityManagerService.this) {
4136                                    d.dismiss();
4137                                    mLaunchWarningShown = false;
4138                                }
4139                            }
4140                        }, 4000);
4141                    }
4142                }
4143            });
4144        }
4145    }
4146
4147    @Override
4148    public boolean clearApplicationUserData(final String packageName,
4149            final IPackageDataObserver observer, int userId) {
4150        enforceNotIsolatedCaller("clearApplicationUserData");
4151        int uid = Binder.getCallingUid();
4152        int pid = Binder.getCallingPid();
4153        userId = handleIncomingUser(pid, uid,
4154                userId, false, true, "clearApplicationUserData", null);
4155        long callingId = Binder.clearCallingIdentity();
4156        try {
4157            IPackageManager pm = AppGlobals.getPackageManager();
4158            int pkgUid = -1;
4159            synchronized(this) {
4160                try {
4161                    pkgUid = pm.getPackageUid(packageName, userId);
4162                } catch (RemoteException e) {
4163                }
4164                if (pkgUid == -1) {
4165                    Slog.w(TAG, "Invalid packageName: " + packageName);
4166                    if (observer != null) {
4167                        try {
4168                            observer.onRemoveCompleted(packageName, false);
4169                        } catch (RemoteException e) {
4170                            Slog.i(TAG, "Observer no longer exists.");
4171                        }
4172                    }
4173                    return false;
4174                }
4175                if (uid == pkgUid || checkComponentPermission(
4176                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4177                        pid, uid, -1, true)
4178                        == PackageManager.PERMISSION_GRANTED) {
4179                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4180                } else {
4181                    throw new SecurityException("PID " + pid + " does not have permission "
4182                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4183                                    + " of package " + packageName);
4184                }
4185            }
4186
4187            try {
4188                // Clear application user data
4189                pm.clearApplicationUserData(packageName, observer, userId);
4190
4191                // Remove all permissions granted from/to this package
4192                removeUriPermissionsForPackageLocked(packageName, userId, true);
4193
4194                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4195                        Uri.fromParts("package", packageName, null));
4196                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4197                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4198                        null, null, 0, null, null, null, false, false, userId);
4199            } catch (RemoteException e) {
4200            }
4201        } finally {
4202            Binder.restoreCallingIdentity(callingId);
4203        }
4204        return true;
4205    }
4206
4207    @Override
4208    public void killBackgroundProcesses(final String packageName, int userId) {
4209        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4210                != PackageManager.PERMISSION_GRANTED &&
4211                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4212                        != PackageManager.PERMISSION_GRANTED) {
4213            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4214                    + Binder.getCallingPid()
4215                    + ", uid=" + Binder.getCallingUid()
4216                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4217            Slog.w(TAG, msg);
4218            throw new SecurityException(msg);
4219        }
4220
4221        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4222                userId, true, true, "killBackgroundProcesses", null);
4223        long callingId = Binder.clearCallingIdentity();
4224        try {
4225            IPackageManager pm = AppGlobals.getPackageManager();
4226            synchronized(this) {
4227                int appId = -1;
4228                try {
4229                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4230                } catch (RemoteException e) {
4231                }
4232                if (appId == -1) {
4233                    Slog.w(TAG, "Invalid packageName: " + packageName);
4234                    return;
4235                }
4236                killPackageProcessesLocked(packageName, appId, userId,
4237                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4238            }
4239        } finally {
4240            Binder.restoreCallingIdentity(callingId);
4241        }
4242    }
4243
4244    @Override
4245    public void killAllBackgroundProcesses() {
4246        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4247                != PackageManager.PERMISSION_GRANTED) {
4248            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4249                    + Binder.getCallingPid()
4250                    + ", uid=" + Binder.getCallingUid()
4251                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4252            Slog.w(TAG, msg);
4253            throw new SecurityException(msg);
4254        }
4255
4256        long callingId = Binder.clearCallingIdentity();
4257        try {
4258            synchronized(this) {
4259                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4260                final int NP = mProcessNames.getMap().size();
4261                for (int ip=0; ip<NP; ip++) {
4262                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4263                    final int NA = apps.size();
4264                    for (int ia=0; ia<NA; ia++) {
4265                        ProcessRecord app = apps.valueAt(ia);
4266                        if (app.persistent) {
4267                            // we don't kill persistent processes
4268                            continue;
4269                        }
4270                        if (app.removed) {
4271                            procs.add(app);
4272                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4273                            app.removed = true;
4274                            procs.add(app);
4275                        }
4276                    }
4277                }
4278
4279                int N = procs.size();
4280                for (int i=0; i<N; i++) {
4281                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4282                }
4283                mAllowLowerMemLevel = true;
4284                updateOomAdjLocked();
4285                doLowMemReportIfNeededLocked(null);
4286            }
4287        } finally {
4288            Binder.restoreCallingIdentity(callingId);
4289        }
4290    }
4291
4292    @Override
4293    public void forceStopPackage(final String packageName, int userId) {
4294        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4295                != PackageManager.PERMISSION_GRANTED) {
4296            String msg = "Permission Denial: forceStopPackage() from pid="
4297                    + Binder.getCallingPid()
4298                    + ", uid=" + Binder.getCallingUid()
4299                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4300            Slog.w(TAG, msg);
4301            throw new SecurityException(msg);
4302        }
4303        final int callingPid = Binder.getCallingPid();
4304        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4305                userId, true, true, "forceStopPackage", null);
4306        long callingId = Binder.clearCallingIdentity();
4307        try {
4308            IPackageManager pm = AppGlobals.getPackageManager();
4309            synchronized(this) {
4310                int[] users = userId == UserHandle.USER_ALL
4311                        ? getUsersLocked() : new int[] { userId };
4312                for (int user : users) {
4313                    int pkgUid = -1;
4314                    try {
4315                        pkgUid = pm.getPackageUid(packageName, user);
4316                    } catch (RemoteException e) {
4317                    }
4318                    if (pkgUid == -1) {
4319                        Slog.w(TAG, "Invalid packageName: " + packageName);
4320                        continue;
4321                    }
4322                    try {
4323                        pm.setPackageStoppedState(packageName, true, user);
4324                    } catch (RemoteException e) {
4325                    } catch (IllegalArgumentException e) {
4326                        Slog.w(TAG, "Failed trying to unstop package "
4327                                + packageName + ": " + e);
4328                    }
4329                    if (isUserRunningLocked(user, false)) {
4330                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4331                    }
4332                }
4333            }
4334        } finally {
4335            Binder.restoreCallingIdentity(callingId);
4336        }
4337    }
4338
4339    /*
4340     * The pkg name and app id have to be specified.
4341     */
4342    @Override
4343    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4344        if (pkg == null) {
4345            return;
4346        }
4347        // Make sure the uid is valid.
4348        if (appid < 0) {
4349            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4350            return;
4351        }
4352        int callerUid = Binder.getCallingUid();
4353        // Only the system server can kill an application
4354        if (callerUid == Process.SYSTEM_UID) {
4355            // Post an aysnc message to kill the application
4356            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4357            msg.arg1 = appid;
4358            msg.arg2 = 0;
4359            Bundle bundle = new Bundle();
4360            bundle.putString("pkg", pkg);
4361            bundle.putString("reason", reason);
4362            msg.obj = bundle;
4363            mHandler.sendMessage(msg);
4364        } else {
4365            throw new SecurityException(callerUid + " cannot kill pkg: " +
4366                    pkg);
4367        }
4368    }
4369
4370    @Override
4371    public void closeSystemDialogs(String reason) {
4372        enforceNotIsolatedCaller("closeSystemDialogs");
4373
4374        final int pid = Binder.getCallingPid();
4375        final int uid = Binder.getCallingUid();
4376        final long origId = Binder.clearCallingIdentity();
4377        try {
4378            synchronized (this) {
4379                // Only allow this from foreground processes, so that background
4380                // applications can't abuse it to prevent system UI from being shown.
4381                if (uid >= Process.FIRST_APPLICATION_UID) {
4382                    ProcessRecord proc;
4383                    synchronized (mPidsSelfLocked) {
4384                        proc = mPidsSelfLocked.get(pid);
4385                    }
4386                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4387                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4388                                + " from background process " + proc);
4389                        return;
4390                    }
4391                }
4392                closeSystemDialogsLocked(reason);
4393            }
4394        } finally {
4395            Binder.restoreCallingIdentity(origId);
4396        }
4397    }
4398
4399    void closeSystemDialogsLocked(String reason) {
4400        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4401        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4402                | Intent.FLAG_RECEIVER_FOREGROUND);
4403        if (reason != null) {
4404            intent.putExtra("reason", reason);
4405        }
4406        mWindowManager.closeSystemDialogs(reason);
4407
4408        mStackSupervisor.closeSystemDialogsLocked();
4409
4410        broadcastIntentLocked(null, null, intent, null,
4411                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4412                Process.SYSTEM_UID, UserHandle.USER_ALL);
4413    }
4414
4415    @Override
4416    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4417        enforceNotIsolatedCaller("getProcessMemoryInfo");
4418        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4419        for (int i=pids.length-1; i>=0; i--) {
4420            ProcessRecord proc;
4421            int oomAdj;
4422            synchronized (this) {
4423                synchronized (mPidsSelfLocked) {
4424                    proc = mPidsSelfLocked.get(pids[i]);
4425                    oomAdj = proc != null ? proc.setAdj : 0;
4426                }
4427            }
4428            infos[i] = new Debug.MemoryInfo();
4429            Debug.getMemoryInfo(pids[i], infos[i]);
4430            if (proc != null) {
4431                synchronized (this) {
4432                    if (proc.thread != null && proc.setAdj == oomAdj) {
4433                        // Record this for posterity if the process has been stable.
4434                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4435                                infos[i].getTotalUss(), false, proc.pkgList);
4436                    }
4437                }
4438            }
4439        }
4440        return infos;
4441    }
4442
4443    @Override
4444    public long[] getProcessPss(int[] pids) {
4445        enforceNotIsolatedCaller("getProcessPss");
4446        long[] pss = new long[pids.length];
4447        for (int i=pids.length-1; i>=0; i--) {
4448            ProcessRecord proc;
4449            int oomAdj;
4450            synchronized (this) {
4451                synchronized (mPidsSelfLocked) {
4452                    proc = mPidsSelfLocked.get(pids[i]);
4453                    oomAdj = proc != null ? proc.setAdj : 0;
4454                }
4455            }
4456            long[] tmpUss = new long[1];
4457            pss[i] = Debug.getPss(pids[i], tmpUss);
4458            if (proc != null) {
4459                synchronized (this) {
4460                    if (proc.thread != null && proc.setAdj == oomAdj) {
4461                        // Record this for posterity if the process has been stable.
4462                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4463                    }
4464                }
4465            }
4466        }
4467        return pss;
4468    }
4469
4470    @Override
4471    public void killApplicationProcess(String processName, int uid) {
4472        if (processName == null) {
4473            return;
4474        }
4475
4476        int callerUid = Binder.getCallingUid();
4477        // Only the system server can kill an application
4478        if (callerUid == Process.SYSTEM_UID) {
4479            synchronized (this) {
4480                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4481                if (app != null && app.thread != null) {
4482                    try {
4483                        app.thread.scheduleSuicide();
4484                    } catch (RemoteException e) {
4485                        // If the other end already died, then our work here is done.
4486                    }
4487                } else {
4488                    Slog.w(TAG, "Process/uid not found attempting kill of "
4489                            + processName + " / " + uid);
4490                }
4491            }
4492        } else {
4493            throw new SecurityException(callerUid + " cannot kill app process: " +
4494                    processName);
4495        }
4496    }
4497
4498    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4499        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4500                false, true, false, false, UserHandle.getUserId(uid), reason);
4501        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4502                Uri.fromParts("package", packageName, null));
4503        if (!mProcessesReady) {
4504            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4505                    | Intent.FLAG_RECEIVER_FOREGROUND);
4506        }
4507        intent.putExtra(Intent.EXTRA_UID, uid);
4508        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4509        broadcastIntentLocked(null, null, intent,
4510                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4511                false, false,
4512                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4513    }
4514
4515    private void forceStopUserLocked(int userId, String reason) {
4516        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4517        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4518        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4519                | Intent.FLAG_RECEIVER_FOREGROUND);
4520        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4521        broadcastIntentLocked(null, null, intent,
4522                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4523                false, false,
4524                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4525    }
4526
4527    private final boolean killPackageProcessesLocked(String packageName, int appId,
4528            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4529            boolean doit, boolean evenPersistent, String reason) {
4530        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4531
4532        // Remove all processes this package may have touched: all with the
4533        // same UID (except for the system or root user), and all whose name
4534        // matches the package name.
4535        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4536        final int NP = mProcessNames.getMap().size();
4537        for (int ip=0; ip<NP; ip++) {
4538            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4539            final int NA = apps.size();
4540            for (int ia=0; ia<NA; ia++) {
4541                ProcessRecord app = apps.valueAt(ia);
4542                if (app.persistent && !evenPersistent) {
4543                    // we don't kill persistent processes
4544                    continue;
4545                }
4546                if (app.removed) {
4547                    if (doit) {
4548                        procs.add(app);
4549                    }
4550                    continue;
4551                }
4552
4553                // Skip process if it doesn't meet our oom adj requirement.
4554                if (app.setAdj < minOomAdj) {
4555                    continue;
4556                }
4557
4558                // If no package is specified, we call all processes under the
4559                // give user id.
4560                if (packageName == null) {
4561                    if (app.userId != userId) {
4562                        continue;
4563                    }
4564                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4565                        continue;
4566                    }
4567                // Package has been specified, we want to hit all processes
4568                // that match it.  We need to qualify this by the processes
4569                // that are running under the specified app and user ID.
4570                } else {
4571                    if (UserHandle.getAppId(app.uid) != appId) {
4572                        continue;
4573                    }
4574                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4575                        continue;
4576                    }
4577                    if (!app.pkgList.containsKey(packageName)) {
4578                        continue;
4579                    }
4580                }
4581
4582                // Process has passed all conditions, kill it!
4583                if (!doit) {
4584                    return true;
4585                }
4586                app.removed = true;
4587                procs.add(app);
4588            }
4589        }
4590
4591        int N = procs.size();
4592        for (int i=0; i<N; i++) {
4593            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4594        }
4595        updateOomAdjLocked();
4596        return N > 0;
4597    }
4598
4599    private final boolean forceStopPackageLocked(String name, int appId,
4600            boolean callerWillRestart, boolean purgeCache, boolean doit,
4601            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4602        int i;
4603        int N;
4604
4605        if (userId == UserHandle.USER_ALL && name == null) {
4606            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4607        }
4608
4609        if (appId < 0 && name != null) {
4610            try {
4611                appId = UserHandle.getAppId(
4612                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4613            } catch (RemoteException e) {
4614            }
4615        }
4616
4617        if (doit) {
4618            if (name != null) {
4619                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4620                        + " user=" + userId + ": " + reason);
4621            } else {
4622                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4623            }
4624
4625            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4626            for (int ip=pmap.size()-1; ip>=0; ip--) {
4627                SparseArray<Long> ba = pmap.valueAt(ip);
4628                for (i=ba.size()-1; i>=0; i--) {
4629                    boolean remove = false;
4630                    final int entUid = ba.keyAt(i);
4631                    if (name != null) {
4632                        if (userId == UserHandle.USER_ALL) {
4633                            if (UserHandle.getAppId(entUid) == appId) {
4634                                remove = true;
4635                            }
4636                        } else {
4637                            if (entUid == UserHandle.getUid(userId, appId)) {
4638                                remove = true;
4639                            }
4640                        }
4641                    } else if (UserHandle.getUserId(entUid) == userId) {
4642                        remove = true;
4643                    }
4644                    if (remove) {
4645                        ba.removeAt(i);
4646                    }
4647                }
4648                if (ba.size() == 0) {
4649                    pmap.removeAt(ip);
4650                }
4651            }
4652        }
4653
4654        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4655                -100, callerWillRestart, true, doit, evenPersistent,
4656                name == null ? ("stop user " + userId) : ("stop " + name));
4657
4658        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4659            if (!doit) {
4660                return true;
4661            }
4662            didSomething = true;
4663        }
4664
4665        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4666            if (!doit) {
4667                return true;
4668            }
4669            didSomething = true;
4670        }
4671
4672        if (name == null) {
4673            // Remove all sticky broadcasts from this user.
4674            mStickyBroadcasts.remove(userId);
4675        }
4676
4677        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4678        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4679                userId, providers)) {
4680            if (!doit) {
4681                return true;
4682            }
4683            didSomething = true;
4684        }
4685        N = providers.size();
4686        for (i=0; i<N; i++) {
4687            removeDyingProviderLocked(null, providers.get(i), true);
4688        }
4689
4690        // Remove transient permissions granted from/to this package/user
4691        removeUriPermissionsForPackageLocked(name, userId, false);
4692
4693        if (name == null || uninstalling) {
4694            // Remove pending intents.  For now we only do this when force
4695            // stopping users, because we have some problems when doing this
4696            // for packages -- app widgets are not currently cleaned up for
4697            // such packages, so they can be left with bad pending intents.
4698            if (mIntentSenderRecords.size() > 0) {
4699                Iterator<WeakReference<PendingIntentRecord>> it
4700                        = mIntentSenderRecords.values().iterator();
4701                while (it.hasNext()) {
4702                    WeakReference<PendingIntentRecord> wpir = it.next();
4703                    if (wpir == null) {
4704                        it.remove();
4705                        continue;
4706                    }
4707                    PendingIntentRecord pir = wpir.get();
4708                    if (pir == null) {
4709                        it.remove();
4710                        continue;
4711                    }
4712                    if (name == null) {
4713                        // Stopping user, remove all objects for the user.
4714                        if (pir.key.userId != userId) {
4715                            // Not the same user, skip it.
4716                            continue;
4717                        }
4718                    } else {
4719                        if (UserHandle.getAppId(pir.uid) != appId) {
4720                            // Different app id, skip it.
4721                            continue;
4722                        }
4723                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4724                            // Different user, skip it.
4725                            continue;
4726                        }
4727                        if (!pir.key.packageName.equals(name)) {
4728                            // Different package, skip it.
4729                            continue;
4730                        }
4731                    }
4732                    if (!doit) {
4733                        return true;
4734                    }
4735                    didSomething = true;
4736                    it.remove();
4737                    pir.canceled = true;
4738                    if (pir.key.activity != null) {
4739                        pir.key.activity.pendingResults.remove(pir.ref);
4740                    }
4741                }
4742            }
4743        }
4744
4745        if (doit) {
4746            if (purgeCache && name != null) {
4747                AttributeCache ac = AttributeCache.instance();
4748                if (ac != null) {
4749                    ac.removePackage(name);
4750                }
4751            }
4752            if (mBooted) {
4753                mStackSupervisor.resumeTopActivitiesLocked();
4754                mStackSupervisor.scheduleIdleLocked();
4755            }
4756        }
4757
4758        return didSomething;
4759    }
4760
4761    private final boolean removeProcessLocked(ProcessRecord app,
4762            boolean callerWillRestart, boolean allowRestart, String reason) {
4763        final String name = app.processName;
4764        final int uid = app.uid;
4765        if (DEBUG_PROCESSES) Slog.d(
4766            TAG, "Force removing proc " + app.toShortString() + " (" + name
4767            + "/" + uid + ")");
4768
4769        mProcessNames.remove(name, uid);
4770        mIsolatedProcesses.remove(app.uid);
4771        if (mHeavyWeightProcess == app) {
4772            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4773                    mHeavyWeightProcess.userId, 0));
4774            mHeavyWeightProcess = null;
4775        }
4776        boolean needRestart = false;
4777        if (app.pid > 0 && app.pid != MY_PID) {
4778            int pid = app.pid;
4779            synchronized (mPidsSelfLocked) {
4780                mPidsSelfLocked.remove(pid);
4781                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4782            }
4783            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
4784                    app.processName, app.info.uid);
4785            if (app.isolated) {
4786                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
4787            }
4788            killUnneededProcessLocked(app, reason);
4789            handleAppDiedLocked(app, true, allowRestart);
4790            removeLruProcessLocked(app);
4791
4792            if (app.persistent && !app.isolated) {
4793                if (!callerWillRestart) {
4794                    addAppLocked(app.info, false);
4795                } else {
4796                    needRestart = true;
4797                }
4798            }
4799        } else {
4800            mRemovedProcesses.add(app);
4801        }
4802
4803        return needRestart;
4804    }
4805
4806    private final void processStartTimedOutLocked(ProcessRecord app) {
4807        final int pid = app.pid;
4808        boolean gone = false;
4809        synchronized (mPidsSelfLocked) {
4810            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4811            if (knownApp != null && knownApp.thread == null) {
4812                mPidsSelfLocked.remove(pid);
4813                gone = true;
4814            }
4815        }
4816
4817        if (gone) {
4818            Slog.w(TAG, "Process " + app + " failed to attach");
4819            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
4820                    pid, app.uid, app.processName);
4821            mProcessNames.remove(app.processName, app.uid);
4822            mIsolatedProcesses.remove(app.uid);
4823            if (mHeavyWeightProcess == app) {
4824                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4825                        mHeavyWeightProcess.userId, 0));
4826                mHeavyWeightProcess = null;
4827            }
4828            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
4829                    app.processName, app.info.uid);
4830            if (app.isolated) {
4831                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
4832            }
4833            // Take care of any launching providers waiting for this process.
4834            checkAppInLaunchingProvidersLocked(app, true);
4835            // Take care of any services that are waiting for the process.
4836            mServices.processStartTimedOutLocked(app);
4837            killUnneededProcessLocked(app, "start timeout");
4838            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4839                Slog.w(TAG, "Unattached app died before backup, skipping");
4840                try {
4841                    IBackupManager bm = IBackupManager.Stub.asInterface(
4842                            ServiceManager.getService(Context.BACKUP_SERVICE));
4843                    bm.agentDisconnected(app.info.packageName);
4844                } catch (RemoteException e) {
4845                    // Can't happen; the backup manager is local
4846                }
4847            }
4848            if (isPendingBroadcastProcessLocked(pid)) {
4849                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4850                skipPendingBroadcastLocked(pid);
4851            }
4852        } else {
4853            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4854        }
4855    }
4856
4857    private final boolean attachApplicationLocked(IApplicationThread thread,
4858            int pid) {
4859
4860        // Find the application record that is being attached...  either via
4861        // the pid if we are running in multiple processes, or just pull the
4862        // next app record if we are emulating process with anonymous threads.
4863        ProcessRecord app;
4864        if (pid != MY_PID && pid >= 0) {
4865            synchronized (mPidsSelfLocked) {
4866                app = mPidsSelfLocked.get(pid);
4867            }
4868        } else {
4869            app = null;
4870        }
4871
4872        if (app == null) {
4873            Slog.w(TAG, "No pending application record for pid " + pid
4874                    + " (IApplicationThread " + thread + "); dropping process");
4875            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4876            if (pid > 0 && pid != MY_PID) {
4877                Process.killProcessQuiet(pid);
4878            } else {
4879                try {
4880                    thread.scheduleExit();
4881                } catch (Exception e) {
4882                    // Ignore exceptions.
4883                }
4884            }
4885            return false;
4886        }
4887
4888        // If this application record is still attached to a previous
4889        // process, clean it up now.
4890        if (app.thread != null) {
4891            handleAppDiedLocked(app, true, true);
4892        }
4893
4894        // Tell the process all about itself.
4895
4896        if (localLOGV) Slog.v(
4897                TAG, "Binding process pid " + pid + " to record " + app);
4898
4899        final String processName = app.processName;
4900        try {
4901            AppDeathRecipient adr = new AppDeathRecipient(
4902                    app, pid, thread);
4903            thread.asBinder().linkToDeath(adr, 0);
4904            app.deathRecipient = adr;
4905        } catch (RemoteException e) {
4906            app.resetPackageList(mProcessStats);
4907            startProcessLocked(app, "link fail", processName);
4908            return false;
4909        }
4910
4911        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
4912
4913        app.makeActive(thread, mProcessStats);
4914        app.curAdj = app.setAdj = -100;
4915        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
4916        app.forcingToForeground = null;
4917        updateProcessForegroundLocked(app, false, false);
4918        app.hasShownUi = false;
4919        app.debugging = false;
4920        app.cached = false;
4921
4922        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4923
4924        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4925        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4926
4927        if (!normalMode) {
4928            Slog.i(TAG, "Launching preboot mode app: " + app);
4929        }
4930
4931        if (localLOGV) Slog.v(
4932            TAG, "New app record " + app
4933            + " thread=" + thread.asBinder() + " pid=" + pid);
4934        try {
4935            int testMode = IApplicationThread.DEBUG_OFF;
4936            if (mDebugApp != null && mDebugApp.equals(processName)) {
4937                testMode = mWaitForDebugger
4938                    ? IApplicationThread.DEBUG_WAIT
4939                    : IApplicationThread.DEBUG_ON;
4940                app.debugging = true;
4941                if (mDebugTransient) {
4942                    mDebugApp = mOrigDebugApp;
4943                    mWaitForDebugger = mOrigWaitForDebugger;
4944                }
4945            }
4946            String profileFile = app.instrumentationProfileFile;
4947            ParcelFileDescriptor profileFd = null;
4948            boolean profileAutoStop = false;
4949            if (mProfileApp != null && mProfileApp.equals(processName)) {
4950                mProfileProc = app;
4951                profileFile = mProfileFile;
4952                profileFd = mProfileFd;
4953                profileAutoStop = mAutoStopProfiler;
4954            }
4955            boolean enableOpenGlTrace = false;
4956            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4957                enableOpenGlTrace = true;
4958                mOpenGlTraceApp = null;
4959            }
4960
4961            // If the app is being launched for restore or full backup, set it up specially
4962            boolean isRestrictedBackupMode = false;
4963            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4964                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4965                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4966                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4967            }
4968
4969            ensurePackageDexOpt(app.instrumentationInfo != null
4970                    ? app.instrumentationInfo.packageName
4971                    : app.info.packageName);
4972            if (app.instrumentationClass != null) {
4973                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4974            }
4975            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4976                    + processName + " with config " + mConfiguration);
4977            ApplicationInfo appInfo = app.instrumentationInfo != null
4978                    ? app.instrumentationInfo : app.info;
4979            app.compat = compatibilityInfoForPackageLocked(appInfo);
4980            if (profileFd != null) {
4981                profileFd = profileFd.dup();
4982            }
4983            thread.bindApplication(processName, appInfo, providers,
4984                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4985                    app.instrumentationArguments, app.instrumentationWatcher,
4986                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
4987                    isRestrictedBackupMode || !normalMode, app.persistent,
4988                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4989                    mCoreSettingsObserver.getCoreSettingsLocked());
4990            updateLruProcessLocked(app, false, null);
4991            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4992        } catch (Exception e) {
4993            // todo: Yikes!  What should we do?  For now we will try to
4994            // start another process, but that could easily get us in
4995            // an infinite loop of restarting processes...
4996            Slog.w(TAG, "Exception thrown during bind!", e);
4997
4998            app.resetPackageList(mProcessStats);
4999            app.unlinkDeathRecipient();
5000            startProcessLocked(app, "bind fail", processName);
5001            return false;
5002        }
5003
5004        // Remove this record from the list of starting applications.
5005        mPersistentStartingProcesses.remove(app);
5006        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5007                "Attach application locked removing on hold: " + app);
5008        mProcessesOnHold.remove(app);
5009
5010        boolean badApp = false;
5011        boolean didSomething = false;
5012
5013        // See if the top visible activity is waiting to run in this process...
5014        if (normalMode) {
5015            try {
5016                if (mStackSupervisor.attachApplicationLocked(app)) {
5017                    didSomething = true;
5018                }
5019            } catch (Exception e) {
5020                badApp = true;
5021            }
5022        }
5023
5024        // Find any services that should be running in this process...
5025        if (!badApp) {
5026            try {
5027                didSomething |= mServices.attachApplicationLocked(app, processName);
5028            } catch (Exception e) {
5029                badApp = true;
5030            }
5031        }
5032
5033        // Check if a next-broadcast receiver is in this process...
5034        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5035            try {
5036                didSomething |= sendPendingBroadcastsLocked(app);
5037            } catch (Exception e) {
5038                // If the app died trying to launch the receiver we declare it 'bad'
5039                badApp = true;
5040            }
5041        }
5042
5043        // Check whether the next backup agent is in this process...
5044        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5045            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5046            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5047            try {
5048                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5049                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5050                        mBackupTarget.backupMode);
5051            } catch (Exception e) {
5052                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5053                e.printStackTrace();
5054            }
5055        }
5056
5057        if (badApp) {
5058            // todo: Also need to kill application to deal with all
5059            // kinds of exceptions.
5060            handleAppDiedLocked(app, false, true);
5061            return false;
5062        }
5063
5064        if (!didSomething) {
5065            updateOomAdjLocked();
5066        }
5067
5068        return true;
5069    }
5070
5071    @Override
5072    public final void attachApplication(IApplicationThread thread) {
5073        synchronized (this) {
5074            int callingPid = Binder.getCallingPid();
5075            final long origId = Binder.clearCallingIdentity();
5076            attachApplicationLocked(thread, callingPid);
5077            Binder.restoreCallingIdentity(origId);
5078        }
5079    }
5080
5081    @Override
5082    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5083        final long origId = Binder.clearCallingIdentity();
5084        synchronized (this) {
5085            ActivityStack stack = ActivityRecord.getStackLocked(token);
5086            if (stack != null) {
5087                ActivityRecord r =
5088                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5089                if (stopProfiling) {
5090                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5091                        try {
5092                            mProfileFd.close();
5093                        } catch (IOException e) {
5094                        }
5095                        clearProfilerLocked();
5096                    }
5097                }
5098            }
5099        }
5100        Binder.restoreCallingIdentity(origId);
5101    }
5102
5103    void enableScreenAfterBoot() {
5104        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5105                SystemClock.uptimeMillis());
5106        mWindowManager.enableScreenAfterBoot();
5107
5108        synchronized (this) {
5109            updateEventDispatchingLocked();
5110        }
5111    }
5112
5113    @Override
5114    public void showBootMessage(final CharSequence msg, final boolean always) {
5115        enforceNotIsolatedCaller("showBootMessage");
5116        mWindowManager.showBootMessage(msg, always);
5117    }
5118
5119    @Override
5120    public void dismissKeyguardOnNextActivity() {
5121        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5122        final long token = Binder.clearCallingIdentity();
5123        try {
5124            synchronized (this) {
5125                if (DEBUG_LOCKSCREEN) logLockScreen("");
5126                if (mLockScreenShown) {
5127                    mLockScreenShown = false;
5128                    comeOutOfSleepIfNeededLocked();
5129                }
5130                mStackSupervisor.setDismissKeyguard(true);
5131            }
5132        } finally {
5133            Binder.restoreCallingIdentity(token);
5134        }
5135    }
5136
5137    final void finishBooting() {
5138        IntentFilter pkgFilter = new IntentFilter();
5139        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
5140        pkgFilter.addDataScheme("package");
5141        mContext.registerReceiver(new BroadcastReceiver() {
5142            @Override
5143            public void onReceive(Context context, Intent intent) {
5144                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
5145                if (pkgs != null) {
5146                    for (String pkg : pkgs) {
5147                        synchronized (ActivityManagerService.this) {
5148                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
5149                                    "finished booting")) {
5150                                setResultCode(Activity.RESULT_OK);
5151                                return;
5152                            }
5153                        }
5154                    }
5155                }
5156            }
5157        }, pkgFilter);
5158
5159        synchronized (this) {
5160            // Ensure that any processes we had put on hold are now started
5161            // up.
5162            final int NP = mProcessesOnHold.size();
5163            if (NP > 0) {
5164                ArrayList<ProcessRecord> procs =
5165                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5166                for (int ip=0; ip<NP; ip++) {
5167                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5168                            + procs.get(ip));
5169                    startProcessLocked(procs.get(ip), "on-hold", null);
5170                }
5171            }
5172
5173            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5174                // Start looking for apps that are abusing wake locks.
5175                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5176                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5177                // Tell anyone interested that we are done booting!
5178                SystemProperties.set("sys.boot_completed", "1");
5179                SystemProperties.set("dev.bootcomplete", "1");
5180                for (int i=0; i<mStartedUsers.size(); i++) {
5181                    UserStartedState uss = mStartedUsers.valueAt(i);
5182                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5183                        uss.mState = UserStartedState.STATE_RUNNING;
5184                        final int userId = mStartedUsers.keyAt(i);
5185                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5186                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5187                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5188                        broadcastIntentLocked(null, null, intent, null,
5189                                new IIntentReceiver.Stub() {
5190                                    @Override
5191                                    public void performReceive(Intent intent, int resultCode,
5192                                            String data, Bundle extras, boolean ordered,
5193                                            boolean sticky, int sendingUser) {
5194                                        synchronized (ActivityManagerService.this) {
5195                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5196                                                    true, false);
5197                                        }
5198                                    }
5199                                },
5200                                0, null, null,
5201                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5202                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5203                                userId);
5204                    }
5205                }
5206                scheduleStartRelatedUsersLocked();
5207            }
5208        }
5209    }
5210
5211    final void ensureBootCompleted() {
5212        boolean booting;
5213        boolean enableScreen;
5214        synchronized (this) {
5215            booting = mBooting;
5216            mBooting = false;
5217            enableScreen = !mBooted;
5218            mBooted = true;
5219        }
5220
5221        if (booting) {
5222            finishBooting();
5223        }
5224
5225        if (enableScreen) {
5226            enableScreenAfterBoot();
5227        }
5228    }
5229
5230    @Override
5231    public final void activityResumed(IBinder token) {
5232        final long origId = Binder.clearCallingIdentity();
5233        synchronized(this) {
5234            ActivityStack stack = ActivityRecord.getStackLocked(token);
5235            if (stack != null) {
5236                ActivityRecord.activityResumedLocked(token);
5237            }
5238        }
5239        Binder.restoreCallingIdentity(origId);
5240    }
5241
5242    @Override
5243    public final void activityPaused(IBinder token) {
5244        final long origId = Binder.clearCallingIdentity();
5245        synchronized(this) {
5246            ActivityStack stack = ActivityRecord.getStackLocked(token);
5247            if (stack != null) {
5248                stack.activityPausedLocked(token, false);
5249            }
5250        }
5251        Binder.restoreCallingIdentity(origId);
5252    }
5253
5254    @Override
5255    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
5256            CharSequence description) {
5257        if (localLOGV) Slog.v(
5258            TAG, "Activity stopped: token=" + token);
5259
5260        // Refuse possible leaked file descriptors
5261        if (icicle != null && icicle.hasFileDescriptors()) {
5262            throw new IllegalArgumentException("File descriptors passed in Bundle");
5263        }
5264
5265        ActivityRecord r = null;
5266
5267        final long origId = Binder.clearCallingIdentity();
5268
5269        synchronized (this) {
5270            r = ActivityRecord.isInStackLocked(token);
5271            if (r != null) {
5272                r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description);
5273            }
5274        }
5275
5276        if (r != null) {
5277            sendPendingThumbnail(r, null, null, null, false);
5278        }
5279
5280        trimApplications();
5281
5282        Binder.restoreCallingIdentity(origId);
5283    }
5284
5285    @Override
5286    public final void activityDestroyed(IBinder token) {
5287        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5288        synchronized (this) {
5289            ActivityStack stack = ActivityRecord.getStackLocked(token);
5290            if (stack != null) {
5291                stack.activityDestroyedLocked(token);
5292            }
5293        }
5294    }
5295
5296    @Override
5297    public String getCallingPackage(IBinder token) {
5298        synchronized (this) {
5299            ActivityRecord r = getCallingRecordLocked(token);
5300            return r != null ? r.info.packageName : null;
5301        }
5302    }
5303
5304    @Override
5305    public ComponentName getCallingActivity(IBinder token) {
5306        synchronized (this) {
5307            ActivityRecord r = getCallingRecordLocked(token);
5308            return r != null ? r.intent.getComponent() : null;
5309        }
5310    }
5311
5312    private ActivityRecord getCallingRecordLocked(IBinder token) {
5313        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5314        if (r == null) {
5315            return null;
5316        }
5317        return r.resultTo;
5318    }
5319
5320    @Override
5321    public ComponentName getActivityClassForToken(IBinder token) {
5322        synchronized(this) {
5323            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5324            if (r == null) {
5325                return null;
5326            }
5327            return r.intent.getComponent();
5328        }
5329    }
5330
5331    @Override
5332    public String getPackageForToken(IBinder token) {
5333        synchronized(this) {
5334            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5335            if (r == null) {
5336                return null;
5337            }
5338            return r.packageName;
5339        }
5340    }
5341
5342    @Override
5343    public IIntentSender getIntentSender(int type,
5344            String packageName, IBinder token, String resultWho,
5345            int requestCode, Intent[] intents, String[] resolvedTypes,
5346            int flags, Bundle options, int userId) {
5347        enforceNotIsolatedCaller("getIntentSender");
5348        // Refuse possible leaked file descriptors
5349        if (intents != null) {
5350            if (intents.length < 1) {
5351                throw new IllegalArgumentException("Intents array length must be >= 1");
5352            }
5353            for (int i=0; i<intents.length; i++) {
5354                Intent intent = intents[i];
5355                if (intent != null) {
5356                    if (intent.hasFileDescriptors()) {
5357                        throw new IllegalArgumentException("File descriptors passed in Intent");
5358                    }
5359                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5360                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5361                        throw new IllegalArgumentException(
5362                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5363                    }
5364                    intents[i] = new Intent(intent);
5365                }
5366            }
5367            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5368                throw new IllegalArgumentException(
5369                        "Intent array length does not match resolvedTypes length");
5370            }
5371        }
5372        if (options != null) {
5373            if (options.hasFileDescriptors()) {
5374                throw new IllegalArgumentException("File descriptors passed in options");
5375            }
5376        }
5377
5378        synchronized(this) {
5379            int callingUid = Binder.getCallingUid();
5380            int origUserId = userId;
5381            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5382                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5383                    "getIntentSender", null);
5384            if (origUserId == UserHandle.USER_CURRENT) {
5385                // We don't want to evaluate this until the pending intent is
5386                // actually executed.  However, we do want to always do the
5387                // security checking for it above.
5388                userId = UserHandle.USER_CURRENT;
5389            }
5390            try {
5391                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5392                    int uid = AppGlobals.getPackageManager()
5393                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5394                    if (!UserHandle.isSameApp(callingUid, uid)) {
5395                        String msg = "Permission Denial: getIntentSender() from pid="
5396                            + Binder.getCallingPid()
5397                            + ", uid=" + Binder.getCallingUid()
5398                            + ", (need uid=" + uid + ")"
5399                            + " is not allowed to send as package " + packageName;
5400                        Slog.w(TAG, msg);
5401                        throw new SecurityException(msg);
5402                    }
5403                }
5404
5405                return getIntentSenderLocked(type, packageName, callingUid, userId,
5406                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5407
5408            } catch (RemoteException e) {
5409                throw new SecurityException(e);
5410            }
5411        }
5412    }
5413
5414    IIntentSender getIntentSenderLocked(int type, String packageName,
5415            int callingUid, int userId, IBinder token, String resultWho,
5416            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5417            Bundle options) {
5418        if (DEBUG_MU)
5419            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5420        ActivityRecord activity = null;
5421        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5422            activity = ActivityRecord.isInStackLocked(token);
5423            if (activity == null) {
5424                return null;
5425            }
5426            if (activity.finishing) {
5427                return null;
5428            }
5429        }
5430
5431        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5432        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5433        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5434        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5435                |PendingIntent.FLAG_UPDATE_CURRENT);
5436
5437        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5438                type, packageName, activity, resultWho,
5439                requestCode, intents, resolvedTypes, flags, options, userId);
5440        WeakReference<PendingIntentRecord> ref;
5441        ref = mIntentSenderRecords.get(key);
5442        PendingIntentRecord rec = ref != null ? ref.get() : null;
5443        if (rec != null) {
5444            if (!cancelCurrent) {
5445                if (updateCurrent) {
5446                    if (rec.key.requestIntent != null) {
5447                        rec.key.requestIntent.replaceExtras(intents != null ?
5448                                intents[intents.length - 1] : null);
5449                    }
5450                    if (intents != null) {
5451                        intents[intents.length-1] = rec.key.requestIntent;
5452                        rec.key.allIntents = intents;
5453                        rec.key.allResolvedTypes = resolvedTypes;
5454                    } else {
5455                        rec.key.allIntents = null;
5456                        rec.key.allResolvedTypes = null;
5457                    }
5458                }
5459                return rec;
5460            }
5461            rec.canceled = true;
5462            mIntentSenderRecords.remove(key);
5463        }
5464        if (noCreate) {
5465            return rec;
5466        }
5467        rec = new PendingIntentRecord(this, key, callingUid);
5468        mIntentSenderRecords.put(key, rec.ref);
5469        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5470            if (activity.pendingResults == null) {
5471                activity.pendingResults
5472                        = new HashSet<WeakReference<PendingIntentRecord>>();
5473            }
5474            activity.pendingResults.add(rec.ref);
5475        }
5476        return rec;
5477    }
5478
5479    @Override
5480    public void cancelIntentSender(IIntentSender sender) {
5481        if (!(sender instanceof PendingIntentRecord)) {
5482            return;
5483        }
5484        synchronized(this) {
5485            PendingIntentRecord rec = (PendingIntentRecord)sender;
5486            try {
5487                int uid = AppGlobals.getPackageManager()
5488                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5489                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5490                    String msg = "Permission Denial: cancelIntentSender() from pid="
5491                        + Binder.getCallingPid()
5492                        + ", uid=" + Binder.getCallingUid()
5493                        + " is not allowed to cancel packges "
5494                        + rec.key.packageName;
5495                    Slog.w(TAG, msg);
5496                    throw new SecurityException(msg);
5497                }
5498            } catch (RemoteException e) {
5499                throw new SecurityException(e);
5500            }
5501            cancelIntentSenderLocked(rec, true);
5502        }
5503    }
5504
5505    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5506        rec.canceled = true;
5507        mIntentSenderRecords.remove(rec.key);
5508        if (cleanActivity && rec.key.activity != null) {
5509            rec.key.activity.pendingResults.remove(rec.ref);
5510        }
5511    }
5512
5513    @Override
5514    public String getPackageForIntentSender(IIntentSender pendingResult) {
5515        if (!(pendingResult instanceof PendingIntentRecord)) {
5516            return null;
5517        }
5518        try {
5519            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5520            return res.key.packageName;
5521        } catch (ClassCastException e) {
5522        }
5523        return null;
5524    }
5525
5526    @Override
5527    public int getUidForIntentSender(IIntentSender sender) {
5528        if (sender instanceof PendingIntentRecord) {
5529            try {
5530                PendingIntentRecord res = (PendingIntentRecord)sender;
5531                return res.uid;
5532            } catch (ClassCastException e) {
5533            }
5534        }
5535        return -1;
5536    }
5537
5538    @Override
5539    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5540        if (!(pendingResult instanceof PendingIntentRecord)) {
5541            return false;
5542        }
5543        try {
5544            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5545            if (res.key.allIntents == null) {
5546                return false;
5547            }
5548            for (int i=0; i<res.key.allIntents.length; i++) {
5549                Intent intent = res.key.allIntents[i];
5550                if (intent.getPackage() != null && intent.getComponent() != null) {
5551                    return false;
5552                }
5553            }
5554            return true;
5555        } catch (ClassCastException e) {
5556        }
5557        return false;
5558    }
5559
5560    @Override
5561    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5562        if (!(pendingResult instanceof PendingIntentRecord)) {
5563            return false;
5564        }
5565        try {
5566            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5567            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5568                return true;
5569            }
5570            return false;
5571        } catch (ClassCastException e) {
5572        }
5573        return false;
5574    }
5575
5576    @Override
5577    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5578        if (!(pendingResult instanceof PendingIntentRecord)) {
5579            return null;
5580        }
5581        try {
5582            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5583            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5584        } catch (ClassCastException e) {
5585        }
5586        return null;
5587    }
5588
5589    @Override
5590    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5591        if (!(pendingResult instanceof PendingIntentRecord)) {
5592            return null;
5593        }
5594        try {
5595            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5596            Intent intent = res.key.requestIntent;
5597            if (intent != null) {
5598                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5599                        || res.lastTagPrefix.equals(prefix))) {
5600                    return res.lastTag;
5601                }
5602                res.lastTagPrefix = prefix;
5603                StringBuilder sb = new StringBuilder(128);
5604                if (prefix != null) {
5605                    sb.append(prefix);
5606                }
5607                if (intent.getAction() != null) {
5608                    sb.append(intent.getAction());
5609                } else if (intent.getComponent() != null) {
5610                    intent.getComponent().appendShortString(sb);
5611                } else {
5612                    sb.append("?");
5613                }
5614                return res.lastTag = sb.toString();
5615            }
5616        } catch (ClassCastException e) {
5617        }
5618        return null;
5619    }
5620
5621    @Override
5622    public void setProcessLimit(int max) {
5623        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5624                "setProcessLimit()");
5625        synchronized (this) {
5626            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5627            mProcessLimitOverride = max;
5628        }
5629        trimApplications();
5630    }
5631
5632    @Override
5633    public int getProcessLimit() {
5634        synchronized (this) {
5635            return mProcessLimitOverride;
5636        }
5637    }
5638
5639    void foregroundTokenDied(ForegroundToken token) {
5640        synchronized (ActivityManagerService.this) {
5641            synchronized (mPidsSelfLocked) {
5642                ForegroundToken cur
5643                    = mForegroundProcesses.get(token.pid);
5644                if (cur != token) {
5645                    return;
5646                }
5647                mForegroundProcesses.remove(token.pid);
5648                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5649                if (pr == null) {
5650                    return;
5651                }
5652                pr.forcingToForeground = null;
5653                updateProcessForegroundLocked(pr, false, false);
5654            }
5655            updateOomAdjLocked();
5656        }
5657    }
5658
5659    @Override
5660    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5661        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5662                "setProcessForeground()");
5663        synchronized(this) {
5664            boolean changed = false;
5665
5666            synchronized (mPidsSelfLocked) {
5667                ProcessRecord pr = mPidsSelfLocked.get(pid);
5668                if (pr == null && isForeground) {
5669                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5670                    return;
5671                }
5672                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5673                if (oldToken != null) {
5674                    oldToken.token.unlinkToDeath(oldToken, 0);
5675                    mForegroundProcesses.remove(pid);
5676                    if (pr != null) {
5677                        pr.forcingToForeground = null;
5678                    }
5679                    changed = true;
5680                }
5681                if (isForeground && token != null) {
5682                    ForegroundToken newToken = new ForegroundToken() {
5683                        @Override
5684                        public void binderDied() {
5685                            foregroundTokenDied(this);
5686                        }
5687                    };
5688                    newToken.pid = pid;
5689                    newToken.token = token;
5690                    try {
5691                        token.linkToDeath(newToken, 0);
5692                        mForegroundProcesses.put(pid, newToken);
5693                        pr.forcingToForeground = token;
5694                        changed = true;
5695                    } catch (RemoteException e) {
5696                        // If the process died while doing this, we will later
5697                        // do the cleanup with the process death link.
5698                    }
5699                }
5700            }
5701
5702            if (changed) {
5703                updateOomAdjLocked();
5704            }
5705        }
5706    }
5707
5708    // =========================================================
5709    // PERMISSIONS
5710    // =========================================================
5711
5712    static class PermissionController extends IPermissionController.Stub {
5713        ActivityManagerService mActivityManagerService;
5714        PermissionController(ActivityManagerService activityManagerService) {
5715            mActivityManagerService = activityManagerService;
5716        }
5717
5718        @Override
5719        public boolean checkPermission(String permission, int pid, int uid) {
5720            return mActivityManagerService.checkPermission(permission, pid,
5721                    uid) == PackageManager.PERMISSION_GRANTED;
5722        }
5723    }
5724
5725    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5726        @Override
5727        public int checkComponentPermission(String permission, int pid, int uid,
5728                int owningUid, boolean exported) {
5729            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5730                    owningUid, exported);
5731        }
5732
5733        @Override
5734        public Object getAMSLock() {
5735            return ActivityManagerService.this;
5736        }
5737    }
5738
5739    /**
5740     * This can be called with or without the global lock held.
5741     */
5742    int checkComponentPermission(String permission, int pid, int uid,
5743            int owningUid, boolean exported) {
5744        // We might be performing an operation on behalf of an indirect binder
5745        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5746        // client identity accordingly before proceeding.
5747        Identity tlsIdentity = sCallerIdentity.get();
5748        if (tlsIdentity != null) {
5749            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5750                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5751            uid = tlsIdentity.uid;
5752            pid = tlsIdentity.pid;
5753        }
5754
5755        if (pid == MY_PID) {
5756            return PackageManager.PERMISSION_GRANTED;
5757        }
5758
5759        return ActivityManager.checkComponentPermission(permission, uid,
5760                owningUid, exported);
5761    }
5762
5763    /**
5764     * As the only public entry point for permissions checking, this method
5765     * can enforce the semantic that requesting a check on a null global
5766     * permission is automatically denied.  (Internally a null permission
5767     * string is used when calling {@link #checkComponentPermission} in cases
5768     * when only uid-based security is needed.)
5769     *
5770     * This can be called with or without the global lock held.
5771     */
5772    @Override
5773    public int checkPermission(String permission, int pid, int uid) {
5774        if (permission == null) {
5775            return PackageManager.PERMISSION_DENIED;
5776        }
5777        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5778    }
5779
5780    /**
5781     * Binder IPC calls go through the public entry point.
5782     * This can be called with or without the global lock held.
5783     */
5784    int checkCallingPermission(String permission) {
5785        return checkPermission(permission,
5786                Binder.getCallingPid(),
5787                UserHandle.getAppId(Binder.getCallingUid()));
5788    }
5789
5790    /**
5791     * This can be called with or without the global lock held.
5792     */
5793    void enforceCallingPermission(String permission, String func) {
5794        if (checkCallingPermission(permission)
5795                == PackageManager.PERMISSION_GRANTED) {
5796            return;
5797        }
5798
5799        String msg = "Permission Denial: " + func + " from pid="
5800                + Binder.getCallingPid()
5801                + ", uid=" + Binder.getCallingUid()
5802                + " requires " + permission;
5803        Slog.w(TAG, msg);
5804        throw new SecurityException(msg);
5805    }
5806
5807    /**
5808     * Determine if UID is holding permissions required to access {@link Uri} in
5809     * the given {@link ProviderInfo}. Final permission checking is always done
5810     * in {@link ContentProvider}.
5811     */
5812    private final boolean checkHoldingPermissionsLocked(
5813            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
5814        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5815                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
5816
5817        if (pi.applicationInfo.uid == uid) {
5818            return true;
5819        } else if (!pi.exported) {
5820            return false;
5821        }
5822
5823        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
5824        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
5825        try {
5826            // check if target holds top-level <provider> permissions
5827            if (!readMet && pi.readPermission != null
5828                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
5829                readMet = true;
5830            }
5831            if (!writeMet && pi.writePermission != null
5832                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
5833                writeMet = true;
5834            }
5835
5836            // track if unprotected read/write is allowed; any denied
5837            // <path-permission> below removes this ability
5838            boolean allowDefaultRead = pi.readPermission == null;
5839            boolean allowDefaultWrite = pi.writePermission == null;
5840
5841            // check if target holds any <path-permission> that match uri
5842            final PathPermission[] pps = pi.pathPermissions;
5843            if (pps != null) {
5844                final String path = uri.getPath();
5845                int i = pps.length;
5846                while (i > 0 && (!readMet || !writeMet)) {
5847                    i--;
5848                    PathPermission pp = pps[i];
5849                    if (pp.match(path)) {
5850                        if (!readMet) {
5851                            final String pprperm = pp.getReadPermission();
5852                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
5853                                    + pprperm + " for " + pp.getPath()
5854                                    + ": match=" + pp.match(path)
5855                                    + " check=" + pm.checkUidPermission(pprperm, uid));
5856                            if (pprperm != null) {
5857                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
5858                                    readMet = true;
5859                                } else {
5860                                    allowDefaultRead = false;
5861                                }
5862                            }
5863                        }
5864                        if (!writeMet) {
5865                            final String ppwperm = pp.getWritePermission();
5866                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
5867                                    + ppwperm + " for " + pp.getPath()
5868                                    + ": match=" + pp.match(path)
5869                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
5870                            if (ppwperm != null) {
5871                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
5872                                    writeMet = true;
5873                                } else {
5874                                    allowDefaultWrite = false;
5875                                }
5876                            }
5877                        }
5878                    }
5879                }
5880            }
5881
5882            // grant unprotected <provider> read/write, if not blocked by
5883            // <path-permission> above
5884            if (allowDefaultRead) readMet = true;
5885            if (allowDefaultWrite) writeMet = true;
5886
5887        } catch (RemoteException e) {
5888            return false;
5889        }
5890
5891        return readMet && writeMet;
5892    }
5893
5894    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
5895        ProviderInfo pi = null;
5896        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
5897        if (cpr != null) {
5898            pi = cpr.info;
5899        } else {
5900            try {
5901                pi = AppGlobals.getPackageManager().resolveContentProvider(
5902                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
5903            } catch (RemoteException ex) {
5904            }
5905        }
5906        return pi;
5907    }
5908
5909    private UriPermission findUriPermissionLocked(int targetUid, Uri uri) {
5910        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5911        if (targetUris != null) {
5912            return targetUris.get(uri);
5913        } else {
5914            return null;
5915        }
5916    }
5917
5918    private UriPermission findOrCreateUriPermissionLocked(
5919            String sourcePkg, String targetPkg, int targetUid, Uri uri) {
5920        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5921        if (targetUris == null) {
5922            targetUris = Maps.newArrayMap();
5923            mGrantedUriPermissions.put(targetUid, targetUris);
5924        }
5925
5926        UriPermission perm = targetUris.get(uri);
5927        if (perm == null) {
5928            perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri);
5929            targetUris.put(uri, perm);
5930        }
5931
5932        return perm;
5933    }
5934
5935    private final boolean checkUriPermissionLocked(
5936            Uri uri, int uid, int modeFlags, int minStrength) {
5937        // Root gets to do everything.
5938        if (uid == 0) {
5939            return true;
5940        }
5941        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5942        if (perms == null) return false;
5943        UriPermission perm = perms.get(uri);
5944        if (perm == null) return false;
5945        return perm.getStrength(modeFlags) >= minStrength;
5946    }
5947
5948    @Override
5949    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
5950        enforceNotIsolatedCaller("checkUriPermission");
5951
5952        // Another redirected-binder-call permissions check as in
5953        // {@link checkComponentPermission}.
5954        Identity tlsIdentity = sCallerIdentity.get();
5955        if (tlsIdentity != null) {
5956            uid = tlsIdentity.uid;
5957            pid = tlsIdentity.pid;
5958        }
5959
5960        // Our own process gets to do everything.
5961        if (pid == MY_PID) {
5962            return PackageManager.PERMISSION_GRANTED;
5963        }
5964        synchronized(this) {
5965            return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED)
5966                    ? PackageManager.PERMISSION_GRANTED
5967                    : PackageManager.PERMISSION_DENIED;
5968        }
5969    }
5970
5971    /**
5972     * Check if the targetPkg can be granted permission to access uri by
5973     * the callingUid using the given modeFlags.  Throws a security exception
5974     * if callingUid is not allowed to do this.  Returns the uid of the target
5975     * if the URI permission grant should be performed; returns -1 if it is not
5976     * needed (for example targetPkg already has permission to access the URI).
5977     * If you already know the uid of the target, you can supply it in
5978     * lastTargetUid else set that to -1.
5979     */
5980    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5981            Uri uri, int modeFlags, int lastTargetUid) {
5982        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
5983        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5984                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5985        if (modeFlags == 0) {
5986            return -1;
5987        }
5988
5989        if (targetPkg != null) {
5990            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5991                    "Checking grant " + targetPkg + " permission to " + uri);
5992        }
5993
5994        final IPackageManager pm = AppGlobals.getPackageManager();
5995
5996        // If this is not a content: uri, we can't do anything with it.
5997        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
5998            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5999                    "Can't grant URI permission for non-content URI: " + uri);
6000            return -1;
6001        }
6002
6003        final String authority = uri.getAuthority();
6004        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6005        if (pi == null) {
6006            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
6007            return -1;
6008        }
6009
6010        int targetUid = lastTargetUid;
6011        if (targetUid < 0 && targetPkg != null) {
6012            try {
6013                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6014                if (targetUid < 0) {
6015                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6016                            "Can't grant URI permission no uid for: " + targetPkg);
6017                    return -1;
6018                }
6019            } catch (RemoteException ex) {
6020                return -1;
6021            }
6022        }
6023
6024        if (targetUid >= 0) {
6025            // First...  does the target actually need this permission?
6026            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
6027                // No need to grant the target this permission.
6028                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6029                        "Target " + targetPkg + " already has full permission to " + uri);
6030                return -1;
6031            }
6032        } else {
6033            // First...  there is no target package, so can anyone access it?
6034            boolean allowed = pi.exported;
6035            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6036                if (pi.readPermission != null) {
6037                    allowed = false;
6038                }
6039            }
6040            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6041                if (pi.writePermission != null) {
6042                    allowed = false;
6043                }
6044            }
6045            if (allowed) {
6046                return -1;
6047            }
6048        }
6049
6050        // Second...  is the provider allowing granting of URI permissions?
6051        if (!pi.grantUriPermissions) {
6052            throw new SecurityException("Provider " + pi.packageName
6053                    + "/" + pi.name
6054                    + " does not allow granting of Uri permissions (uri "
6055                    + uri + ")");
6056        }
6057        if (pi.uriPermissionPatterns != null) {
6058            final int N = pi.uriPermissionPatterns.length;
6059            boolean allowed = false;
6060            for (int i=0; i<N; i++) {
6061                if (pi.uriPermissionPatterns[i] != null
6062                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
6063                    allowed = true;
6064                    break;
6065                }
6066            }
6067            if (!allowed) {
6068                throw new SecurityException("Provider " + pi.packageName
6069                        + "/" + pi.name
6070                        + " does not allow granting of permission to path of Uri "
6071                        + uri);
6072            }
6073        }
6074
6075        // Third...  does the caller itself have permission to access
6076        // this uri?
6077        if (callingUid != Process.myUid()) {
6078            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6079                // Require they hold a strong enough Uri permission
6080                final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6081                        : UriPermission.STRENGTH_OWNED;
6082                if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) {
6083                    throw new SecurityException("Uid " + callingUid
6084                            + " does not have permission to uri " + uri);
6085                }
6086            }
6087        }
6088
6089        return targetUid;
6090    }
6091
6092    @Override
6093    public int checkGrantUriPermission(int callingUid, String targetPkg,
6094            Uri uri, int modeFlags) {
6095        enforceNotIsolatedCaller("checkGrantUriPermission");
6096        synchronized(this) {
6097            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6098        }
6099    }
6100
6101    void grantUriPermissionUncheckedLocked(
6102            int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
6103        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6104        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6105                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6106        if (modeFlags == 0) {
6107            return;
6108        }
6109
6110        // So here we are: the caller has the assumed permission
6111        // to the uri, and the target doesn't.  Let's now give this to
6112        // the target.
6113
6114        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6115                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
6116
6117        final String authority = uri.getAuthority();
6118        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid));
6119        if (pi == null) {
6120            Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString());
6121            return;
6122        }
6123
6124        final UriPermission perm = findOrCreateUriPermissionLocked(
6125                pi.packageName, targetPkg, targetUid, uri);
6126        perm.grantModes(modeFlags, persistable, owner);
6127    }
6128
6129    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
6130            int modeFlags, UriPermissionOwner owner) {
6131        if (targetPkg == null) {
6132            throw new NullPointerException("targetPkg");
6133        }
6134
6135        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6136        if (targetUid < 0) {
6137            return;
6138        }
6139
6140        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
6141    }
6142
6143    static class NeededUriGrants extends ArrayList<Uri> {
6144        final String targetPkg;
6145        final int targetUid;
6146        final int flags;
6147
6148        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6149            this.targetPkg = targetPkg;
6150            this.targetUid = targetUid;
6151            this.flags = flags;
6152        }
6153    }
6154
6155    /**
6156     * Like checkGrantUriPermissionLocked, but takes an Intent.
6157     */
6158    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6159            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6160        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6161                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6162                + " clip=" + (intent != null ? intent.getClipData() : null)
6163                + " from " + intent + "; flags=0x"
6164                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6165
6166        if (targetPkg == null) {
6167            throw new NullPointerException("targetPkg");
6168        }
6169
6170        if (intent == null) {
6171            return null;
6172        }
6173        Uri data = intent.getData();
6174        ClipData clip = intent.getClipData();
6175        if (data == null && clip == null) {
6176            return null;
6177        }
6178
6179        if (data != null) {
6180            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
6181                mode, needed != null ? needed.targetUid : -1);
6182            if (targetUid > 0) {
6183                if (needed == null) {
6184                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6185                }
6186                needed.add(data);
6187            }
6188        }
6189        if (clip != null) {
6190            for (int i=0; i<clip.getItemCount(); i++) {
6191                Uri uri = clip.getItemAt(i).getUri();
6192                if (uri != null) {
6193                    int targetUid = -1;
6194                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
6195                            mode, needed != null ? needed.targetUid : -1);
6196                    if (targetUid > 0) {
6197                        if (needed == null) {
6198                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6199                        }
6200                        needed.add(uri);
6201                    }
6202                } else {
6203                    Intent clipIntent = clip.getItemAt(i).getIntent();
6204                    if (clipIntent != null) {
6205                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6206                                callingUid, targetPkg, clipIntent, mode, needed);
6207                        if (newNeeded != null) {
6208                            needed = newNeeded;
6209                        }
6210                    }
6211                }
6212            }
6213        }
6214
6215        return needed;
6216    }
6217
6218    /**
6219     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6220     */
6221    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6222            UriPermissionOwner owner) {
6223        if (needed != null) {
6224            for (int i=0; i<needed.size(); i++) {
6225                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6226                        needed.get(i), needed.flags, owner);
6227            }
6228        }
6229    }
6230
6231    void grantUriPermissionFromIntentLocked(int callingUid,
6232            String targetPkg, Intent intent, UriPermissionOwner owner) {
6233        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6234                intent, intent != null ? intent.getFlags() : 0, null);
6235        if (needed == null) {
6236            return;
6237        }
6238
6239        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6240    }
6241
6242    @Override
6243    public void grantUriPermission(IApplicationThread caller, String targetPkg,
6244            Uri uri, int modeFlags) {
6245        enforceNotIsolatedCaller("grantUriPermission");
6246        synchronized(this) {
6247            final ProcessRecord r = getRecordForAppLocked(caller);
6248            if (r == null) {
6249                throw new SecurityException("Unable to find app for caller "
6250                        + caller
6251                        + " when granting permission to uri " + uri);
6252            }
6253            if (targetPkg == null) {
6254                throw new IllegalArgumentException("null target");
6255            }
6256            if (uri == null) {
6257                throw new IllegalArgumentException("null uri");
6258            }
6259
6260            // Persistable only supported through Intents
6261            Preconditions.checkFlagsArgument(modeFlags,
6262                    Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6263
6264            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
6265                    null);
6266        }
6267    }
6268
6269    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6270        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
6271                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
6272            ArrayMap<Uri, UriPermission> perms
6273                    = mGrantedUriPermissions.get(perm.targetUid);
6274            if (perms != null) {
6275                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6276                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6277                perms.remove(perm.uri);
6278                if (perms.size() == 0) {
6279                    mGrantedUriPermissions.remove(perm.targetUid);
6280                }
6281            }
6282        }
6283    }
6284
6285    private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) {
6286        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri);
6287
6288        final IPackageManager pm = AppGlobals.getPackageManager();
6289        final String authority = uri.getAuthority();
6290        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6291        if (pi == null) {
6292            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
6293            return;
6294        }
6295
6296        // Does the caller have this permission on the URI?
6297        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6298            // Right now, if you are not the original owner of the permission,
6299            // you are not allowed to revoke it.
6300            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6301                throw new SecurityException("Uid " + callingUid
6302                        + " does not have permission to uri " + uri);
6303            //}
6304        }
6305
6306        boolean persistChanged = false;
6307
6308        // Go through all of the permissions and remove any that match.
6309        final List<String> SEGMENTS = uri.getPathSegments();
6310        if (SEGMENTS != null) {
6311            final int NS = SEGMENTS.size();
6312            int N = mGrantedUriPermissions.size();
6313            for (int i=0; i<N; i++) {
6314                ArrayMap<Uri, UriPermission> perms
6315                        = mGrantedUriPermissions.valueAt(i);
6316                Iterator<UriPermission> it = perms.values().iterator();
6317            toploop:
6318                while (it.hasNext()) {
6319                    UriPermission perm = it.next();
6320                    Uri targetUri = perm.uri;
6321                    if (!authority.equals(targetUri.getAuthority())) {
6322                        continue;
6323                    }
6324                    List<String> targetSegments = targetUri.getPathSegments();
6325                    if (targetSegments == null) {
6326                        continue;
6327                    }
6328                    if (targetSegments.size() < NS) {
6329                        continue;
6330                    }
6331                    for (int j=0; j<NS; j++) {
6332                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
6333                            continue toploop;
6334                        }
6335                    }
6336                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6337                            "Revoking " + perm.targetUid + " permission to " + perm.uri);
6338                    persistChanged |= perm.clearModes(modeFlags, true);
6339                    if (perm.modeFlags == 0) {
6340                        it.remove();
6341                    }
6342                }
6343                if (perms.size() == 0) {
6344                    mGrantedUriPermissions.remove(
6345                            mGrantedUriPermissions.keyAt(i));
6346                    N--;
6347                    i--;
6348                }
6349            }
6350        }
6351
6352        if (persistChanged) {
6353            schedulePersistUriGrants();
6354        }
6355    }
6356
6357    @Override
6358    public void revokeUriPermission(IApplicationThread caller, Uri uri,
6359            int modeFlags) {
6360        enforceNotIsolatedCaller("revokeUriPermission");
6361        synchronized(this) {
6362            final ProcessRecord r = getRecordForAppLocked(caller);
6363            if (r == null) {
6364                throw new SecurityException("Unable to find app for caller "
6365                        + caller
6366                        + " when revoking permission to uri " + uri);
6367            }
6368            if (uri == null) {
6369                Slog.w(TAG, "revokeUriPermission: null uri");
6370                return;
6371            }
6372
6373            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6374                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6375            if (modeFlags == 0) {
6376                return;
6377            }
6378
6379            final IPackageManager pm = AppGlobals.getPackageManager();
6380            final String authority = uri.getAuthority();
6381            final ProviderInfo pi = getProviderInfoLocked(authority, r.userId);
6382            if (pi == null) {
6383                Slog.w(TAG, "No content provider found for permission revoke: "
6384                        + uri.toSafeString());
6385                return;
6386            }
6387
6388            revokeUriPermissionLocked(r.uid, uri, modeFlags);
6389        }
6390    }
6391
6392    /**
6393     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6394     * given package.
6395     *
6396     * @param packageName Package name to match, or {@code null} to apply to all
6397     *            packages.
6398     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6399     *            to all users.
6400     * @param persistable If persistable grants should be removed.
6401     */
6402    private void removeUriPermissionsForPackageLocked(
6403            String packageName, int userHandle, boolean persistable) {
6404        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6405            throw new IllegalArgumentException("Must narrow by either package or user");
6406        }
6407
6408        boolean persistChanged = false;
6409
6410        final int size = mGrantedUriPermissions.size();
6411        for (int i = 0; i < size; i++) {
6412            // Only inspect grants matching user
6413            if (userHandle == UserHandle.USER_ALL
6414                    || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) {
6415                final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i)
6416                        .values().iterator();
6417                while (it.hasNext()) {
6418                    final UriPermission perm = it.next();
6419
6420                    // Only inspect grants matching package
6421                    if (packageName == null || perm.sourcePkg.equals(packageName)
6422                            || perm.targetPkg.equals(packageName)) {
6423                        persistChanged |= perm.clearModes(~0, persistable);
6424
6425                        // Only remove when no modes remain; any persisted grants
6426                        // will keep this alive.
6427                        if (perm.modeFlags == 0) {
6428                            it.remove();
6429                        }
6430                    }
6431                }
6432            }
6433        }
6434
6435        if (persistChanged) {
6436            schedulePersistUriGrants();
6437        }
6438    }
6439
6440    @Override
6441    public IBinder newUriPermissionOwner(String name) {
6442        enforceNotIsolatedCaller("newUriPermissionOwner");
6443        synchronized(this) {
6444            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6445            return owner.getExternalTokenLocked();
6446        }
6447    }
6448
6449    @Override
6450    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
6451            Uri uri, int modeFlags) {
6452        synchronized(this) {
6453            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6454            if (owner == null) {
6455                throw new IllegalArgumentException("Unknown owner: " + token);
6456            }
6457            if (fromUid != Binder.getCallingUid()) {
6458                if (Binder.getCallingUid() != Process.myUid()) {
6459                    // Only system code can grant URI permissions on behalf
6460                    // of other users.
6461                    throw new SecurityException("nice try");
6462                }
6463            }
6464            if (targetPkg == null) {
6465                throw new IllegalArgumentException("null target");
6466            }
6467            if (uri == null) {
6468                throw new IllegalArgumentException("null uri");
6469            }
6470
6471            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
6472        }
6473    }
6474
6475    @Override
6476    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
6477        synchronized(this) {
6478            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6479            if (owner == null) {
6480                throw new IllegalArgumentException("Unknown owner: " + token);
6481            }
6482
6483            if (uri == null) {
6484                owner.removeUriPermissionsLocked(mode);
6485            } else {
6486                owner.removeUriPermissionLocked(uri, mode);
6487            }
6488        }
6489    }
6490
6491    private void schedulePersistUriGrants() {
6492        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6493            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6494                    10 * DateUtils.SECOND_IN_MILLIS);
6495        }
6496    }
6497
6498    private void writeGrantedUriPermissions() {
6499        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6500
6501        // Snapshot permissions so we can persist without lock
6502        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6503        synchronized (this) {
6504            final int size = mGrantedUriPermissions.size();
6505            for (int i = 0 ; i < size; i++) {
6506                for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) {
6507                    if (perm.persistedModeFlags != 0) {
6508                        persist.add(perm.snapshot());
6509                    }
6510                }
6511            }
6512        }
6513
6514        FileOutputStream fos = null;
6515        try {
6516            fos = mGrantFile.startWrite();
6517
6518            XmlSerializer out = new FastXmlSerializer();
6519            out.setOutput(fos, "utf-8");
6520            out.startDocument(null, true);
6521            out.startTag(null, TAG_URI_GRANTS);
6522            for (UriPermission.Snapshot perm : persist) {
6523                out.startTag(null, TAG_URI_GRANT);
6524                writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle);
6525                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6526                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6527                out.attribute(null, ATTR_URI, String.valueOf(perm.uri));
6528                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6529                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6530                out.endTag(null, TAG_URI_GRANT);
6531            }
6532            out.endTag(null, TAG_URI_GRANTS);
6533            out.endDocument();
6534
6535            mGrantFile.finishWrite(fos);
6536        } catch (IOException e) {
6537            if (fos != null) {
6538                mGrantFile.failWrite(fos);
6539            }
6540        }
6541    }
6542
6543    private void readGrantedUriPermissionsLocked() {
6544        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6545
6546        final long now = System.currentTimeMillis();
6547
6548        FileInputStream fis = null;
6549        try {
6550            fis = mGrantFile.openRead();
6551            final XmlPullParser in = Xml.newPullParser();
6552            in.setInput(fis, null);
6553
6554            int type;
6555            while ((type = in.next()) != END_DOCUMENT) {
6556                final String tag = in.getName();
6557                if (type == START_TAG) {
6558                    if (TAG_URI_GRANT.equals(tag)) {
6559                        final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE);
6560                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6561                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6562                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6563                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6564                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6565
6566                        // Sanity check that provider still belongs to source package
6567                        final ProviderInfo pi = getProviderInfoLocked(
6568                                uri.getAuthority(), userHandle);
6569                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6570                            int targetUid = -1;
6571                            try {
6572                                targetUid = AppGlobals.getPackageManager()
6573                                        .getPackageUid(targetPkg, userHandle);
6574                            } catch (RemoteException e) {
6575                            }
6576                            if (targetUid != -1) {
6577                                final UriPermission perm = findOrCreateUriPermissionLocked(
6578                                        sourcePkg, targetPkg, targetUid, uri);
6579                                perm.initPersistedModes(modeFlags, createdTime);
6580                            }
6581                        } else {
6582                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6583                                    + " but instead found " + pi);
6584                        }
6585                    }
6586                }
6587            }
6588        } catch (FileNotFoundException e) {
6589            // Missing grants is okay
6590        } catch (IOException e) {
6591            Log.wtf(TAG, "Failed reading Uri grants", e);
6592        } catch (XmlPullParserException e) {
6593            Log.wtf(TAG, "Failed reading Uri grants", e);
6594        } finally {
6595            IoUtils.closeQuietly(fis);
6596        }
6597    }
6598
6599    @Override
6600    public void takePersistableUriPermission(Uri uri, int modeFlags) {
6601        enforceNotIsolatedCaller("takePersistableUriPermission");
6602
6603        Preconditions.checkFlagsArgument(modeFlags,
6604                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6605
6606        synchronized (this) {
6607            final int callingUid = Binder.getCallingUid();
6608            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6609            if (perm == null) {
6610                throw new SecurityException("No permission grant found for UID " + callingUid
6611                        + " and Uri " + uri.toSafeString());
6612            }
6613
6614            boolean persistChanged = perm.takePersistableModes(modeFlags);
6615            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6616
6617            if (persistChanged) {
6618                schedulePersistUriGrants();
6619            }
6620        }
6621    }
6622
6623    @Override
6624    public void releasePersistableUriPermission(Uri uri, int modeFlags) {
6625        enforceNotIsolatedCaller("releasePersistableUriPermission");
6626
6627        Preconditions.checkFlagsArgument(modeFlags,
6628                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6629
6630        synchronized (this) {
6631            final int callingUid = Binder.getCallingUid();
6632
6633            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6634            if (perm == null) {
6635                Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri "
6636                        + uri.toSafeString());
6637                return;
6638            }
6639
6640            final boolean persistChanged = perm.releasePersistableModes(modeFlags);
6641            removeUriPermissionIfNeededLocked(perm);
6642            if (persistChanged) {
6643                schedulePersistUriGrants();
6644            }
6645        }
6646    }
6647
6648    /**
6649     * Prune any older {@link UriPermission} for the given UID until outstanding
6650     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6651     *
6652     * @return if any mutations occured that require persisting.
6653     */
6654    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6655        final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6656        if (perms == null) return false;
6657        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6658
6659        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6660        for (UriPermission perm : perms.values()) {
6661            if (perm.persistedModeFlags != 0) {
6662                persisted.add(perm);
6663            }
6664        }
6665
6666        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6667        if (trimCount <= 0) return false;
6668
6669        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6670        for (int i = 0; i < trimCount; i++) {
6671            final UriPermission perm = persisted.get(i);
6672
6673            if (DEBUG_URI_PERMISSION) {
6674                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6675            }
6676
6677            perm.releasePersistableModes(~0);
6678            removeUriPermissionIfNeededLocked(perm);
6679        }
6680
6681        return true;
6682    }
6683
6684    @Override
6685    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6686            String packageName, boolean incoming) {
6687        enforceNotIsolatedCaller("getPersistedUriPermissions");
6688        Preconditions.checkNotNull(packageName, "packageName");
6689
6690        final int callingUid = Binder.getCallingUid();
6691        final IPackageManager pm = AppGlobals.getPackageManager();
6692        try {
6693            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6694            if (packageUid != callingUid) {
6695                throw new SecurityException(
6696                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6697            }
6698        } catch (RemoteException e) {
6699            throw new SecurityException("Failed to verify package name ownership");
6700        }
6701
6702        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6703        synchronized (this) {
6704            if (incoming) {
6705                final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6706                if (perms == null) {
6707                    Slog.w(TAG, "No permission grants found for " + packageName);
6708                } else {
6709                    final int size = perms.size();
6710                    for (int i = 0; i < size; i++) {
6711                        final UriPermission perm = perms.valueAt(i);
6712                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6713                            result.add(perm.buildPersistedPublicApiObject());
6714                        }
6715                    }
6716                }
6717            } else {
6718                final int size = mGrantedUriPermissions.size();
6719                for (int i = 0; i < size; i++) {
6720                    final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6721                    final int permsSize = perms.size();
6722                    for (int j = 0; j < permsSize; j++) {
6723                        final UriPermission perm = perms.valueAt(j);
6724                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6725                            result.add(perm.buildPersistedPublicApiObject());
6726                        }
6727                    }
6728                }
6729            }
6730        }
6731        return new ParceledListSlice<android.content.UriPermission>(result);
6732    }
6733
6734    @Override
6735    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6736        synchronized (this) {
6737            ProcessRecord app =
6738                who != null ? getRecordForAppLocked(who) : null;
6739            if (app == null) return;
6740
6741            Message msg = Message.obtain();
6742            msg.what = WAIT_FOR_DEBUGGER_MSG;
6743            msg.obj = app;
6744            msg.arg1 = waiting ? 1 : 0;
6745            mHandler.sendMessage(msg);
6746        }
6747    }
6748
6749    @Override
6750    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
6751        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
6752        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
6753        outInfo.availMem = Process.getFreeMemory();
6754        outInfo.totalMem = Process.getTotalMemory();
6755        outInfo.threshold = homeAppMem;
6756        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
6757        outInfo.hiddenAppThreshold = cachedAppMem;
6758        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
6759                ProcessList.SERVICE_ADJ);
6760        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
6761                ProcessList.VISIBLE_APP_ADJ);
6762        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
6763                ProcessList.FOREGROUND_APP_ADJ);
6764    }
6765
6766    // =========================================================
6767    // TASK MANAGEMENT
6768    // =========================================================
6769
6770    @Override
6771    public List<RunningTaskInfo> getTasks(int maxNum, int flags,
6772                         IThumbnailReceiver receiver) {
6773        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
6774
6775        PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver);
6776        ActivityRecord topRecord = null;
6777
6778        synchronized(this) {
6779            if (localLOGV) Slog.v(
6780                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
6781                + ", receiver=" + receiver);
6782
6783            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
6784                    != PackageManager.PERMISSION_GRANTED) {
6785                if (receiver != null) {
6786                    // If the caller wants to wait for pending thumbnails,
6787                    // it ain't gonna get them.
6788                    try {
6789                        receiver.finished();
6790                    } catch (RemoteException ex) {
6791                    }
6792                }
6793                String msg = "Permission Denial: getTasks() from pid="
6794                        + Binder.getCallingPid()
6795                        + ", uid=" + Binder.getCallingUid()
6796                        + " requires " + android.Manifest.permission.GET_TASKS;
6797                Slog.w(TAG, msg);
6798                throw new SecurityException(msg);
6799            }
6800
6801            // TODO: Improve with MRU list from all ActivityStacks.
6802            topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list);
6803
6804            if (!pending.pendingRecords.isEmpty()) {
6805                mPendingThumbnails.add(pending);
6806            }
6807        }
6808
6809        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
6810
6811        if (topRecord != null) {
6812            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
6813            try {
6814                IApplicationThread topThumbnail = topRecord.app.thread;
6815                topThumbnail.requestThumbnail(topRecord.appToken);
6816            } catch (Exception e) {
6817                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
6818                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
6819            }
6820        }
6821
6822        if (pending == null && receiver != null) {
6823            // In this case all thumbnails were available and the client
6824            // is being asked to be told when the remaining ones come in...
6825            // which is unusually, since the top-most currently running
6826            // activity should never have a canned thumbnail!  Oh well.
6827            try {
6828                receiver.finished();
6829            } catch (RemoteException ex) {
6830            }
6831        }
6832
6833        return list;
6834    }
6835
6836    TaskRecord getMostRecentTask() {
6837        return mRecentTasks.get(0);
6838    }
6839
6840    @Override
6841    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
6842            int flags, int userId) {
6843        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6844                false, true, "getRecentTasks", null);
6845
6846        synchronized (this) {
6847            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
6848                    "getRecentTasks()");
6849            final boolean detailed = checkCallingPermission(
6850                    android.Manifest.permission.GET_DETAILED_TASKS)
6851                    == PackageManager.PERMISSION_GRANTED;
6852
6853            IPackageManager pm = AppGlobals.getPackageManager();
6854
6855            final int N = mRecentTasks.size();
6856            ArrayList<ActivityManager.RecentTaskInfo> res
6857                    = new ArrayList<ActivityManager.RecentTaskInfo>(
6858                            maxNum < N ? maxNum : N);
6859            for (int i=0; i<N && maxNum > 0; i++) {
6860                TaskRecord tr = mRecentTasks.get(i);
6861                // Only add calling user's recent tasks
6862                if (tr.userId != userId) continue;
6863                // Return the entry if desired by the caller.  We always return
6864                // the first entry, because callers always expect this to be the
6865                // foreground app.  We may filter others if the caller has
6866                // not supplied RECENT_WITH_EXCLUDED and there is some reason
6867                // we should exclude the entry.
6868
6869                if (i == 0
6870                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
6871                        || (tr.intent == null)
6872                        || ((tr.intent.getFlags()
6873                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
6874                    ActivityManager.RecentTaskInfo rti
6875                            = new ActivityManager.RecentTaskInfo();
6876                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
6877                    rti.persistentId = tr.taskId;
6878                    rti.baseIntent = new Intent(
6879                            tr.intent != null ? tr.intent : tr.affinityIntent);
6880                    if (!detailed) {
6881                        rti.baseIntent.replaceExtras((Bundle)null);
6882                    }
6883                    rti.origActivity = tr.origActivity;
6884                    rti.description = tr.lastDescription;
6885                    rti.stackId = tr.stack.mStackId;
6886
6887                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
6888                        // Check whether this activity is currently available.
6889                        try {
6890                            if (rti.origActivity != null) {
6891                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
6892                                        == null) {
6893                                    continue;
6894                                }
6895                            } else if (rti.baseIntent != null) {
6896                                if (pm.queryIntentActivities(rti.baseIntent,
6897                                        null, 0, userId) == null) {
6898                                    continue;
6899                                }
6900                            }
6901                        } catch (RemoteException e) {
6902                            // Will never happen.
6903                        }
6904                    }
6905
6906                    res.add(rti);
6907                    maxNum--;
6908                }
6909            }
6910            return res;
6911        }
6912    }
6913
6914    private TaskRecord recentTaskForIdLocked(int id) {
6915        final int N = mRecentTasks.size();
6916            for (int i=0; i<N; i++) {
6917                TaskRecord tr = mRecentTasks.get(i);
6918                if (tr.taskId == id) {
6919                    return tr;
6920                }
6921            }
6922            return null;
6923    }
6924
6925    @Override
6926    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
6927        synchronized (this) {
6928            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6929                    "getTaskThumbnails()");
6930            TaskRecord tr = recentTaskForIdLocked(id);
6931            if (tr != null) {
6932                return tr.getTaskThumbnailsLocked();
6933            }
6934        }
6935        return null;
6936    }
6937
6938    @Override
6939    public Bitmap getTaskTopThumbnail(int id) {
6940        synchronized (this) {
6941            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6942                    "getTaskTopThumbnail()");
6943            TaskRecord tr = recentTaskForIdLocked(id);
6944            if (tr != null) {
6945                return tr.getTaskTopThumbnailLocked();
6946            }
6947        }
6948        return null;
6949    }
6950
6951    @Override
6952    public boolean removeSubTask(int taskId, int subTaskIndex) {
6953        synchronized (this) {
6954            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6955                    "removeSubTask()");
6956            long ident = Binder.clearCallingIdentity();
6957            try {
6958                TaskRecord tr = recentTaskForIdLocked(taskId);
6959                if (tr != null) {
6960                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
6961                }
6962                return false;
6963            } finally {
6964                Binder.restoreCallingIdentity(ident);
6965            }
6966        }
6967    }
6968
6969    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
6970        if (!pr.killedByAm) {
6971            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
6972            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
6973                    pr.processName, pr.setAdj, reason);
6974            pr.killedByAm = true;
6975            Process.killProcessQuiet(pr.pid);
6976        }
6977    }
6978
6979    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
6980        tr.disposeThumbnail();
6981        mRecentTasks.remove(tr);
6982        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
6983        Intent baseIntent = new Intent(
6984                tr.intent != null ? tr.intent : tr.affinityIntent);
6985        ComponentName component = baseIntent.getComponent();
6986        if (component == null) {
6987            Slog.w(TAG, "Now component for base intent of task: " + tr);
6988            return;
6989        }
6990
6991        // Find any running services associated with this app.
6992        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
6993
6994        if (killProcesses) {
6995            // Find any running processes associated with this app.
6996            final String pkg = component.getPackageName();
6997            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
6998            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
6999            for (int i=0; i<pmap.size(); i++) {
7000                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7001                for (int j=0; j<uids.size(); j++) {
7002                    ProcessRecord proc = uids.valueAt(j);
7003                    if (proc.userId != tr.userId) {
7004                        continue;
7005                    }
7006                    if (!proc.pkgList.containsKey(pkg)) {
7007                        continue;
7008                    }
7009                    procs.add(proc);
7010                }
7011            }
7012
7013            // Kill the running processes.
7014            for (int i=0; i<procs.size(); i++) {
7015                ProcessRecord pr = procs.get(i);
7016                if (pr == mHomeProcess) {
7017                    // Don't kill the home process along with tasks from the same package.
7018                    continue;
7019                }
7020                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7021                    killUnneededProcessLocked(pr, "remove task");
7022                } else {
7023                    pr.waitingToKill = "remove task";
7024                }
7025            }
7026        }
7027    }
7028
7029    @Override
7030    public boolean removeTask(int taskId, int flags) {
7031        synchronized (this) {
7032            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7033                    "removeTask()");
7034            long ident = Binder.clearCallingIdentity();
7035            try {
7036                TaskRecord tr = recentTaskForIdLocked(taskId);
7037                if (tr != null) {
7038                    ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false);
7039                    if (r != null) {
7040                        cleanUpRemovedTaskLocked(tr, flags);
7041                        return true;
7042                    }
7043                    if (tr.mActivities.size() == 0) {
7044                        // Caller is just removing a recent task that is
7045                        // not actively running.  That is easy!
7046                        cleanUpRemovedTaskLocked(tr, flags);
7047                        return true;
7048                    }
7049                    Slog.w(TAG, "removeTask: task " + taskId
7050                            + " does not have activities to remove, "
7051                            + " but numActivities=" + tr.numActivities
7052                            + ": " + tr);
7053                }
7054            } finally {
7055                Binder.restoreCallingIdentity(ident);
7056            }
7057        }
7058        return false;
7059    }
7060
7061    /**
7062     * TODO: Add mController hook
7063     */
7064    @Override
7065    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7066        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7067                "moveTaskToFront()");
7068
7069        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7070        synchronized(this) {
7071            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7072                    Binder.getCallingUid(), "Task to front")) {
7073                ActivityOptions.abort(options);
7074                return;
7075            }
7076            final long origId = Binder.clearCallingIdentity();
7077            try {
7078                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7079                if (task == null) {
7080                    return;
7081                }
7082                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7083                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7084                    return;
7085                }
7086                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7087            } finally {
7088                Binder.restoreCallingIdentity(origId);
7089            }
7090            ActivityOptions.abort(options);
7091        }
7092    }
7093
7094    @Override
7095    public void moveTaskToBack(int taskId) {
7096        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7097                "moveTaskToBack()");
7098
7099        synchronized(this) {
7100            TaskRecord tr = recentTaskForIdLocked(taskId);
7101            if (tr != null) {
7102                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7103                ActivityStack stack = tr.stack;
7104                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7105                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7106                            Binder.getCallingUid(), "Task to back")) {
7107                        return;
7108                    }
7109                }
7110                final long origId = Binder.clearCallingIdentity();
7111                try {
7112                    stack.moveTaskToBackLocked(taskId, null);
7113                } finally {
7114                    Binder.restoreCallingIdentity(origId);
7115                }
7116            }
7117        }
7118    }
7119
7120    /**
7121     * Moves an activity, and all of the other activities within the same task, to the bottom
7122     * of the history stack.  The activity's order within the task is unchanged.
7123     *
7124     * @param token A reference to the activity we wish to move
7125     * @param nonRoot If false then this only works if the activity is the root
7126     *                of a task; if true it will work for any activity in a task.
7127     * @return Returns true if the move completed, false if not.
7128     */
7129    @Override
7130    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7131        enforceNotIsolatedCaller("moveActivityTaskToBack");
7132        synchronized(this) {
7133            final long origId = Binder.clearCallingIdentity();
7134            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7135            if (taskId >= 0) {
7136                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7137            }
7138            Binder.restoreCallingIdentity(origId);
7139        }
7140        return false;
7141    }
7142
7143    @Override
7144    public void moveTaskBackwards(int task) {
7145        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7146                "moveTaskBackwards()");
7147
7148        synchronized(this) {
7149            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7150                    Binder.getCallingUid(), "Task backwards")) {
7151                return;
7152            }
7153            final long origId = Binder.clearCallingIdentity();
7154            moveTaskBackwardsLocked(task);
7155            Binder.restoreCallingIdentity(origId);
7156        }
7157    }
7158
7159    private final void moveTaskBackwardsLocked(int task) {
7160        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7161    }
7162
7163    @Override
7164    public IBinder getHomeActivityToken() throws RemoteException {
7165        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7166                "getHomeActivityToken()");
7167        synchronized (this) {
7168            return mStackSupervisor.getHomeActivityToken();
7169        }
7170    }
7171
7172    @Override
7173    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7174            IActivityContainerCallback callback) throws RemoteException {
7175        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7176                "createActivityContainer()");
7177        synchronized (this) {
7178            if (parentActivityToken == null) {
7179                throw new IllegalArgumentException("parent token must not be null");
7180            }
7181            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7182            if (r == null) {
7183                return null;
7184            }
7185            return mStackSupervisor.createActivityContainer(r, callback);
7186        }
7187    }
7188
7189    @Override
7190    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7191        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7192                "deleteActivityContainer()");
7193        synchronized (this) {
7194            mStackSupervisor.deleteActivityContainer(container);
7195        }
7196    }
7197
7198    @Override
7199    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7200            throws RemoteException {
7201        synchronized (this) {
7202            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7203            if (stack != null) {
7204                return stack.mActivityContainer;
7205            }
7206            return null;
7207        }
7208    }
7209
7210    @Override
7211    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7212        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7213                "moveTaskToStack()");
7214        if (stackId == HOME_STACK_ID) {
7215            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7216                    new RuntimeException("here").fillInStackTrace());
7217        }
7218        synchronized (this) {
7219            long ident = Binder.clearCallingIdentity();
7220            try {
7221                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7222                        + stackId + " toTop=" + toTop);
7223                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7224            } finally {
7225                Binder.restoreCallingIdentity(ident);
7226            }
7227        }
7228    }
7229
7230    @Override
7231    public void resizeStack(int stackBoxId, Rect bounds) {
7232        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7233                "resizeStackBox()");
7234        long ident = Binder.clearCallingIdentity();
7235        try {
7236            mWindowManager.resizeStack(stackBoxId, bounds);
7237        } finally {
7238            Binder.restoreCallingIdentity(ident);
7239        }
7240    }
7241
7242    @Override
7243    public List<StackInfo> getAllStackInfos() {
7244        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7245                "getAllStackInfos()");
7246        long ident = Binder.clearCallingIdentity();
7247        try {
7248            synchronized (this) {
7249                return mStackSupervisor.getAllStackInfosLocked();
7250            }
7251        } finally {
7252            Binder.restoreCallingIdentity(ident);
7253        }
7254    }
7255
7256    @Override
7257    public StackInfo getStackInfo(int stackId) {
7258        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7259                "getStackInfo()");
7260        long ident = Binder.clearCallingIdentity();
7261        try {
7262            synchronized (this) {
7263                return mStackSupervisor.getStackInfoLocked(stackId);
7264            }
7265        } finally {
7266            Binder.restoreCallingIdentity(ident);
7267        }
7268    }
7269
7270    @Override
7271    public boolean isInHomeStack(int taskId) {
7272        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7273                "getStackInfo()");
7274        long ident = Binder.clearCallingIdentity();
7275        try {
7276            synchronized (this) {
7277                TaskRecord tr = recentTaskForIdLocked(taskId);
7278                if (tr != null) {
7279                    return tr.stack.isHomeStack();
7280                }
7281            }
7282        } finally {
7283            Binder.restoreCallingIdentity(ident);
7284        }
7285        return false;
7286    }
7287
7288    @Override
7289    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7290        synchronized(this) {
7291            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7292        }
7293    }
7294
7295    private boolean isLockTaskAuthorized(ComponentName name) {
7296//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7297//                "startLockTaskMode()");
7298//        DevicePolicyManager dpm = (DevicePolicyManager)
7299//                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7300//        return dpm != null && dpm.isLockTaskPermitted(name);
7301        return true;
7302    }
7303
7304    private void startLockTaskMode(TaskRecord task) {
7305        if (!isLockTaskAuthorized(task.intent.getComponent())) {
7306            return;
7307        }
7308        long ident = Binder.clearCallingIdentity();
7309        try {
7310            synchronized (this) {
7311                // Since we lost lock on task, make sure it is still there.
7312                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7313                if (task != null) {
7314                    mStackSupervisor.setLockTaskModeLocked(task);
7315                }
7316            }
7317        } finally {
7318            Binder.restoreCallingIdentity(ident);
7319        }
7320    }
7321
7322    @Override
7323    public void startLockTaskMode(int taskId) {
7324        long ident = Binder.clearCallingIdentity();
7325        try {
7326            final TaskRecord task;
7327            synchronized (this) {
7328                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7329            }
7330            if (task != null) {
7331                startLockTaskMode(task);
7332            }
7333        } finally {
7334            Binder.restoreCallingIdentity(ident);
7335        }
7336    }
7337
7338    @Override
7339    public void startLockTaskMode(IBinder token) {
7340        long ident = Binder.clearCallingIdentity();
7341        try {
7342            final TaskRecord task;
7343            synchronized (this) {
7344                final ActivityRecord r = ActivityRecord.forToken(token);
7345                if (r == null) {
7346                    return;
7347                }
7348                task = r.task;
7349            }
7350            if (task != null) {
7351                startLockTaskMode(task);
7352            }
7353        } finally {
7354            Binder.restoreCallingIdentity(ident);
7355        }
7356    }
7357
7358    @Override
7359    public void stopLockTaskMode() {
7360//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7361//                "stopLockTaskMode()");
7362        synchronized (this) {
7363            mStackSupervisor.setLockTaskModeLocked(null);
7364        }
7365    }
7366
7367    @Override
7368    public boolean isInLockTaskMode() {
7369        synchronized (this) {
7370            return mStackSupervisor.isInLockTaskMode();
7371        }
7372    }
7373
7374    // =========================================================
7375    // THUMBNAILS
7376    // =========================================================
7377
7378    public void reportThumbnail(IBinder token,
7379            Bitmap thumbnail, CharSequence description) {
7380        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
7381        final long origId = Binder.clearCallingIdentity();
7382        sendPendingThumbnail(null, token, thumbnail, description, true);
7383        Binder.restoreCallingIdentity(origId);
7384    }
7385
7386    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
7387            Bitmap thumbnail, CharSequence description, boolean always) {
7388        TaskRecord task;
7389        ArrayList<PendingThumbnailsRecord> receivers = null;
7390
7391        //System.out.println("Send pending thumbnail: " + r);
7392
7393        synchronized(this) {
7394            if (r == null) {
7395                r = ActivityRecord.isInStackLocked(token);
7396                if (r == null) {
7397                    return;
7398                }
7399            }
7400            if (thumbnail == null && r.thumbHolder != null) {
7401                thumbnail = r.thumbHolder.lastThumbnail;
7402                description = r.thumbHolder.lastDescription;
7403            }
7404            if (thumbnail == null && !always) {
7405                // If there is no thumbnail, and this entry is not actually
7406                // going away, then abort for now and pick up the next
7407                // thumbnail we get.
7408                return;
7409            }
7410            task = r.task;
7411
7412            int N = mPendingThumbnails.size();
7413            int i=0;
7414            while (i<N) {
7415                PendingThumbnailsRecord pr = mPendingThumbnails.get(i);
7416                //System.out.println("Looking in " + pr.pendingRecords);
7417                if (pr.pendingRecords.remove(r)) {
7418                    if (receivers == null) {
7419                        receivers = new ArrayList<PendingThumbnailsRecord>();
7420                    }
7421                    receivers.add(pr);
7422                    if (pr.pendingRecords.size() == 0) {
7423                        pr.finished = true;
7424                        mPendingThumbnails.remove(i);
7425                        N--;
7426                        continue;
7427                    }
7428                }
7429                i++;
7430            }
7431        }
7432
7433        if (receivers != null) {
7434            final int N = receivers.size();
7435            for (int i=0; i<N; i++) {
7436                try {
7437                    PendingThumbnailsRecord pr = receivers.get(i);
7438                    pr.receiver.newThumbnail(
7439                        task != null ? task.taskId : -1, thumbnail, description);
7440                    if (pr.finished) {
7441                        pr.receiver.finished();
7442                    }
7443                } catch (Exception e) {
7444                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
7445                }
7446            }
7447        }
7448    }
7449
7450    // =========================================================
7451    // CONTENT PROVIDERS
7452    // =========================================================
7453
7454    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7455        List<ProviderInfo> providers = null;
7456        try {
7457            providers = AppGlobals.getPackageManager().
7458                queryContentProviders(app.processName, app.uid,
7459                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7460        } catch (RemoteException ex) {
7461        }
7462        if (DEBUG_MU)
7463            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7464        int userId = app.userId;
7465        if (providers != null) {
7466            int N = providers.size();
7467            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7468            for (int i=0; i<N; i++) {
7469                ProviderInfo cpi =
7470                    (ProviderInfo)providers.get(i);
7471                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7472                        cpi.name, cpi.flags);
7473                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7474                    // This is a singleton provider, but a user besides the
7475                    // default user is asking to initialize a process it runs
7476                    // in...  well, no, it doesn't actually run in this process,
7477                    // it runs in the process of the default user.  Get rid of it.
7478                    providers.remove(i);
7479                    N--;
7480                    i--;
7481                    continue;
7482                }
7483
7484                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7485                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7486                if (cpr == null) {
7487                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7488                    mProviderMap.putProviderByClass(comp, cpr);
7489                }
7490                if (DEBUG_MU)
7491                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7492                app.pubProviders.put(cpi.name, cpr);
7493                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7494                    // Don't add this if it is a platform component that is marked
7495                    // to run in multiple processes, because this is actually
7496                    // part of the framework so doesn't make sense to track as a
7497                    // separate apk in the process.
7498                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7499                }
7500                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7501            }
7502        }
7503        return providers;
7504    }
7505
7506    /**
7507     * Check if {@link ProcessRecord} has a possible chance at accessing the
7508     * given {@link ProviderInfo}. Final permission checking is always done
7509     * in {@link ContentProvider}.
7510     */
7511    private final String checkContentProviderPermissionLocked(
7512            ProviderInfo cpi, ProcessRecord r) {
7513        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7514        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7515        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7516                cpi.applicationInfo.uid, cpi.exported)
7517                == PackageManager.PERMISSION_GRANTED) {
7518            return null;
7519        }
7520        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7521                cpi.applicationInfo.uid, cpi.exported)
7522                == PackageManager.PERMISSION_GRANTED) {
7523            return null;
7524        }
7525
7526        PathPermission[] pps = cpi.pathPermissions;
7527        if (pps != null) {
7528            int i = pps.length;
7529            while (i > 0) {
7530                i--;
7531                PathPermission pp = pps[i];
7532                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7533                        cpi.applicationInfo.uid, cpi.exported)
7534                        == PackageManager.PERMISSION_GRANTED) {
7535                    return null;
7536                }
7537                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7538                        cpi.applicationInfo.uid, cpi.exported)
7539                        == PackageManager.PERMISSION_GRANTED) {
7540                    return null;
7541                }
7542            }
7543        }
7544
7545        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7546        if (perms != null) {
7547            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
7548                if (uri.getKey().getAuthority().equals(cpi.authority)) {
7549                    return null;
7550                }
7551            }
7552        }
7553
7554        String msg;
7555        if (!cpi.exported) {
7556            msg = "Permission Denial: opening provider " + cpi.name
7557                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7558                    + ", uid=" + callingUid + ") that is not exported from uid "
7559                    + cpi.applicationInfo.uid;
7560        } else {
7561            msg = "Permission Denial: opening provider " + cpi.name
7562                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7563                    + ", uid=" + callingUid + ") requires "
7564                    + cpi.readPermission + " or " + cpi.writePermission;
7565        }
7566        Slog.w(TAG, msg);
7567        return msg;
7568    }
7569
7570    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7571            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7572        if (r != null) {
7573            for (int i=0; i<r.conProviders.size(); i++) {
7574                ContentProviderConnection conn = r.conProviders.get(i);
7575                if (conn.provider == cpr) {
7576                    if (DEBUG_PROVIDER) Slog.v(TAG,
7577                            "Adding provider requested by "
7578                            + r.processName + " from process "
7579                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7580                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7581                    if (stable) {
7582                        conn.stableCount++;
7583                        conn.numStableIncs++;
7584                    } else {
7585                        conn.unstableCount++;
7586                        conn.numUnstableIncs++;
7587                    }
7588                    return conn;
7589                }
7590            }
7591            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7592            if (stable) {
7593                conn.stableCount = 1;
7594                conn.numStableIncs = 1;
7595            } else {
7596                conn.unstableCount = 1;
7597                conn.numUnstableIncs = 1;
7598            }
7599            cpr.connections.add(conn);
7600            r.conProviders.add(conn);
7601            return conn;
7602        }
7603        cpr.addExternalProcessHandleLocked(externalProcessToken);
7604        return null;
7605    }
7606
7607    boolean decProviderCountLocked(ContentProviderConnection conn,
7608            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7609        if (conn != null) {
7610            cpr = conn.provider;
7611            if (DEBUG_PROVIDER) Slog.v(TAG,
7612                    "Removing provider requested by "
7613                    + conn.client.processName + " from process "
7614                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7615                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7616            if (stable) {
7617                conn.stableCount--;
7618            } else {
7619                conn.unstableCount--;
7620            }
7621            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7622                cpr.connections.remove(conn);
7623                conn.client.conProviders.remove(conn);
7624                return true;
7625            }
7626            return false;
7627        }
7628        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7629        return false;
7630    }
7631
7632    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7633            String name, IBinder token, boolean stable, int userId) {
7634        ContentProviderRecord cpr;
7635        ContentProviderConnection conn = null;
7636        ProviderInfo cpi = null;
7637
7638        synchronized(this) {
7639            ProcessRecord r = null;
7640            if (caller != null) {
7641                r = getRecordForAppLocked(caller);
7642                if (r == null) {
7643                    throw new SecurityException(
7644                            "Unable to find app for caller " + caller
7645                          + " (pid=" + Binder.getCallingPid()
7646                          + ") when getting content provider " + name);
7647                }
7648            }
7649
7650            // First check if this content provider has been published...
7651            cpr = mProviderMap.getProviderByName(name, userId);
7652            boolean providerRunning = cpr != null;
7653            if (providerRunning) {
7654                cpi = cpr.info;
7655                String msg;
7656                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7657                    throw new SecurityException(msg);
7658                }
7659
7660                if (r != null && cpr.canRunHere(r)) {
7661                    // This provider has been published or is in the process
7662                    // of being published...  but it is also allowed to run
7663                    // in the caller's process, so don't make a connection
7664                    // and just let the caller instantiate its own instance.
7665                    ContentProviderHolder holder = cpr.newHolder(null);
7666                    // don't give caller the provider object, it needs
7667                    // to make its own.
7668                    holder.provider = null;
7669                    return holder;
7670                }
7671
7672                final long origId = Binder.clearCallingIdentity();
7673
7674                // In this case the provider instance already exists, so we can
7675                // return it right away.
7676                conn = incProviderCountLocked(r, cpr, token, stable);
7677                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7678                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7679                        // If this is a perceptible app accessing the provider,
7680                        // make sure to count it as being accessed and thus
7681                        // back up on the LRU list.  This is good because
7682                        // content providers are often expensive to start.
7683                        updateLruProcessLocked(cpr.proc, false, null);
7684                    }
7685                }
7686
7687                if (cpr.proc != null) {
7688                    if (false) {
7689                        if (cpr.name.flattenToShortString().equals(
7690                                "com.android.providers.calendar/.CalendarProvider2")) {
7691                            Slog.v(TAG, "****************** KILLING "
7692                                + cpr.name.flattenToShortString());
7693                            Process.killProcess(cpr.proc.pid);
7694                        }
7695                    }
7696                    boolean success = updateOomAdjLocked(cpr.proc);
7697                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7698                    // NOTE: there is still a race here where a signal could be
7699                    // pending on the process even though we managed to update its
7700                    // adj level.  Not sure what to do about this, but at least
7701                    // the race is now smaller.
7702                    if (!success) {
7703                        // Uh oh...  it looks like the provider's process
7704                        // has been killed on us.  We need to wait for a new
7705                        // process to be started, and make sure its death
7706                        // doesn't kill our process.
7707                        Slog.i(TAG,
7708                                "Existing provider " + cpr.name.flattenToShortString()
7709                                + " is crashing; detaching " + r);
7710                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7711                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7712                        if (!lastRef) {
7713                            // This wasn't the last ref our process had on
7714                            // the provider...  we have now been killed, bail.
7715                            return null;
7716                        }
7717                        providerRunning = false;
7718                        conn = null;
7719                    }
7720                }
7721
7722                Binder.restoreCallingIdentity(origId);
7723            }
7724
7725            boolean singleton;
7726            if (!providerRunning) {
7727                try {
7728                    cpi = AppGlobals.getPackageManager().
7729                        resolveContentProvider(name,
7730                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7731                } catch (RemoteException ex) {
7732                }
7733                if (cpi == null) {
7734                    return null;
7735                }
7736                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7737                        cpi.name, cpi.flags);
7738                if (singleton) {
7739                    userId = 0;
7740                }
7741                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7742
7743                String msg;
7744                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7745                    throw new SecurityException(msg);
7746                }
7747
7748                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
7749                        && !cpi.processName.equals("system")) {
7750                    // If this content provider does not run in the system
7751                    // process, and the system is not yet ready to run other
7752                    // processes, then fail fast instead of hanging.
7753                    throw new IllegalArgumentException(
7754                            "Attempt to launch content provider before system ready");
7755                }
7756
7757                // Make sure that the user who owns this provider is started.  If not,
7758                // we don't want to allow it to run.
7759                if (mStartedUsers.get(userId) == null) {
7760                    Slog.w(TAG, "Unable to launch app "
7761                            + cpi.applicationInfo.packageName + "/"
7762                            + cpi.applicationInfo.uid + " for provider "
7763                            + name + ": user " + userId + " is stopped");
7764                    return null;
7765                }
7766
7767                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7768                cpr = mProviderMap.getProviderByClass(comp, userId);
7769                final boolean firstClass = cpr == null;
7770                if (firstClass) {
7771                    try {
7772                        ApplicationInfo ai =
7773                            AppGlobals.getPackageManager().
7774                                getApplicationInfo(
7775                                        cpi.applicationInfo.packageName,
7776                                        STOCK_PM_FLAGS, userId);
7777                        if (ai == null) {
7778                            Slog.w(TAG, "No package info for content provider "
7779                                    + cpi.name);
7780                            return null;
7781                        }
7782                        ai = getAppInfoForUser(ai, userId);
7783                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
7784                    } catch (RemoteException ex) {
7785                        // pm is in same process, this will never happen.
7786                    }
7787                }
7788
7789                if (r != null && cpr.canRunHere(r)) {
7790                    // If this is a multiprocess provider, then just return its
7791                    // info and allow the caller to instantiate it.  Only do
7792                    // this if the provider is the same user as the caller's
7793                    // process, or can run as root (so can be in any process).
7794                    return cpr.newHolder(null);
7795                }
7796
7797                if (DEBUG_PROVIDER) {
7798                    RuntimeException e = new RuntimeException("here");
7799                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
7800                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
7801                }
7802
7803                // This is single process, and our app is now connecting to it.
7804                // See if we are already in the process of launching this
7805                // provider.
7806                final int N = mLaunchingProviders.size();
7807                int i;
7808                for (i=0; i<N; i++) {
7809                    if (mLaunchingProviders.get(i) == cpr) {
7810                        break;
7811                    }
7812                }
7813
7814                // If the provider is not already being launched, then get it
7815                // started.
7816                if (i >= N) {
7817                    final long origId = Binder.clearCallingIdentity();
7818
7819                    try {
7820                        // Content provider is now in use, its package can't be stopped.
7821                        try {
7822                            AppGlobals.getPackageManager().setPackageStoppedState(
7823                                    cpr.appInfo.packageName, false, userId);
7824                        } catch (RemoteException e) {
7825                        } catch (IllegalArgumentException e) {
7826                            Slog.w(TAG, "Failed trying to unstop package "
7827                                    + cpr.appInfo.packageName + ": " + e);
7828                        }
7829
7830                        // Use existing process if already started
7831                        ProcessRecord proc = getProcessRecordLocked(
7832                                cpi.processName, cpr.appInfo.uid, false);
7833                        if (proc != null && proc.thread != null) {
7834                            if (DEBUG_PROVIDER) {
7835                                Slog.d(TAG, "Installing in existing process " + proc);
7836                            }
7837                            proc.pubProviders.put(cpi.name, cpr);
7838                            try {
7839                                proc.thread.scheduleInstallProvider(cpi);
7840                            } catch (RemoteException e) {
7841                            }
7842                        } else {
7843                            proc = startProcessLocked(cpi.processName,
7844                                    cpr.appInfo, false, 0, "content provider",
7845                                    new ComponentName(cpi.applicationInfo.packageName,
7846                                            cpi.name), false, false, false);
7847                            if (proc == null) {
7848                                Slog.w(TAG, "Unable to launch app "
7849                                        + cpi.applicationInfo.packageName + "/"
7850                                        + cpi.applicationInfo.uid + " for provider "
7851                                        + name + ": process is bad");
7852                                return null;
7853                            }
7854                        }
7855                        cpr.launchingApp = proc;
7856                        mLaunchingProviders.add(cpr);
7857                    } finally {
7858                        Binder.restoreCallingIdentity(origId);
7859                    }
7860                }
7861
7862                // Make sure the provider is published (the same provider class
7863                // may be published under multiple names).
7864                if (firstClass) {
7865                    mProviderMap.putProviderByClass(comp, cpr);
7866                }
7867
7868                mProviderMap.putProviderByName(name, cpr);
7869                conn = incProviderCountLocked(r, cpr, token, stable);
7870                if (conn != null) {
7871                    conn.waiting = true;
7872                }
7873            }
7874        }
7875
7876        // Wait for the provider to be published...
7877        synchronized (cpr) {
7878            while (cpr.provider == null) {
7879                if (cpr.launchingApp == null) {
7880                    Slog.w(TAG, "Unable to launch app "
7881                            + cpi.applicationInfo.packageName + "/"
7882                            + cpi.applicationInfo.uid + " for provider "
7883                            + name + ": launching app became null");
7884                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
7885                            UserHandle.getUserId(cpi.applicationInfo.uid),
7886                            cpi.applicationInfo.packageName,
7887                            cpi.applicationInfo.uid, name);
7888                    return null;
7889                }
7890                try {
7891                    if (DEBUG_MU) {
7892                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
7893                                + cpr.launchingApp);
7894                    }
7895                    if (conn != null) {
7896                        conn.waiting = true;
7897                    }
7898                    cpr.wait();
7899                } catch (InterruptedException ex) {
7900                } finally {
7901                    if (conn != null) {
7902                        conn.waiting = false;
7903                    }
7904                }
7905            }
7906        }
7907        return cpr != null ? cpr.newHolder(conn) : null;
7908    }
7909
7910    public final ContentProviderHolder getContentProvider(
7911            IApplicationThread caller, String name, int userId, boolean stable) {
7912        enforceNotIsolatedCaller("getContentProvider");
7913        if (caller == null) {
7914            String msg = "null IApplicationThread when getting content provider "
7915                    + name;
7916            Slog.w(TAG, msg);
7917            throw new SecurityException(msg);
7918        }
7919
7920        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7921                false, true, "getContentProvider", null);
7922        return getContentProviderImpl(caller, name, null, stable, userId);
7923    }
7924
7925    public ContentProviderHolder getContentProviderExternal(
7926            String name, int userId, IBinder token) {
7927        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7928            "Do not have permission in call getContentProviderExternal()");
7929        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7930                false, true, "getContentProvider", null);
7931        return getContentProviderExternalUnchecked(name, token, userId);
7932    }
7933
7934    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
7935            IBinder token, int userId) {
7936        return getContentProviderImpl(null, name, token, true, userId);
7937    }
7938
7939    /**
7940     * Drop a content provider from a ProcessRecord's bookkeeping
7941     */
7942    public void removeContentProvider(IBinder connection, boolean stable) {
7943        enforceNotIsolatedCaller("removeContentProvider");
7944        long ident = Binder.clearCallingIdentity();
7945        try {
7946            synchronized (this) {
7947                ContentProviderConnection conn;
7948                try {
7949                    conn = (ContentProviderConnection)connection;
7950                } catch (ClassCastException e) {
7951                    String msg ="removeContentProvider: " + connection
7952                            + " not a ContentProviderConnection";
7953                    Slog.w(TAG, msg);
7954                    throw new IllegalArgumentException(msg);
7955                }
7956                if (conn == null) {
7957                    throw new NullPointerException("connection is null");
7958                }
7959                if (decProviderCountLocked(conn, null, null, stable)) {
7960                    updateOomAdjLocked();
7961                }
7962            }
7963        } finally {
7964            Binder.restoreCallingIdentity(ident);
7965        }
7966    }
7967
7968    public void removeContentProviderExternal(String name, IBinder token) {
7969        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7970            "Do not have permission in call removeContentProviderExternal()");
7971        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
7972    }
7973
7974    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
7975        synchronized (this) {
7976            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
7977            if(cpr == null) {
7978                //remove from mProvidersByClass
7979                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
7980                return;
7981            }
7982
7983            //update content provider record entry info
7984            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
7985            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
7986            if (localCpr.hasExternalProcessHandles()) {
7987                if (localCpr.removeExternalProcessHandleLocked(token)) {
7988                    updateOomAdjLocked();
7989                } else {
7990                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
7991                            + " with no external reference for token: "
7992                            + token + ".");
7993                }
7994            } else {
7995                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
7996                        + " with no external references.");
7997            }
7998        }
7999    }
8000
8001    public final void publishContentProviders(IApplicationThread caller,
8002            List<ContentProviderHolder> providers) {
8003        if (providers == null) {
8004            return;
8005        }
8006
8007        enforceNotIsolatedCaller("publishContentProviders");
8008        synchronized (this) {
8009            final ProcessRecord r = getRecordForAppLocked(caller);
8010            if (DEBUG_MU)
8011                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8012            if (r == null) {
8013                throw new SecurityException(
8014                        "Unable to find app for caller " + caller
8015                      + " (pid=" + Binder.getCallingPid()
8016                      + ") when publishing content providers");
8017            }
8018
8019            final long origId = Binder.clearCallingIdentity();
8020
8021            final int N = providers.size();
8022            for (int i=0; i<N; i++) {
8023                ContentProviderHolder src = providers.get(i);
8024                if (src == null || src.info == null || src.provider == null) {
8025                    continue;
8026                }
8027                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8028                if (DEBUG_MU)
8029                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8030                if (dst != null) {
8031                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8032                    mProviderMap.putProviderByClass(comp, dst);
8033                    String names[] = dst.info.authority.split(";");
8034                    for (int j = 0; j < names.length; j++) {
8035                        mProviderMap.putProviderByName(names[j], dst);
8036                    }
8037
8038                    int NL = mLaunchingProviders.size();
8039                    int j;
8040                    for (j=0; j<NL; j++) {
8041                        if (mLaunchingProviders.get(j) == dst) {
8042                            mLaunchingProviders.remove(j);
8043                            j--;
8044                            NL--;
8045                        }
8046                    }
8047                    synchronized (dst) {
8048                        dst.provider = src.provider;
8049                        dst.proc = r;
8050                        dst.notifyAll();
8051                    }
8052                    updateOomAdjLocked(r);
8053                }
8054            }
8055
8056            Binder.restoreCallingIdentity(origId);
8057        }
8058    }
8059
8060    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8061        ContentProviderConnection conn;
8062        try {
8063            conn = (ContentProviderConnection)connection;
8064        } catch (ClassCastException e) {
8065            String msg ="refContentProvider: " + connection
8066                    + " not a ContentProviderConnection";
8067            Slog.w(TAG, msg);
8068            throw new IllegalArgumentException(msg);
8069        }
8070        if (conn == null) {
8071            throw new NullPointerException("connection is null");
8072        }
8073
8074        synchronized (this) {
8075            if (stable > 0) {
8076                conn.numStableIncs += stable;
8077            }
8078            stable = conn.stableCount + stable;
8079            if (stable < 0) {
8080                throw new IllegalStateException("stableCount < 0: " + stable);
8081            }
8082
8083            if (unstable > 0) {
8084                conn.numUnstableIncs += unstable;
8085            }
8086            unstable = conn.unstableCount + unstable;
8087            if (unstable < 0) {
8088                throw new IllegalStateException("unstableCount < 0: " + unstable);
8089            }
8090
8091            if ((stable+unstable) <= 0) {
8092                throw new IllegalStateException("ref counts can't go to zero here: stable="
8093                        + stable + " unstable=" + unstable);
8094            }
8095            conn.stableCount = stable;
8096            conn.unstableCount = unstable;
8097            return !conn.dead;
8098        }
8099    }
8100
8101    public void unstableProviderDied(IBinder connection) {
8102        ContentProviderConnection conn;
8103        try {
8104            conn = (ContentProviderConnection)connection;
8105        } catch (ClassCastException e) {
8106            String msg ="refContentProvider: " + connection
8107                    + " not a ContentProviderConnection";
8108            Slog.w(TAG, msg);
8109            throw new IllegalArgumentException(msg);
8110        }
8111        if (conn == null) {
8112            throw new NullPointerException("connection is null");
8113        }
8114
8115        // Safely retrieve the content provider associated with the connection.
8116        IContentProvider provider;
8117        synchronized (this) {
8118            provider = conn.provider.provider;
8119        }
8120
8121        if (provider == null) {
8122            // Um, yeah, we're way ahead of you.
8123            return;
8124        }
8125
8126        // Make sure the caller is being honest with us.
8127        if (provider.asBinder().pingBinder()) {
8128            // Er, no, still looks good to us.
8129            synchronized (this) {
8130                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8131                        + " says " + conn + " died, but we don't agree");
8132                return;
8133            }
8134        }
8135
8136        // Well look at that!  It's dead!
8137        synchronized (this) {
8138            if (conn.provider.provider != provider) {
8139                // But something changed...  good enough.
8140                return;
8141            }
8142
8143            ProcessRecord proc = conn.provider.proc;
8144            if (proc == null || proc.thread == null) {
8145                // Seems like the process is already cleaned up.
8146                return;
8147            }
8148
8149            // As far as we're concerned, this is just like receiving a
8150            // death notification...  just a bit prematurely.
8151            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8152                    + ") early provider death");
8153            final long ident = Binder.clearCallingIdentity();
8154            try {
8155                appDiedLocked(proc, proc.pid, proc.thread);
8156            } finally {
8157                Binder.restoreCallingIdentity(ident);
8158            }
8159        }
8160    }
8161
8162    @Override
8163    public void appNotRespondingViaProvider(IBinder connection) {
8164        enforceCallingPermission(
8165                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8166
8167        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8168        if (conn == null) {
8169            Slog.w(TAG, "ContentProviderConnection is null");
8170            return;
8171        }
8172
8173        final ProcessRecord host = conn.provider.proc;
8174        if (host == null) {
8175            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8176            return;
8177        }
8178
8179        final long token = Binder.clearCallingIdentity();
8180        try {
8181            appNotResponding(host, null, null, false, "ContentProvider not responding");
8182        } finally {
8183            Binder.restoreCallingIdentity(token);
8184        }
8185    }
8186
8187    public final void installSystemProviders() {
8188        List<ProviderInfo> providers;
8189        synchronized (this) {
8190            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8191            providers = generateApplicationProvidersLocked(app);
8192            if (providers != null) {
8193                for (int i=providers.size()-1; i>=0; i--) {
8194                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8195                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8196                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8197                                + ": not system .apk");
8198                        providers.remove(i);
8199                    }
8200                }
8201            }
8202        }
8203        if (providers != null) {
8204            mSystemThread.installSystemProviders(providers);
8205        }
8206
8207        mCoreSettingsObserver = new CoreSettingsObserver(this);
8208
8209        mUsageStatsService.monitorPackages();
8210    }
8211
8212    /**
8213     * Allows app to retrieve the MIME type of a URI without having permission
8214     * to access its content provider.
8215     *
8216     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8217     *
8218     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8219     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8220     */
8221    public String getProviderMimeType(Uri uri, int userId) {
8222        enforceNotIsolatedCaller("getProviderMimeType");
8223        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8224                userId, false, true, "getProviderMimeType", null);
8225        final String name = uri.getAuthority();
8226        final long ident = Binder.clearCallingIdentity();
8227        ContentProviderHolder holder = null;
8228
8229        try {
8230            holder = getContentProviderExternalUnchecked(name, null, userId);
8231            if (holder != null) {
8232                return holder.provider.getType(uri);
8233            }
8234        } catch (RemoteException e) {
8235            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8236            return null;
8237        } finally {
8238            if (holder != null) {
8239                removeContentProviderExternalUnchecked(name, null, userId);
8240            }
8241            Binder.restoreCallingIdentity(ident);
8242        }
8243
8244        return null;
8245    }
8246
8247    // =========================================================
8248    // GLOBAL MANAGEMENT
8249    // =========================================================
8250
8251    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8252            boolean isolated) {
8253        String proc = customProcess != null ? customProcess : info.processName;
8254        BatteryStatsImpl.Uid.Proc ps = null;
8255        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8256        int uid = info.uid;
8257        if (isolated) {
8258            int userId = UserHandle.getUserId(uid);
8259            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8260            while (true) {
8261                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8262                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8263                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8264                }
8265                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8266                mNextIsolatedProcessUid++;
8267                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8268                    // No process for this uid, use it.
8269                    break;
8270                }
8271                stepsLeft--;
8272                if (stepsLeft <= 0) {
8273                    return null;
8274                }
8275            }
8276        }
8277        return new ProcessRecord(stats, info, proc, uid);
8278    }
8279
8280    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8281        ProcessRecord app;
8282        if (!isolated) {
8283            app = getProcessRecordLocked(info.processName, info.uid, true);
8284        } else {
8285            app = null;
8286        }
8287
8288        if (app == null) {
8289            app = newProcessRecordLocked(info, null, isolated);
8290            mProcessNames.put(info.processName, app.uid, app);
8291            if (isolated) {
8292                mIsolatedProcesses.put(app.uid, app);
8293            }
8294            updateLruProcessLocked(app, false, null);
8295            updateOomAdjLocked();
8296        }
8297
8298        // This package really, really can not be stopped.
8299        try {
8300            AppGlobals.getPackageManager().setPackageStoppedState(
8301                    info.packageName, false, UserHandle.getUserId(app.uid));
8302        } catch (RemoteException e) {
8303        } catch (IllegalArgumentException e) {
8304            Slog.w(TAG, "Failed trying to unstop package "
8305                    + info.packageName + ": " + e);
8306        }
8307
8308        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8309                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8310            app.persistent = true;
8311            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8312        }
8313        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8314            mPersistentStartingProcesses.add(app);
8315            startProcessLocked(app, "added application", app.processName);
8316        }
8317
8318        return app;
8319    }
8320
8321    public void unhandledBack() {
8322        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8323                "unhandledBack()");
8324
8325        synchronized(this) {
8326            final long origId = Binder.clearCallingIdentity();
8327            try {
8328                getFocusedStack().unhandledBackLocked();
8329            } finally {
8330                Binder.restoreCallingIdentity(origId);
8331            }
8332        }
8333    }
8334
8335    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8336        enforceNotIsolatedCaller("openContentUri");
8337        final int userId = UserHandle.getCallingUserId();
8338        String name = uri.getAuthority();
8339        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8340        ParcelFileDescriptor pfd = null;
8341        if (cph != null) {
8342            // We record the binder invoker's uid in thread-local storage before
8343            // going to the content provider to open the file.  Later, in the code
8344            // that handles all permissions checks, we look for this uid and use
8345            // that rather than the Activity Manager's own uid.  The effect is that
8346            // we do the check against the caller's permissions even though it looks
8347            // to the content provider like the Activity Manager itself is making
8348            // the request.
8349            sCallerIdentity.set(new Identity(
8350                    Binder.getCallingPid(), Binder.getCallingUid()));
8351            try {
8352                pfd = cph.provider.openFile(null, uri, "r", null);
8353            } catch (FileNotFoundException e) {
8354                // do nothing; pfd will be returned null
8355            } finally {
8356                // Ensure that whatever happens, we clean up the identity state
8357                sCallerIdentity.remove();
8358            }
8359
8360            // We've got the fd now, so we're done with the provider.
8361            removeContentProviderExternalUnchecked(name, null, userId);
8362        } else {
8363            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8364        }
8365        return pfd;
8366    }
8367
8368    // Actually is sleeping or shutting down or whatever else in the future
8369    // is an inactive state.
8370    public boolean isSleepingOrShuttingDown() {
8371        return mSleeping || mShuttingDown;
8372    }
8373
8374    public void goingToSleep() {
8375        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8376                != PackageManager.PERMISSION_GRANTED) {
8377            throw new SecurityException("Requires permission "
8378                    + android.Manifest.permission.DEVICE_POWER);
8379        }
8380
8381        synchronized(this) {
8382            mWentToSleep = true;
8383            updateEventDispatchingLocked();
8384
8385            if (!mSleeping) {
8386                mSleeping = true;
8387                mStackSupervisor.goingToSleepLocked();
8388
8389                // Initialize the wake times of all processes.
8390                checkExcessivePowerUsageLocked(false);
8391                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8392                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8393                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8394            }
8395        }
8396    }
8397
8398    @Override
8399    public boolean shutdown(int timeout) {
8400        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8401                != PackageManager.PERMISSION_GRANTED) {
8402            throw new SecurityException("Requires permission "
8403                    + android.Manifest.permission.SHUTDOWN);
8404        }
8405
8406        boolean timedout = false;
8407
8408        synchronized(this) {
8409            mShuttingDown = true;
8410            updateEventDispatchingLocked();
8411            timedout = mStackSupervisor.shutdownLocked(timeout);
8412        }
8413
8414        mAppOpsService.shutdown();
8415        mUsageStatsService.shutdown();
8416        mBatteryStatsService.shutdown();
8417        synchronized (this) {
8418            mProcessStats.shutdownLocked();
8419        }
8420
8421        return timedout;
8422    }
8423
8424    public final void activitySlept(IBinder token) {
8425        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8426
8427        final long origId = Binder.clearCallingIdentity();
8428
8429        synchronized (this) {
8430            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8431            if (r != null) {
8432                mStackSupervisor.activitySleptLocked(r);
8433            }
8434        }
8435
8436        Binder.restoreCallingIdentity(origId);
8437    }
8438
8439    void logLockScreen(String msg) {
8440        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8441                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8442                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8443                mStackSupervisor.mDismissKeyguardOnNextActivity);
8444    }
8445
8446    private void comeOutOfSleepIfNeededLocked() {
8447        if (!mWentToSleep && !mLockScreenShown) {
8448            if (mSleeping) {
8449                mSleeping = false;
8450                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8451            }
8452        }
8453    }
8454
8455    public void wakingUp() {
8456        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8457                != PackageManager.PERMISSION_GRANTED) {
8458            throw new SecurityException("Requires permission "
8459                    + android.Manifest.permission.DEVICE_POWER);
8460        }
8461
8462        synchronized(this) {
8463            mWentToSleep = false;
8464            updateEventDispatchingLocked();
8465            comeOutOfSleepIfNeededLocked();
8466        }
8467    }
8468
8469    private void updateEventDispatchingLocked() {
8470        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8471    }
8472
8473    public void setLockScreenShown(boolean shown) {
8474        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8475                != PackageManager.PERMISSION_GRANTED) {
8476            throw new SecurityException("Requires permission "
8477                    + android.Manifest.permission.DEVICE_POWER);
8478        }
8479
8480        synchronized(this) {
8481            long ident = Binder.clearCallingIdentity();
8482            try {
8483                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8484                mLockScreenShown = shown;
8485                comeOutOfSleepIfNeededLocked();
8486            } finally {
8487                Binder.restoreCallingIdentity(ident);
8488            }
8489        }
8490    }
8491
8492    public void stopAppSwitches() {
8493        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8494                != PackageManager.PERMISSION_GRANTED) {
8495            throw new SecurityException("Requires permission "
8496                    + android.Manifest.permission.STOP_APP_SWITCHES);
8497        }
8498
8499        synchronized(this) {
8500            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8501                    + APP_SWITCH_DELAY_TIME;
8502            mDidAppSwitch = false;
8503            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8504            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8505            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8506        }
8507    }
8508
8509    public void resumeAppSwitches() {
8510        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8511                != PackageManager.PERMISSION_GRANTED) {
8512            throw new SecurityException("Requires permission "
8513                    + android.Manifest.permission.STOP_APP_SWITCHES);
8514        }
8515
8516        synchronized(this) {
8517            // Note that we don't execute any pending app switches... we will
8518            // let those wait until either the timeout, or the next start
8519            // activity request.
8520            mAppSwitchesAllowedTime = 0;
8521        }
8522    }
8523
8524    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8525            String name) {
8526        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8527            return true;
8528        }
8529
8530        final int perm = checkComponentPermission(
8531                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8532                callingUid, -1, true);
8533        if (perm == PackageManager.PERMISSION_GRANTED) {
8534            return true;
8535        }
8536
8537        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8538        return false;
8539    }
8540
8541    public void setDebugApp(String packageName, boolean waitForDebugger,
8542            boolean persistent) {
8543        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8544                "setDebugApp()");
8545
8546        long ident = Binder.clearCallingIdentity();
8547        try {
8548            // Note that this is not really thread safe if there are multiple
8549            // callers into it at the same time, but that's not a situation we
8550            // care about.
8551            if (persistent) {
8552                final ContentResolver resolver = mContext.getContentResolver();
8553                Settings.Global.putString(
8554                    resolver, Settings.Global.DEBUG_APP,
8555                    packageName);
8556                Settings.Global.putInt(
8557                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8558                    waitForDebugger ? 1 : 0);
8559            }
8560
8561            synchronized (this) {
8562                if (!persistent) {
8563                    mOrigDebugApp = mDebugApp;
8564                    mOrigWaitForDebugger = mWaitForDebugger;
8565                }
8566                mDebugApp = packageName;
8567                mWaitForDebugger = waitForDebugger;
8568                mDebugTransient = !persistent;
8569                if (packageName != null) {
8570                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8571                            false, UserHandle.USER_ALL, "set debug app");
8572                }
8573            }
8574        } finally {
8575            Binder.restoreCallingIdentity(ident);
8576        }
8577    }
8578
8579    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8580        synchronized (this) {
8581            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8582            if (!isDebuggable) {
8583                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8584                    throw new SecurityException("Process not debuggable: " + app.packageName);
8585                }
8586            }
8587
8588            mOpenGlTraceApp = processName;
8589        }
8590    }
8591
8592    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8593            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8594        synchronized (this) {
8595            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8596            if (!isDebuggable) {
8597                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8598                    throw new SecurityException("Process not debuggable: " + app.packageName);
8599                }
8600            }
8601            mProfileApp = processName;
8602            mProfileFile = profileFile;
8603            if (mProfileFd != null) {
8604                try {
8605                    mProfileFd.close();
8606                } catch (IOException e) {
8607                }
8608                mProfileFd = null;
8609            }
8610            mProfileFd = profileFd;
8611            mProfileType = 0;
8612            mAutoStopProfiler = autoStopProfiler;
8613        }
8614    }
8615
8616    @Override
8617    public void setAlwaysFinish(boolean enabled) {
8618        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8619                "setAlwaysFinish()");
8620
8621        Settings.Global.putInt(
8622                mContext.getContentResolver(),
8623                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8624
8625        synchronized (this) {
8626            mAlwaysFinishActivities = enabled;
8627        }
8628    }
8629
8630    @Override
8631    public void setActivityController(IActivityController controller) {
8632        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8633                "setActivityController()");
8634        synchronized (this) {
8635            mController = controller;
8636            Watchdog.getInstance().setActivityController(controller);
8637        }
8638    }
8639
8640    @Override
8641    public void setUserIsMonkey(boolean userIsMonkey) {
8642        synchronized (this) {
8643            synchronized (mPidsSelfLocked) {
8644                final int callingPid = Binder.getCallingPid();
8645                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8646                if (precessRecord == null) {
8647                    throw new SecurityException("Unknown process: " + callingPid);
8648                }
8649                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8650                    throw new SecurityException("Only an instrumentation process "
8651                            + "with a UiAutomation can call setUserIsMonkey");
8652                }
8653            }
8654            mUserIsMonkey = userIsMonkey;
8655        }
8656    }
8657
8658    @Override
8659    public boolean isUserAMonkey() {
8660        synchronized (this) {
8661            // If there is a controller also implies the user is a monkey.
8662            return (mUserIsMonkey || mController != null);
8663        }
8664    }
8665
8666    public void requestBugReport() {
8667        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8668        SystemProperties.set("ctl.start", "bugreport");
8669    }
8670
8671    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8672        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8673    }
8674
8675    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8676        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8677            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8678        }
8679        return KEY_DISPATCHING_TIMEOUT;
8680    }
8681
8682    @Override
8683    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8684        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8685                != PackageManager.PERMISSION_GRANTED) {
8686            throw new SecurityException("Requires permission "
8687                    + android.Manifest.permission.FILTER_EVENTS);
8688        }
8689        ProcessRecord proc;
8690        long timeout;
8691        synchronized (this) {
8692            synchronized (mPidsSelfLocked) {
8693                proc = mPidsSelfLocked.get(pid);
8694            }
8695            timeout = getInputDispatchingTimeoutLocked(proc);
8696        }
8697
8698        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8699            return -1;
8700        }
8701
8702        return timeout;
8703    }
8704
8705    /**
8706     * Handle input dispatching timeouts.
8707     * Returns whether input dispatching should be aborted or not.
8708     */
8709    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8710            final ActivityRecord activity, final ActivityRecord parent,
8711            final boolean aboveSystem, String reason) {
8712        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8713                != PackageManager.PERMISSION_GRANTED) {
8714            throw new SecurityException("Requires permission "
8715                    + android.Manifest.permission.FILTER_EVENTS);
8716        }
8717
8718        final String annotation;
8719        if (reason == null) {
8720            annotation = "Input dispatching timed out";
8721        } else {
8722            annotation = "Input dispatching timed out (" + reason + ")";
8723        }
8724
8725        if (proc != null) {
8726            synchronized (this) {
8727                if (proc.debugging) {
8728                    return false;
8729                }
8730
8731                if (mDidDexOpt) {
8732                    // Give more time since we were dexopting.
8733                    mDidDexOpt = false;
8734                    return false;
8735                }
8736
8737                if (proc.instrumentationClass != null) {
8738                    Bundle info = new Bundle();
8739                    info.putString("shortMsg", "keyDispatchingTimedOut");
8740                    info.putString("longMsg", annotation);
8741                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8742                    return true;
8743                }
8744            }
8745            mHandler.post(new Runnable() {
8746                @Override
8747                public void run() {
8748                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
8749                }
8750            });
8751        }
8752
8753        return true;
8754    }
8755
8756    public Bundle getAssistContextExtras(int requestType) {
8757        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
8758                "getAssistContextExtras()");
8759        PendingAssistExtras pae;
8760        Bundle extras = new Bundle();
8761        synchronized (this) {
8762            ActivityRecord activity = getFocusedStack().mResumedActivity;
8763            if (activity == null) {
8764                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
8765                return null;
8766            }
8767            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
8768            if (activity.app == null || activity.app.thread == null) {
8769                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
8770                return extras;
8771            }
8772            if (activity.app.pid == Binder.getCallingPid()) {
8773                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
8774                return extras;
8775            }
8776            pae = new PendingAssistExtras(activity);
8777            try {
8778                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
8779                        requestType);
8780                mPendingAssistExtras.add(pae);
8781                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
8782            } catch (RemoteException e) {
8783                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
8784                return extras;
8785            }
8786        }
8787        synchronized (pae) {
8788            while (!pae.haveResult) {
8789                try {
8790                    pae.wait();
8791                } catch (InterruptedException e) {
8792                }
8793            }
8794            if (pae.result != null) {
8795                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
8796            }
8797        }
8798        synchronized (this) {
8799            mPendingAssistExtras.remove(pae);
8800            mHandler.removeCallbacks(pae);
8801        }
8802        return extras;
8803    }
8804
8805    public void reportAssistContextExtras(IBinder token, Bundle extras) {
8806        PendingAssistExtras pae = (PendingAssistExtras)token;
8807        synchronized (pae) {
8808            pae.result = extras;
8809            pae.haveResult = true;
8810            pae.notifyAll();
8811        }
8812    }
8813
8814    public void registerProcessObserver(IProcessObserver observer) {
8815        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8816                "registerProcessObserver()");
8817        synchronized (this) {
8818            mProcessObservers.register(observer);
8819        }
8820    }
8821
8822    @Override
8823    public void unregisterProcessObserver(IProcessObserver observer) {
8824        synchronized (this) {
8825            mProcessObservers.unregister(observer);
8826        }
8827    }
8828
8829    @Override
8830    public boolean convertFromTranslucent(IBinder token) {
8831        final long origId = Binder.clearCallingIdentity();
8832        try {
8833            synchronized (this) {
8834                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8835                if (r == null) {
8836                    return false;
8837                }
8838                if (r.changeWindowTranslucency(true)) {
8839                    mWindowManager.setAppFullscreen(token, true);
8840                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8841                    return true;
8842                }
8843                return false;
8844            }
8845        } finally {
8846            Binder.restoreCallingIdentity(origId);
8847        }
8848    }
8849
8850    @Override
8851    public boolean convertToTranslucent(IBinder token) {
8852        final long origId = Binder.clearCallingIdentity();
8853        try {
8854            synchronized (this) {
8855                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8856                if (r == null) {
8857                    return false;
8858                }
8859                if (r.changeWindowTranslucency(false)) {
8860                    r.task.stack.convertToTranslucent(r);
8861                    mWindowManager.setAppFullscreen(token, false);
8862                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8863                    return true;
8864                }
8865                return false;
8866            }
8867        } finally {
8868            Binder.restoreCallingIdentity(origId);
8869        }
8870    }
8871
8872    @Override
8873    public void setImmersive(IBinder token, boolean immersive) {
8874        synchronized(this) {
8875            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8876            if (r == null) {
8877                throw new IllegalArgumentException();
8878            }
8879            r.immersive = immersive;
8880
8881            // update associated state if we're frontmost
8882            if (r == mFocusedActivity) {
8883                if (DEBUG_IMMERSIVE) {
8884                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
8885                }
8886                applyUpdateLockStateLocked(r);
8887            }
8888        }
8889    }
8890
8891    @Override
8892    public boolean isImmersive(IBinder token) {
8893        synchronized (this) {
8894            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8895            if (r == null) {
8896                throw new IllegalArgumentException();
8897            }
8898            return r.immersive;
8899        }
8900    }
8901
8902    public boolean isTopActivityImmersive() {
8903        enforceNotIsolatedCaller("startActivity");
8904        synchronized (this) {
8905            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
8906            return (r != null) ? r.immersive : false;
8907        }
8908    }
8909
8910    public final void enterSafeMode() {
8911        synchronized(this) {
8912            // It only makes sense to do this before the system is ready
8913            // and started launching other packages.
8914            if (!mSystemReady) {
8915                try {
8916                    AppGlobals.getPackageManager().enterSafeMode();
8917                } catch (RemoteException e) {
8918                }
8919            }
8920        }
8921    }
8922
8923    public final void showSafeModeOverlay() {
8924        View v = LayoutInflater.from(mContext).inflate(
8925                com.android.internal.R.layout.safe_mode, null);
8926        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
8927        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
8928        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
8929        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
8930        lp.gravity = Gravity.BOTTOM | Gravity.START;
8931        lp.format = v.getBackground().getOpacity();
8932        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
8933                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
8934        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
8935        ((WindowManager)mContext.getSystemService(
8936                Context.WINDOW_SERVICE)).addView(v, lp);
8937    }
8938
8939    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
8940        if (!(sender instanceof PendingIntentRecord)) {
8941            return;
8942        }
8943        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8944        synchronized (stats) {
8945            if (mBatteryStatsService.isOnBattery()) {
8946                mBatteryStatsService.enforceCallingPermission();
8947                PendingIntentRecord rec = (PendingIntentRecord)sender;
8948                int MY_UID = Binder.getCallingUid();
8949                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
8950                BatteryStatsImpl.Uid.Pkg pkg =
8951                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
8952                            sourcePkg != null ? sourcePkg : rec.key.packageName);
8953                pkg.incWakeupsLocked();
8954            }
8955        }
8956    }
8957
8958    public boolean killPids(int[] pids, String pReason, boolean secure) {
8959        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8960            throw new SecurityException("killPids only available to the system");
8961        }
8962        String reason = (pReason == null) ? "Unknown" : pReason;
8963        // XXX Note: don't acquire main activity lock here, because the window
8964        // manager calls in with its locks held.
8965
8966        boolean killed = false;
8967        synchronized (mPidsSelfLocked) {
8968            int[] types = new int[pids.length];
8969            int worstType = 0;
8970            for (int i=0; i<pids.length; i++) {
8971                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8972                if (proc != null) {
8973                    int type = proc.setAdj;
8974                    types[i] = type;
8975                    if (type > worstType) {
8976                        worstType = type;
8977                    }
8978                }
8979            }
8980
8981            // If the worst oom_adj is somewhere in the cached proc LRU range,
8982            // then constrain it so we will kill all cached procs.
8983            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
8984                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
8985                worstType = ProcessList.CACHED_APP_MIN_ADJ;
8986            }
8987
8988            // If this is not a secure call, don't let it kill processes that
8989            // are important.
8990            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
8991                worstType = ProcessList.SERVICE_ADJ;
8992            }
8993
8994            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
8995            for (int i=0; i<pids.length; i++) {
8996                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8997                if (proc == null) {
8998                    continue;
8999                }
9000                int adj = proc.setAdj;
9001                if (adj >= worstType && !proc.killedByAm) {
9002                    killUnneededProcessLocked(proc, reason);
9003                    killed = true;
9004                }
9005            }
9006        }
9007        return killed;
9008    }
9009
9010    @Override
9011    public void killUid(int uid, String reason) {
9012        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9013            throw new SecurityException("killUid only available to the system");
9014        }
9015        synchronized (this) {
9016            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9017                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9018                    reason != null ? reason : "kill uid");
9019        }
9020    }
9021
9022    @Override
9023    public boolean killProcessesBelowForeground(String reason) {
9024        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9025            throw new SecurityException("killProcessesBelowForeground() only available to system");
9026        }
9027
9028        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9029    }
9030
9031    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9032        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9033            throw new SecurityException("killProcessesBelowAdj() only available to system");
9034        }
9035
9036        boolean killed = false;
9037        synchronized (mPidsSelfLocked) {
9038            final int size = mPidsSelfLocked.size();
9039            for (int i = 0; i < size; i++) {
9040                final int pid = mPidsSelfLocked.keyAt(i);
9041                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9042                if (proc == null) continue;
9043
9044                final int adj = proc.setAdj;
9045                if (adj > belowAdj && !proc.killedByAm) {
9046                    killUnneededProcessLocked(proc, reason);
9047                    killed = true;
9048                }
9049            }
9050        }
9051        return killed;
9052    }
9053
9054    @Override
9055    public void hang(final IBinder who, boolean allowRestart) {
9056        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9057                != PackageManager.PERMISSION_GRANTED) {
9058            throw new SecurityException("Requires permission "
9059                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9060        }
9061
9062        final IBinder.DeathRecipient death = new DeathRecipient() {
9063            @Override
9064            public void binderDied() {
9065                synchronized (this) {
9066                    notifyAll();
9067                }
9068            }
9069        };
9070
9071        try {
9072            who.linkToDeath(death, 0);
9073        } catch (RemoteException e) {
9074            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9075            return;
9076        }
9077
9078        synchronized (this) {
9079            Watchdog.getInstance().setAllowRestart(allowRestart);
9080            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9081            synchronized (death) {
9082                while (who.isBinderAlive()) {
9083                    try {
9084                        death.wait();
9085                    } catch (InterruptedException e) {
9086                    }
9087                }
9088            }
9089            Watchdog.getInstance().setAllowRestart(true);
9090        }
9091    }
9092
9093    @Override
9094    public void restart() {
9095        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9096                != PackageManager.PERMISSION_GRANTED) {
9097            throw new SecurityException("Requires permission "
9098                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9099        }
9100
9101        Log.i(TAG, "Sending shutdown broadcast...");
9102
9103        BroadcastReceiver br = new BroadcastReceiver() {
9104            @Override public void onReceive(Context context, Intent intent) {
9105                // Now the broadcast is done, finish up the low-level shutdown.
9106                Log.i(TAG, "Shutting down activity manager...");
9107                shutdown(10000);
9108                Log.i(TAG, "Shutdown complete, restarting!");
9109                Process.killProcess(Process.myPid());
9110                System.exit(10);
9111            }
9112        };
9113
9114        // First send the high-level shut down broadcast.
9115        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9116        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9117        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9118        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9119        mContext.sendOrderedBroadcastAsUser(intent,
9120                UserHandle.ALL, null, br, mHandler, 0, null, null);
9121        */
9122        br.onReceive(mContext, intent);
9123    }
9124
9125    private long getLowRamTimeSinceIdle(long now) {
9126        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9127    }
9128
9129    @Override
9130    public void performIdleMaintenance() {
9131        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9132                != PackageManager.PERMISSION_GRANTED) {
9133            throw new SecurityException("Requires permission "
9134                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9135        }
9136
9137        synchronized (this) {
9138            final long now = SystemClock.uptimeMillis();
9139            final long timeSinceLastIdle = now - mLastIdleTime;
9140            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9141            mLastIdleTime = now;
9142            mLowRamTimeSinceLastIdle = 0;
9143            if (mLowRamStartTime != 0) {
9144                mLowRamStartTime = now;
9145            }
9146
9147            StringBuilder sb = new StringBuilder(128);
9148            sb.append("Idle maintenance over ");
9149            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9150            sb.append(" low RAM for ");
9151            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9152            Slog.i(TAG, sb.toString());
9153
9154            // If at least 1/3 of our time since the last idle period has been spent
9155            // with RAM low, then we want to kill processes.
9156            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9157
9158            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9159                ProcessRecord proc = mLruProcesses.get(i);
9160                if (proc.notCachedSinceIdle) {
9161                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9162                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9163                        if (doKilling && proc.initialIdlePss != 0
9164                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9165                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9166                                    + " from " + proc.initialIdlePss + ")");
9167                        }
9168                    }
9169                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9170                    proc.notCachedSinceIdle = true;
9171                    proc.initialIdlePss = 0;
9172                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9173                            mSleeping, now);
9174                }
9175            }
9176
9177            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9178            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9179        }
9180    }
9181
9182    public final void startRunning(String pkg, String cls, String action,
9183            String data) {
9184        synchronized(this) {
9185            if (mStartRunning) {
9186                return;
9187            }
9188            mStartRunning = true;
9189            mTopComponent = pkg != null && cls != null
9190                    ? new ComponentName(pkg, cls) : null;
9191            mTopAction = action != null ? action : Intent.ACTION_MAIN;
9192            mTopData = data;
9193            if (!mSystemReady) {
9194                return;
9195            }
9196        }
9197
9198        systemReady(null);
9199    }
9200
9201    private void retrieveSettings() {
9202        final ContentResolver resolver = mContext.getContentResolver();
9203        String debugApp = Settings.Global.getString(
9204            resolver, Settings.Global.DEBUG_APP);
9205        boolean waitForDebugger = Settings.Global.getInt(
9206            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9207        boolean alwaysFinishActivities = Settings.Global.getInt(
9208            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9209        boolean forceRtl = Settings.Global.getInt(
9210                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9211        // Transfer any global setting for forcing RTL layout, into a System Property
9212        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9213
9214        Configuration configuration = new Configuration();
9215        Settings.System.getConfiguration(resolver, configuration);
9216        if (forceRtl) {
9217            // This will take care of setting the correct layout direction flags
9218            configuration.setLayoutDirection(configuration.locale);
9219        }
9220
9221        synchronized (this) {
9222            mDebugApp = mOrigDebugApp = debugApp;
9223            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9224            mAlwaysFinishActivities = alwaysFinishActivities;
9225            // This happens before any activities are started, so we can
9226            // change mConfiguration in-place.
9227            updateConfigurationLocked(configuration, null, false, true);
9228            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9229        }
9230    }
9231
9232    public boolean testIsSystemReady() {
9233        // no need to synchronize(this) just to read & return the value
9234        return mSystemReady;
9235    }
9236
9237    private static File getCalledPreBootReceiversFile() {
9238        File dataDir = Environment.getDataDirectory();
9239        File systemDir = new File(dataDir, "system");
9240        File fname = new File(systemDir, "called_pre_boots.dat");
9241        return fname;
9242    }
9243
9244    static final int LAST_DONE_VERSION = 10000;
9245
9246    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9247        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9248        File file = getCalledPreBootReceiversFile();
9249        FileInputStream fis = null;
9250        try {
9251            fis = new FileInputStream(file);
9252            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9253            int fvers = dis.readInt();
9254            if (fvers == LAST_DONE_VERSION) {
9255                String vers = dis.readUTF();
9256                String codename = dis.readUTF();
9257                String build = dis.readUTF();
9258                if (android.os.Build.VERSION.RELEASE.equals(vers)
9259                        && android.os.Build.VERSION.CODENAME.equals(codename)
9260                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9261                    int num = dis.readInt();
9262                    while (num > 0) {
9263                        num--;
9264                        String pkg = dis.readUTF();
9265                        String cls = dis.readUTF();
9266                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9267                    }
9268                }
9269            }
9270        } catch (FileNotFoundException e) {
9271        } catch (IOException e) {
9272            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9273        } finally {
9274            if (fis != null) {
9275                try {
9276                    fis.close();
9277                } catch (IOException e) {
9278                }
9279            }
9280        }
9281        return lastDoneReceivers;
9282    }
9283
9284    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9285        File file = getCalledPreBootReceiversFile();
9286        FileOutputStream fos = null;
9287        DataOutputStream dos = null;
9288        try {
9289            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9290            fos = new FileOutputStream(file);
9291            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9292            dos.writeInt(LAST_DONE_VERSION);
9293            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9294            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9295            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9296            dos.writeInt(list.size());
9297            for (int i=0; i<list.size(); i++) {
9298                dos.writeUTF(list.get(i).getPackageName());
9299                dos.writeUTF(list.get(i).getClassName());
9300            }
9301        } catch (IOException e) {
9302            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9303            file.delete();
9304        } finally {
9305            FileUtils.sync(fos);
9306            if (dos != null) {
9307                try {
9308                    dos.close();
9309                } catch (IOException e) {
9310                    // TODO Auto-generated catch block
9311                    e.printStackTrace();
9312                }
9313            }
9314        }
9315    }
9316
9317    public void systemReady(final Runnable goingCallback) {
9318        synchronized(this) {
9319            if (mSystemReady) {
9320                if (goingCallback != null) goingCallback.run();
9321                return;
9322            }
9323
9324            // Check to see if there are any update receivers to run.
9325            if (!mDidUpdate) {
9326                if (mWaitingUpdate) {
9327                    return;
9328                }
9329                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9330                List<ResolveInfo> ris = null;
9331                try {
9332                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9333                            intent, null, 0, 0);
9334                } catch (RemoteException e) {
9335                }
9336                if (ris != null) {
9337                    for (int i=ris.size()-1; i>=0; i--) {
9338                        if ((ris.get(i).activityInfo.applicationInfo.flags
9339                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9340                            ris.remove(i);
9341                        }
9342                    }
9343                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9344
9345                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9346
9347                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9348                    for (int i=0; i<ris.size(); i++) {
9349                        ActivityInfo ai = ris.get(i).activityInfo;
9350                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9351                        if (lastDoneReceivers.contains(comp)) {
9352                            // We already did the pre boot receiver for this app with the current
9353                            // platform version, so don't do it again...
9354                            ris.remove(i);
9355                            i--;
9356                            // ...however, do keep it as one that has been done, so we don't
9357                            // forget about it when rewriting the file of last done receivers.
9358                            doneReceivers.add(comp);
9359                        }
9360                    }
9361
9362                    final int[] users = getUsersLocked();
9363                    for (int i=0; i<ris.size(); i++) {
9364                        ActivityInfo ai = ris.get(i).activityInfo;
9365                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9366                        doneReceivers.add(comp);
9367                        intent.setComponent(comp);
9368                        for (int j=0; j<users.length; j++) {
9369                            IIntentReceiver finisher = null;
9370                            if (i == ris.size()-1 && j == users.length-1) {
9371                                finisher = new IIntentReceiver.Stub() {
9372                                    public void performReceive(Intent intent, int resultCode,
9373                                            String data, Bundle extras, boolean ordered,
9374                                            boolean sticky, int sendingUser) {
9375                                        // The raw IIntentReceiver interface is called
9376                                        // with the AM lock held, so redispatch to
9377                                        // execute our code without the lock.
9378                                        mHandler.post(new Runnable() {
9379                                            public void run() {
9380                                                synchronized (ActivityManagerService.this) {
9381                                                    mDidUpdate = true;
9382                                                }
9383                                                writeLastDonePreBootReceivers(doneReceivers);
9384                                                showBootMessage(mContext.getText(
9385                                                        R.string.android_upgrading_complete),
9386                                                        false);
9387                                                systemReady(goingCallback);
9388                                            }
9389                                        });
9390                                    }
9391                                };
9392                            }
9393                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9394                                    + " for user " + users[j]);
9395                            broadcastIntentLocked(null, null, intent, null, finisher,
9396                                    0, null, null, null, AppOpsManager.OP_NONE,
9397                                    true, false, MY_PID, Process.SYSTEM_UID,
9398                                    users[j]);
9399                            if (finisher != null) {
9400                                mWaitingUpdate = true;
9401                            }
9402                        }
9403                    }
9404                }
9405                if (mWaitingUpdate) {
9406                    return;
9407                }
9408                mDidUpdate = true;
9409            }
9410
9411            mAppOpsService.systemReady();
9412            mSystemReady = true;
9413            if (!mStartRunning) {
9414                return;
9415            }
9416        }
9417
9418        ArrayList<ProcessRecord> procsToKill = null;
9419        synchronized(mPidsSelfLocked) {
9420            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9421                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9422                if (!isAllowedWhileBooting(proc.info)){
9423                    if (procsToKill == null) {
9424                        procsToKill = new ArrayList<ProcessRecord>();
9425                    }
9426                    procsToKill.add(proc);
9427                }
9428            }
9429        }
9430
9431        synchronized(this) {
9432            if (procsToKill != null) {
9433                for (int i=procsToKill.size()-1; i>=0; i--) {
9434                    ProcessRecord proc = procsToKill.get(i);
9435                    Slog.i(TAG, "Removing system update proc: " + proc);
9436                    removeProcessLocked(proc, true, false, "system update done");
9437                }
9438            }
9439
9440            // Now that we have cleaned up any update processes, we
9441            // are ready to start launching real processes and know that
9442            // we won't trample on them any more.
9443            mProcessesReady = true;
9444        }
9445
9446        Slog.i(TAG, "System now ready");
9447        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9448            SystemClock.uptimeMillis());
9449
9450        synchronized(this) {
9451            // Make sure we have no pre-ready processes sitting around.
9452
9453            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9454                ResolveInfo ri = mContext.getPackageManager()
9455                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9456                                STOCK_PM_FLAGS);
9457                CharSequence errorMsg = null;
9458                if (ri != null) {
9459                    ActivityInfo ai = ri.activityInfo;
9460                    ApplicationInfo app = ai.applicationInfo;
9461                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9462                        mTopAction = Intent.ACTION_FACTORY_TEST;
9463                        mTopData = null;
9464                        mTopComponent = new ComponentName(app.packageName,
9465                                ai.name);
9466                    } else {
9467                        errorMsg = mContext.getResources().getText(
9468                                com.android.internal.R.string.factorytest_not_system);
9469                    }
9470                } else {
9471                    errorMsg = mContext.getResources().getText(
9472                            com.android.internal.R.string.factorytest_no_action);
9473                }
9474                if (errorMsg != null) {
9475                    mTopAction = null;
9476                    mTopData = null;
9477                    mTopComponent = null;
9478                    Message msg = Message.obtain();
9479                    msg.what = SHOW_FACTORY_ERROR_MSG;
9480                    msg.getData().putCharSequence("msg", errorMsg);
9481                    mHandler.sendMessage(msg);
9482                }
9483            }
9484        }
9485
9486        retrieveSettings();
9487
9488        synchronized (this) {
9489            readGrantedUriPermissionsLocked();
9490        }
9491
9492        if (goingCallback != null) goingCallback.run();
9493
9494        synchronized (this) {
9495            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9496                try {
9497                    List apps = AppGlobals.getPackageManager().
9498                        getPersistentApplications(STOCK_PM_FLAGS);
9499                    if (apps != null) {
9500                        int N = apps.size();
9501                        int i;
9502                        for (i=0; i<N; i++) {
9503                            ApplicationInfo info
9504                                = (ApplicationInfo)apps.get(i);
9505                            if (info != null &&
9506                                    !info.packageName.equals("android")) {
9507                                addAppLocked(info, false);
9508                            }
9509                        }
9510                    }
9511                } catch (RemoteException ex) {
9512                    // pm is in same process, this will never happen.
9513                }
9514            }
9515
9516            // Start up initial activity.
9517            mBooting = true;
9518
9519            try {
9520                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9521                    Message msg = Message.obtain();
9522                    msg.what = SHOW_UID_ERROR_MSG;
9523                    mHandler.sendMessage(msg);
9524                }
9525            } catch (RemoteException e) {
9526            }
9527
9528            long ident = Binder.clearCallingIdentity();
9529            try {
9530                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9531                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9532                        | Intent.FLAG_RECEIVER_FOREGROUND);
9533                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9534                broadcastIntentLocked(null, null, intent,
9535                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9536                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9537                intent = new Intent(Intent.ACTION_USER_STARTING);
9538                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9539                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9540                broadcastIntentLocked(null, null, intent,
9541                        null, new IIntentReceiver.Stub() {
9542                            @Override
9543                            public void performReceive(Intent intent, int resultCode, String data,
9544                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9545                                    throws RemoteException {
9546                            }
9547                        }, 0, null, null,
9548                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9549                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9550            } finally {
9551                Binder.restoreCallingIdentity(ident);
9552            }
9553            mStackSupervisor.resumeTopActivitiesLocked();
9554            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9555        }
9556    }
9557
9558    private boolean makeAppCrashingLocked(ProcessRecord app,
9559            String shortMsg, String longMsg, String stackTrace) {
9560        app.crashing = true;
9561        app.crashingReport = generateProcessError(app,
9562                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9563        startAppProblemLocked(app);
9564        app.stopFreezingAllLocked();
9565        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9566    }
9567
9568    private void makeAppNotRespondingLocked(ProcessRecord app,
9569            String activity, String shortMsg, String longMsg) {
9570        app.notResponding = true;
9571        app.notRespondingReport = generateProcessError(app,
9572                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9573                activity, shortMsg, longMsg, null);
9574        startAppProblemLocked(app);
9575        app.stopFreezingAllLocked();
9576    }
9577
9578    /**
9579     * Generate a process error record, suitable for attachment to a ProcessRecord.
9580     *
9581     * @param app The ProcessRecord in which the error occurred.
9582     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9583     *                      ActivityManager.AppErrorStateInfo
9584     * @param activity The activity associated with the crash, if known.
9585     * @param shortMsg Short message describing the crash.
9586     * @param longMsg Long message describing the crash.
9587     * @param stackTrace Full crash stack trace, may be null.
9588     *
9589     * @return Returns a fully-formed AppErrorStateInfo record.
9590     */
9591    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9592            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9593        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9594
9595        report.condition = condition;
9596        report.processName = app.processName;
9597        report.pid = app.pid;
9598        report.uid = app.info.uid;
9599        report.tag = activity;
9600        report.shortMsg = shortMsg;
9601        report.longMsg = longMsg;
9602        report.stackTrace = stackTrace;
9603
9604        return report;
9605    }
9606
9607    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9608        synchronized (this) {
9609            app.crashing = false;
9610            app.crashingReport = null;
9611            app.notResponding = false;
9612            app.notRespondingReport = null;
9613            if (app.anrDialog == fromDialog) {
9614                app.anrDialog = null;
9615            }
9616            if (app.waitDialog == fromDialog) {
9617                app.waitDialog = null;
9618            }
9619            if (app.pid > 0 && app.pid != MY_PID) {
9620                handleAppCrashLocked(app, null, null, null);
9621                killUnneededProcessLocked(app, "user request after error");
9622            }
9623        }
9624    }
9625
9626    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9627            String stackTrace) {
9628        long now = SystemClock.uptimeMillis();
9629
9630        Long crashTime;
9631        if (!app.isolated) {
9632            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9633        } else {
9634            crashTime = null;
9635        }
9636        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9637            // This process loses!
9638            Slog.w(TAG, "Process " + app.info.processName
9639                    + " has crashed too many times: killing!");
9640            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9641                    app.userId, app.info.processName, app.uid);
9642            mStackSupervisor.handleAppCrashLocked(app);
9643            if (!app.persistent) {
9644                // We don't want to start this process again until the user
9645                // explicitly does so...  but for persistent process, we really
9646                // need to keep it running.  If a persistent process is actually
9647                // repeatedly crashing, then badness for everyone.
9648                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9649                        app.info.processName);
9650                if (!app.isolated) {
9651                    // XXX We don't have a way to mark isolated processes
9652                    // as bad, since they don't have a peristent identity.
9653                    mBadProcesses.put(app.info.processName, app.uid,
9654                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9655                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9656                }
9657                app.bad = true;
9658                app.removed = true;
9659                // Don't let services in this process be restarted and potentially
9660                // annoy the user repeatedly.  Unless it is persistent, since those
9661                // processes run critical code.
9662                removeProcessLocked(app, false, false, "crash");
9663                mStackSupervisor.resumeTopActivitiesLocked();
9664                return false;
9665            }
9666            mStackSupervisor.resumeTopActivitiesLocked();
9667        } else {
9668            mStackSupervisor.finishTopRunningActivityLocked(app);
9669        }
9670
9671        // Bump up the crash count of any services currently running in the proc.
9672        for (int i=app.services.size()-1; i>=0; i--) {
9673            // Any services running in the application need to be placed
9674            // back in the pending list.
9675            ServiceRecord sr = app.services.valueAt(i);
9676            sr.crashCount++;
9677        }
9678
9679        // If the crashing process is what we consider to be the "home process" and it has been
9680        // replaced by a third-party app, clear the package preferred activities from packages
9681        // with a home activity running in the process to prevent a repeatedly crashing app
9682        // from blocking the user to manually clear the list.
9683        final ArrayList<ActivityRecord> activities = app.activities;
9684        if (app == mHomeProcess && activities.size() > 0
9685                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9686            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9687                final ActivityRecord r = activities.get(activityNdx);
9688                if (r.isHomeActivity()) {
9689                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9690                    try {
9691                        ActivityThread.getPackageManager()
9692                                .clearPackagePreferredActivities(r.packageName);
9693                    } catch (RemoteException c) {
9694                        // pm is in same process, this will never happen.
9695                    }
9696                }
9697            }
9698        }
9699
9700        if (!app.isolated) {
9701            // XXX Can't keep track of crash times for isolated processes,
9702            // because they don't have a perisistent identity.
9703            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9704        }
9705
9706        return true;
9707    }
9708
9709    void startAppProblemLocked(ProcessRecord app) {
9710        if (app.userId == mCurrentUserId) {
9711            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9712                    mContext, app.info.packageName, app.info.flags);
9713        } else {
9714            // If this app is not running under the current user, then we
9715            // can't give it a report button because that would require
9716            // launching the report UI under a different user.
9717            app.errorReportReceiver = null;
9718        }
9719        skipCurrentReceiverLocked(app);
9720    }
9721
9722    void skipCurrentReceiverLocked(ProcessRecord app) {
9723        for (BroadcastQueue queue : mBroadcastQueues) {
9724            queue.skipCurrentReceiverLocked(app);
9725        }
9726    }
9727
9728    /**
9729     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9730     * The application process will exit immediately after this call returns.
9731     * @param app object of the crashing app, null for the system server
9732     * @param crashInfo describing the exception
9733     */
9734    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9735        ProcessRecord r = findAppProcess(app, "Crash");
9736        final String processName = app == null ? "system_server"
9737                : (r == null ? "unknown" : r.processName);
9738
9739        handleApplicationCrashInner("crash", r, processName, crashInfo);
9740    }
9741
9742    /* Native crash reporting uses this inner version because it needs to be somewhat
9743     * decoupled from the AM-managed cleanup lifecycle
9744     */
9745    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
9746            ApplicationErrorReport.CrashInfo crashInfo) {
9747        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
9748                UserHandle.getUserId(Binder.getCallingUid()), processName,
9749                r == null ? -1 : r.info.flags,
9750                crashInfo.exceptionClassName,
9751                crashInfo.exceptionMessage,
9752                crashInfo.throwFileName,
9753                crashInfo.throwLineNumber);
9754
9755        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
9756
9757        crashApplication(r, crashInfo);
9758    }
9759
9760    public void handleApplicationStrictModeViolation(
9761            IBinder app,
9762            int violationMask,
9763            StrictMode.ViolationInfo info) {
9764        ProcessRecord r = findAppProcess(app, "StrictMode");
9765        if (r == null) {
9766            return;
9767        }
9768
9769        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
9770            Integer stackFingerprint = info.hashCode();
9771            boolean logIt = true;
9772            synchronized (mAlreadyLoggedViolatedStacks) {
9773                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
9774                    logIt = false;
9775                    // TODO: sub-sample into EventLog for these, with
9776                    // the info.durationMillis?  Then we'd get
9777                    // the relative pain numbers, without logging all
9778                    // the stack traces repeatedly.  We'd want to do
9779                    // likewise in the client code, which also does
9780                    // dup suppression, before the Binder call.
9781                } else {
9782                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
9783                        mAlreadyLoggedViolatedStacks.clear();
9784                    }
9785                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
9786                }
9787            }
9788            if (logIt) {
9789                logStrictModeViolationToDropBox(r, info);
9790            }
9791        }
9792
9793        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
9794            AppErrorResult result = new AppErrorResult();
9795            synchronized (this) {
9796                final long origId = Binder.clearCallingIdentity();
9797
9798                Message msg = Message.obtain();
9799                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
9800                HashMap<String, Object> data = new HashMap<String, Object>();
9801                data.put("result", result);
9802                data.put("app", r);
9803                data.put("violationMask", violationMask);
9804                data.put("info", info);
9805                msg.obj = data;
9806                mHandler.sendMessage(msg);
9807
9808                Binder.restoreCallingIdentity(origId);
9809            }
9810            int res = result.get();
9811            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
9812        }
9813    }
9814
9815    // Depending on the policy in effect, there could be a bunch of
9816    // these in quick succession so we try to batch these together to
9817    // minimize disk writes, number of dropbox entries, and maximize
9818    // compression, by having more fewer, larger records.
9819    private void logStrictModeViolationToDropBox(
9820            ProcessRecord process,
9821            StrictMode.ViolationInfo info) {
9822        if (info == null) {
9823            return;
9824        }
9825        final boolean isSystemApp = process == null ||
9826                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
9827                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
9828        final String processName = process == null ? "unknown" : process.processName;
9829        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
9830        final DropBoxManager dbox = (DropBoxManager)
9831                mContext.getSystemService(Context.DROPBOX_SERVICE);
9832
9833        // Exit early if the dropbox isn't configured to accept this report type.
9834        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9835
9836        boolean bufferWasEmpty;
9837        boolean needsFlush;
9838        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
9839        synchronized (sb) {
9840            bufferWasEmpty = sb.length() == 0;
9841            appendDropBoxProcessHeaders(process, processName, sb);
9842            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9843            sb.append("System-App: ").append(isSystemApp).append("\n");
9844            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
9845            if (info.violationNumThisLoop != 0) {
9846                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
9847            }
9848            if (info.numAnimationsRunning != 0) {
9849                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
9850            }
9851            if (info.broadcastIntentAction != null) {
9852                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
9853            }
9854            if (info.durationMillis != -1) {
9855                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
9856            }
9857            if (info.numInstances != -1) {
9858                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
9859            }
9860            if (info.tags != null) {
9861                for (String tag : info.tags) {
9862                    sb.append("Span-Tag: ").append(tag).append("\n");
9863                }
9864            }
9865            sb.append("\n");
9866            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
9867                sb.append(info.crashInfo.stackTrace);
9868            }
9869            sb.append("\n");
9870
9871            // Only buffer up to ~64k.  Various logging bits truncate
9872            // things at 128k.
9873            needsFlush = (sb.length() > 64 * 1024);
9874        }
9875
9876        // Flush immediately if the buffer's grown too large, or this
9877        // is a non-system app.  Non-system apps are isolated with a
9878        // different tag & policy and not batched.
9879        //
9880        // Batching is useful during internal testing with
9881        // StrictMode settings turned up high.  Without batching,
9882        // thousands of separate files could be created on boot.
9883        if (!isSystemApp || needsFlush) {
9884            new Thread("Error dump: " + dropboxTag) {
9885                @Override
9886                public void run() {
9887                    String report;
9888                    synchronized (sb) {
9889                        report = sb.toString();
9890                        sb.delete(0, sb.length());
9891                        sb.trimToSize();
9892                    }
9893                    if (report.length() != 0) {
9894                        dbox.addText(dropboxTag, report);
9895                    }
9896                }
9897            }.start();
9898            return;
9899        }
9900
9901        // System app batching:
9902        if (!bufferWasEmpty) {
9903            // An existing dropbox-writing thread is outstanding, so
9904            // we don't need to start it up.  The existing thread will
9905            // catch the buffer appends we just did.
9906            return;
9907        }
9908
9909        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
9910        // (After this point, we shouldn't access AMS internal data structures.)
9911        new Thread("Error dump: " + dropboxTag) {
9912            @Override
9913            public void run() {
9914                // 5 second sleep to let stacks arrive and be batched together
9915                try {
9916                    Thread.sleep(5000);  // 5 seconds
9917                } catch (InterruptedException e) {}
9918
9919                String errorReport;
9920                synchronized (mStrictModeBuffer) {
9921                    errorReport = mStrictModeBuffer.toString();
9922                    if (errorReport.length() == 0) {
9923                        return;
9924                    }
9925                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
9926                    mStrictModeBuffer.trimToSize();
9927                }
9928                dbox.addText(dropboxTag, errorReport);
9929            }
9930        }.start();
9931    }
9932
9933    /**
9934     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
9935     * @param app object of the crashing app, null for the system server
9936     * @param tag reported by the caller
9937     * @param crashInfo describing the context of the error
9938     * @return true if the process should exit immediately (WTF is fatal)
9939     */
9940    public boolean handleApplicationWtf(IBinder app, String tag,
9941            ApplicationErrorReport.CrashInfo crashInfo) {
9942        ProcessRecord r = findAppProcess(app, "WTF");
9943        final String processName = app == null ? "system_server"
9944                : (r == null ? "unknown" : r.processName);
9945
9946        EventLog.writeEvent(EventLogTags.AM_WTF,
9947                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
9948                processName,
9949                r == null ? -1 : r.info.flags,
9950                tag, crashInfo.exceptionMessage);
9951
9952        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
9953
9954        if (r != null && r.pid != Process.myPid() &&
9955                Settings.Global.getInt(mContext.getContentResolver(),
9956                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
9957            crashApplication(r, crashInfo);
9958            return true;
9959        } else {
9960            return false;
9961        }
9962    }
9963
9964    /**
9965     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
9966     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
9967     */
9968    private ProcessRecord findAppProcess(IBinder app, String reason) {
9969        if (app == null) {
9970            return null;
9971        }
9972
9973        synchronized (this) {
9974            final int NP = mProcessNames.getMap().size();
9975            for (int ip=0; ip<NP; ip++) {
9976                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
9977                final int NA = apps.size();
9978                for (int ia=0; ia<NA; ia++) {
9979                    ProcessRecord p = apps.valueAt(ia);
9980                    if (p.thread != null && p.thread.asBinder() == app) {
9981                        return p;
9982                    }
9983                }
9984            }
9985
9986            Slog.w(TAG, "Can't find mystery application for " + reason
9987                    + " from pid=" + Binder.getCallingPid()
9988                    + " uid=" + Binder.getCallingUid() + ": " + app);
9989            return null;
9990        }
9991    }
9992
9993    /**
9994     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
9995     * to append various headers to the dropbox log text.
9996     */
9997    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
9998            StringBuilder sb) {
9999        // Watchdog thread ends up invoking this function (with
10000        // a null ProcessRecord) to add the stack file to dropbox.
10001        // Do not acquire a lock on this (am) in such cases, as it
10002        // could cause a potential deadlock, if and when watchdog
10003        // is invoked due to unavailability of lock on am and it
10004        // would prevent watchdog from killing system_server.
10005        if (process == null) {
10006            sb.append("Process: ").append(processName).append("\n");
10007            return;
10008        }
10009        // Note: ProcessRecord 'process' is guarded by the service
10010        // instance.  (notably process.pkgList, which could otherwise change
10011        // concurrently during execution of this method)
10012        synchronized (this) {
10013            sb.append("Process: ").append(processName).append("\n");
10014            int flags = process.info.flags;
10015            IPackageManager pm = AppGlobals.getPackageManager();
10016            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10017            for (int ip=0; ip<process.pkgList.size(); ip++) {
10018                String pkg = process.pkgList.keyAt(ip);
10019                sb.append("Package: ").append(pkg);
10020                try {
10021                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10022                    if (pi != null) {
10023                        sb.append(" v").append(pi.versionCode);
10024                        if (pi.versionName != null) {
10025                            sb.append(" (").append(pi.versionName).append(")");
10026                        }
10027                    }
10028                } catch (RemoteException e) {
10029                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10030                }
10031                sb.append("\n");
10032            }
10033        }
10034    }
10035
10036    private static String processClass(ProcessRecord process) {
10037        if (process == null || process.pid == MY_PID) {
10038            return "system_server";
10039        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10040            return "system_app";
10041        } else {
10042            return "data_app";
10043        }
10044    }
10045
10046    /**
10047     * Write a description of an error (crash, WTF, ANR) to the drop box.
10048     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10049     * @param process which caused the error, null means the system server
10050     * @param activity which triggered the error, null if unknown
10051     * @param parent activity related to the error, null if unknown
10052     * @param subject line related to the error, null if absent
10053     * @param report in long form describing the error, null if absent
10054     * @param logFile to include in the report, null if none
10055     * @param crashInfo giving an application stack trace, null if absent
10056     */
10057    public void addErrorToDropBox(String eventType,
10058            ProcessRecord process, String processName, ActivityRecord activity,
10059            ActivityRecord parent, String subject,
10060            final String report, final File logFile,
10061            final ApplicationErrorReport.CrashInfo crashInfo) {
10062        // NOTE -- this must never acquire the ActivityManagerService lock,
10063        // otherwise the watchdog may be prevented from resetting the system.
10064
10065        final String dropboxTag = processClass(process) + "_" + eventType;
10066        final DropBoxManager dbox = (DropBoxManager)
10067                mContext.getSystemService(Context.DROPBOX_SERVICE);
10068
10069        // Exit early if the dropbox isn't configured to accept this report type.
10070        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10071
10072        final StringBuilder sb = new StringBuilder(1024);
10073        appendDropBoxProcessHeaders(process, processName, sb);
10074        if (activity != null) {
10075            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10076        }
10077        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10078            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10079        }
10080        if (parent != null && parent != activity) {
10081            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10082        }
10083        if (subject != null) {
10084            sb.append("Subject: ").append(subject).append("\n");
10085        }
10086        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10087        if (Debug.isDebuggerConnected()) {
10088            sb.append("Debugger: Connected\n");
10089        }
10090        sb.append("\n");
10091
10092        // Do the rest in a worker thread to avoid blocking the caller on I/O
10093        // (After this point, we shouldn't access AMS internal data structures.)
10094        Thread worker = new Thread("Error dump: " + dropboxTag) {
10095            @Override
10096            public void run() {
10097                if (report != null) {
10098                    sb.append(report);
10099                }
10100                if (logFile != null) {
10101                    try {
10102                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10103                                    "\n\n[[TRUNCATED]]"));
10104                    } catch (IOException e) {
10105                        Slog.e(TAG, "Error reading " + logFile, e);
10106                    }
10107                }
10108                if (crashInfo != null && crashInfo.stackTrace != null) {
10109                    sb.append(crashInfo.stackTrace);
10110                }
10111
10112                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10113                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10114                if (lines > 0) {
10115                    sb.append("\n");
10116
10117                    // Merge several logcat streams, and take the last N lines
10118                    InputStreamReader input = null;
10119                    try {
10120                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10121                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10122                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10123
10124                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10125                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10126                        input = new InputStreamReader(logcat.getInputStream());
10127
10128                        int num;
10129                        char[] buf = new char[8192];
10130                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10131                    } catch (IOException e) {
10132                        Slog.e(TAG, "Error running logcat", e);
10133                    } finally {
10134                        if (input != null) try { input.close(); } catch (IOException e) {}
10135                    }
10136                }
10137
10138                dbox.addText(dropboxTag, sb.toString());
10139            }
10140        };
10141
10142        if (process == null) {
10143            // If process is null, we are being called from some internal code
10144            // and may be about to die -- run this synchronously.
10145            worker.run();
10146        } else {
10147            worker.start();
10148        }
10149    }
10150
10151    /**
10152     * Bring up the "unexpected error" dialog box for a crashing app.
10153     * Deal with edge cases (intercepts from instrumented applications,
10154     * ActivityController, error intent receivers, that sort of thing).
10155     * @param r the application crashing
10156     * @param crashInfo describing the failure
10157     */
10158    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10159        long timeMillis = System.currentTimeMillis();
10160        String shortMsg = crashInfo.exceptionClassName;
10161        String longMsg = crashInfo.exceptionMessage;
10162        String stackTrace = crashInfo.stackTrace;
10163        if (shortMsg != null && longMsg != null) {
10164            longMsg = shortMsg + ": " + longMsg;
10165        } else if (shortMsg != null) {
10166            longMsg = shortMsg;
10167        }
10168
10169        AppErrorResult result = new AppErrorResult();
10170        synchronized (this) {
10171            if (mController != null) {
10172                try {
10173                    String name = r != null ? r.processName : null;
10174                    int pid = r != null ? r.pid : Binder.getCallingPid();
10175                    if (!mController.appCrashed(name, pid,
10176                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10177                        Slog.w(TAG, "Force-killing crashed app " + name
10178                                + " at watcher's request");
10179                        Process.killProcess(pid);
10180                        return;
10181                    }
10182                } catch (RemoteException e) {
10183                    mController = null;
10184                    Watchdog.getInstance().setActivityController(null);
10185                }
10186            }
10187
10188            final long origId = Binder.clearCallingIdentity();
10189
10190            // If this process is running instrumentation, finish it.
10191            if (r != null && r.instrumentationClass != null) {
10192                Slog.w(TAG, "Error in app " + r.processName
10193                      + " running instrumentation " + r.instrumentationClass + ":");
10194                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10195                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10196                Bundle info = new Bundle();
10197                info.putString("shortMsg", shortMsg);
10198                info.putString("longMsg", longMsg);
10199                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10200                Binder.restoreCallingIdentity(origId);
10201                return;
10202            }
10203
10204            // If we can't identify the process or it's already exceeded its crash quota,
10205            // quit right away without showing a crash dialog.
10206            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10207                Binder.restoreCallingIdentity(origId);
10208                return;
10209            }
10210
10211            Message msg = Message.obtain();
10212            msg.what = SHOW_ERROR_MSG;
10213            HashMap data = new HashMap();
10214            data.put("result", result);
10215            data.put("app", r);
10216            msg.obj = data;
10217            mHandler.sendMessage(msg);
10218
10219            Binder.restoreCallingIdentity(origId);
10220        }
10221
10222        int res = result.get();
10223
10224        Intent appErrorIntent = null;
10225        synchronized (this) {
10226            if (r != null && !r.isolated) {
10227                // XXX Can't keep track of crash time for isolated processes,
10228                // since they don't have a persistent identity.
10229                mProcessCrashTimes.put(r.info.processName, r.uid,
10230                        SystemClock.uptimeMillis());
10231            }
10232            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10233                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10234            }
10235        }
10236
10237        if (appErrorIntent != null) {
10238            try {
10239                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10240            } catch (ActivityNotFoundException e) {
10241                Slog.w(TAG, "bug report receiver dissappeared", e);
10242            }
10243        }
10244    }
10245
10246    Intent createAppErrorIntentLocked(ProcessRecord r,
10247            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10248        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10249        if (report == null) {
10250            return null;
10251        }
10252        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10253        result.setComponent(r.errorReportReceiver);
10254        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10255        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10256        return result;
10257    }
10258
10259    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10260            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10261        if (r.errorReportReceiver == null) {
10262            return null;
10263        }
10264
10265        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10266            return null;
10267        }
10268
10269        ApplicationErrorReport report = new ApplicationErrorReport();
10270        report.packageName = r.info.packageName;
10271        report.installerPackageName = r.errorReportReceiver.getPackageName();
10272        report.processName = r.processName;
10273        report.time = timeMillis;
10274        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10275
10276        if (r.crashing || r.forceCrashReport) {
10277            report.type = ApplicationErrorReport.TYPE_CRASH;
10278            report.crashInfo = crashInfo;
10279        } else if (r.notResponding) {
10280            report.type = ApplicationErrorReport.TYPE_ANR;
10281            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10282
10283            report.anrInfo.activity = r.notRespondingReport.tag;
10284            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10285            report.anrInfo.info = r.notRespondingReport.longMsg;
10286        }
10287
10288        return report;
10289    }
10290
10291    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10292        enforceNotIsolatedCaller("getProcessesInErrorState");
10293        // assume our apps are happy - lazy create the list
10294        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10295
10296        final boolean allUsers = ActivityManager.checkUidPermission(
10297                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10298                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10299        int userId = UserHandle.getUserId(Binder.getCallingUid());
10300
10301        synchronized (this) {
10302
10303            // iterate across all processes
10304            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10305                ProcessRecord app = mLruProcesses.get(i);
10306                if (!allUsers && app.userId != userId) {
10307                    continue;
10308                }
10309                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10310                    // This one's in trouble, so we'll generate a report for it
10311                    // crashes are higher priority (in case there's a crash *and* an anr)
10312                    ActivityManager.ProcessErrorStateInfo report = null;
10313                    if (app.crashing) {
10314                        report = app.crashingReport;
10315                    } else if (app.notResponding) {
10316                        report = app.notRespondingReport;
10317                    }
10318
10319                    if (report != null) {
10320                        if (errList == null) {
10321                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10322                        }
10323                        errList.add(report);
10324                    } else {
10325                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10326                                " crashing = " + app.crashing +
10327                                " notResponding = " + app.notResponding);
10328                    }
10329                }
10330            }
10331        }
10332
10333        return errList;
10334    }
10335
10336    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10337        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10338            if (currApp != null) {
10339                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10340            }
10341            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10342        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10343            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10344        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10345            if (currApp != null) {
10346                currApp.lru = 0;
10347            }
10348            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10349        } else if (adj >= ProcessList.SERVICE_ADJ) {
10350            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10351        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10352            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10353        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10354            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10355        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10356            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10357        } else {
10358            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10359        }
10360    }
10361
10362    private void fillInProcMemInfo(ProcessRecord app,
10363            ActivityManager.RunningAppProcessInfo outInfo) {
10364        outInfo.pid = app.pid;
10365        outInfo.uid = app.info.uid;
10366        if (mHeavyWeightProcess == app) {
10367            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10368        }
10369        if (app.persistent) {
10370            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10371        }
10372        if (app.activities.size() > 0) {
10373            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10374        }
10375        outInfo.lastTrimLevel = app.trimMemoryLevel;
10376        int adj = app.curAdj;
10377        outInfo.importance = oomAdjToImportance(adj, outInfo);
10378        outInfo.importanceReasonCode = app.adjTypeCode;
10379    }
10380
10381    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10382        enforceNotIsolatedCaller("getRunningAppProcesses");
10383        // Lazy instantiation of list
10384        List<ActivityManager.RunningAppProcessInfo> runList = null;
10385        final boolean allUsers = ActivityManager.checkUidPermission(
10386                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10387                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10388        int userId = UserHandle.getUserId(Binder.getCallingUid());
10389        synchronized (this) {
10390            // Iterate across all processes
10391            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10392                ProcessRecord app = mLruProcesses.get(i);
10393                if (!allUsers && app.userId != userId) {
10394                    continue;
10395                }
10396                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10397                    // Generate process state info for running application
10398                    ActivityManager.RunningAppProcessInfo currApp =
10399                        new ActivityManager.RunningAppProcessInfo(app.processName,
10400                                app.pid, app.getPackageList());
10401                    fillInProcMemInfo(app, currApp);
10402                    if (app.adjSource instanceof ProcessRecord) {
10403                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10404                        currApp.importanceReasonImportance = oomAdjToImportance(
10405                                app.adjSourceOom, null);
10406                    } else if (app.adjSource instanceof ActivityRecord) {
10407                        ActivityRecord r = (ActivityRecord)app.adjSource;
10408                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10409                    }
10410                    if (app.adjTarget instanceof ComponentName) {
10411                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10412                    }
10413                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10414                    //        + " lru=" + currApp.lru);
10415                    if (runList == null) {
10416                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10417                    }
10418                    runList.add(currApp);
10419                }
10420            }
10421        }
10422        return runList;
10423    }
10424
10425    public List<ApplicationInfo> getRunningExternalApplications() {
10426        enforceNotIsolatedCaller("getRunningExternalApplications");
10427        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10428        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10429        if (runningApps != null && runningApps.size() > 0) {
10430            Set<String> extList = new HashSet<String>();
10431            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10432                if (app.pkgList != null) {
10433                    for (String pkg : app.pkgList) {
10434                        extList.add(pkg);
10435                    }
10436                }
10437            }
10438            IPackageManager pm = AppGlobals.getPackageManager();
10439            for (String pkg : extList) {
10440                try {
10441                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10442                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10443                        retList.add(info);
10444                    }
10445                } catch (RemoteException e) {
10446                }
10447            }
10448        }
10449        return retList;
10450    }
10451
10452    @Override
10453    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10454        enforceNotIsolatedCaller("getMyMemoryState");
10455        synchronized (this) {
10456            ProcessRecord proc;
10457            synchronized (mPidsSelfLocked) {
10458                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10459            }
10460            fillInProcMemInfo(proc, outInfo);
10461        }
10462    }
10463
10464    @Override
10465    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10466        if (checkCallingPermission(android.Manifest.permission.DUMP)
10467                != PackageManager.PERMISSION_GRANTED) {
10468            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10469                    + Binder.getCallingPid()
10470                    + ", uid=" + Binder.getCallingUid()
10471                    + " without permission "
10472                    + android.Manifest.permission.DUMP);
10473            return;
10474        }
10475
10476        boolean dumpAll = false;
10477        boolean dumpClient = false;
10478        String dumpPackage = null;
10479
10480        int opti = 0;
10481        while (opti < args.length) {
10482            String opt = args[opti];
10483            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10484                break;
10485            }
10486            opti++;
10487            if ("-a".equals(opt)) {
10488                dumpAll = true;
10489            } else if ("-c".equals(opt)) {
10490                dumpClient = true;
10491            } else if ("-h".equals(opt)) {
10492                pw.println("Activity manager dump options:");
10493                pw.println("  [-a] [-c] [-h] [cmd] ...");
10494                pw.println("  cmd may be one of:");
10495                pw.println("    a[ctivities]: activity stack state");
10496                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10497                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10498                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10499                pw.println("    o[om]: out of memory management");
10500                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10501                pw.println("    provider [COMP_SPEC]: provider client-side state");
10502                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10503                pw.println("    service [COMP_SPEC]: service client-side state");
10504                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10505                pw.println("    all: dump all activities");
10506                pw.println("    top: dump the top activity");
10507                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10508                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10509                pw.println("    a partial substring in a component name, a");
10510                pw.println("    hex object identifier.");
10511                pw.println("  -a: include all available server state.");
10512                pw.println("  -c: include client state.");
10513                return;
10514            } else {
10515                pw.println("Unknown argument: " + opt + "; use -h for help");
10516            }
10517        }
10518
10519        long origId = Binder.clearCallingIdentity();
10520        boolean more = false;
10521        // Is the caller requesting to dump a particular piece of data?
10522        if (opti < args.length) {
10523            String cmd = args[opti];
10524            opti++;
10525            if ("activities".equals(cmd) || "a".equals(cmd)) {
10526                synchronized (this) {
10527                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10528                }
10529            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10530                String[] newArgs;
10531                String name;
10532                if (opti >= args.length) {
10533                    name = null;
10534                    newArgs = EMPTY_STRING_ARRAY;
10535                } else {
10536                    name = args[opti];
10537                    opti++;
10538                    newArgs = new String[args.length - opti];
10539                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10540                            args.length - opti);
10541                }
10542                synchronized (this) {
10543                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10544                }
10545            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10546                String[] newArgs;
10547                String name;
10548                if (opti >= args.length) {
10549                    name = null;
10550                    newArgs = EMPTY_STRING_ARRAY;
10551                } else {
10552                    name = args[opti];
10553                    opti++;
10554                    newArgs = new String[args.length - opti];
10555                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10556                            args.length - opti);
10557                }
10558                synchronized (this) {
10559                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10560                }
10561            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10562                String[] newArgs;
10563                String name;
10564                if (opti >= args.length) {
10565                    name = null;
10566                    newArgs = EMPTY_STRING_ARRAY;
10567                } else {
10568                    name = args[opti];
10569                    opti++;
10570                    newArgs = new String[args.length - opti];
10571                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10572                            args.length - opti);
10573                }
10574                synchronized (this) {
10575                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10576                }
10577            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10578                synchronized (this) {
10579                    dumpOomLocked(fd, pw, args, opti, true);
10580                }
10581            } else if ("provider".equals(cmd)) {
10582                String[] newArgs;
10583                String name;
10584                if (opti >= args.length) {
10585                    name = null;
10586                    newArgs = EMPTY_STRING_ARRAY;
10587                } else {
10588                    name = args[opti];
10589                    opti++;
10590                    newArgs = new String[args.length - opti];
10591                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10592                }
10593                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10594                    pw.println("No providers match: " + name);
10595                    pw.println("Use -h for help.");
10596                }
10597            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10598                synchronized (this) {
10599                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10600                }
10601            } else if ("service".equals(cmd)) {
10602                String[] newArgs;
10603                String name;
10604                if (opti >= args.length) {
10605                    name = null;
10606                    newArgs = EMPTY_STRING_ARRAY;
10607                } else {
10608                    name = args[opti];
10609                    opti++;
10610                    newArgs = new String[args.length - opti];
10611                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10612                            args.length - opti);
10613                }
10614                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10615                    pw.println("No services match: " + name);
10616                    pw.println("Use -h for help.");
10617                }
10618            } else if ("package".equals(cmd)) {
10619                String[] newArgs;
10620                if (opti >= args.length) {
10621                    pw.println("package: no package name specified");
10622                    pw.println("Use -h for help.");
10623                } else {
10624                    dumpPackage = args[opti];
10625                    opti++;
10626                    newArgs = new String[args.length - opti];
10627                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10628                            args.length - opti);
10629                    args = newArgs;
10630                    opti = 0;
10631                    more = true;
10632                }
10633            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10634                synchronized (this) {
10635                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10636                }
10637            } else {
10638                // Dumping a single activity?
10639                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10640                    pw.println("Bad activity command, or no activities match: " + cmd);
10641                    pw.println("Use -h for help.");
10642                }
10643            }
10644            if (!more) {
10645                Binder.restoreCallingIdentity(origId);
10646                return;
10647            }
10648        }
10649
10650        // No piece of data specified, dump everything.
10651        synchronized (this) {
10652            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10653            pw.println();
10654            if (dumpAll) {
10655                pw.println("-------------------------------------------------------------------------------");
10656            }
10657            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10658            pw.println();
10659            if (dumpAll) {
10660                pw.println("-------------------------------------------------------------------------------");
10661            }
10662            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10663            pw.println();
10664            if (dumpAll) {
10665                pw.println("-------------------------------------------------------------------------------");
10666            }
10667            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10668            pw.println();
10669            if (dumpAll) {
10670                pw.println("-------------------------------------------------------------------------------");
10671            }
10672            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10673            pw.println();
10674            if (dumpAll) {
10675                pw.println("-------------------------------------------------------------------------------");
10676            }
10677            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10678        }
10679        Binder.restoreCallingIdentity(origId);
10680    }
10681
10682    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10683            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10684        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10685
10686        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10687                dumpPackage);
10688        boolean needSep = printedAnything;
10689
10690        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10691                dumpPackage, needSep, "  mFocusedActivity: ");
10692        if (printed) {
10693            printedAnything = true;
10694            needSep = false;
10695        }
10696
10697        if (dumpPackage == null) {
10698            if (needSep) {
10699                pw.println();
10700            }
10701            needSep = true;
10702            printedAnything = true;
10703            mStackSupervisor.dump(pw, "  ");
10704        }
10705
10706        if (mRecentTasks.size() > 0) {
10707            boolean printedHeader = false;
10708
10709            final int N = mRecentTasks.size();
10710            for (int i=0; i<N; i++) {
10711                TaskRecord tr = mRecentTasks.get(i);
10712                if (dumpPackage != null) {
10713                    if (tr.realActivity == null ||
10714                            !dumpPackage.equals(tr.realActivity)) {
10715                        continue;
10716                    }
10717                }
10718                if (!printedHeader) {
10719                    if (needSep) {
10720                        pw.println();
10721                    }
10722                    pw.println("  Recent tasks:");
10723                    printedHeader = true;
10724                    printedAnything = true;
10725                }
10726                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10727                        pw.println(tr);
10728                if (dumpAll) {
10729                    mRecentTasks.get(i).dump(pw, "    ");
10730                }
10731            }
10732        }
10733
10734        if (!printedAnything) {
10735            pw.println("  (nothing)");
10736        }
10737    }
10738
10739    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10740            int opti, boolean dumpAll, String dumpPackage) {
10741        boolean needSep = false;
10742        boolean printedAnything = false;
10743        int numPers = 0;
10744
10745        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
10746
10747        if (dumpAll) {
10748            final int NP = mProcessNames.getMap().size();
10749            for (int ip=0; ip<NP; ip++) {
10750                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
10751                final int NA = procs.size();
10752                for (int ia=0; ia<NA; ia++) {
10753                    ProcessRecord r = procs.valueAt(ia);
10754                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10755                        continue;
10756                    }
10757                    if (!needSep) {
10758                        pw.println("  All known processes:");
10759                        needSep = true;
10760                        printedAnything = true;
10761                    }
10762                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
10763                        pw.print(" UID "); pw.print(procs.keyAt(ia));
10764                        pw.print(" "); pw.println(r);
10765                    r.dump(pw, "    ");
10766                    if (r.persistent) {
10767                        numPers++;
10768                    }
10769                }
10770            }
10771        }
10772
10773        if (mIsolatedProcesses.size() > 0) {
10774            boolean printed = false;
10775            for (int i=0; i<mIsolatedProcesses.size(); i++) {
10776                ProcessRecord r = mIsolatedProcesses.valueAt(i);
10777                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10778                    continue;
10779                }
10780                if (!printed) {
10781                    if (needSep) {
10782                        pw.println();
10783                    }
10784                    pw.println("  Isolated process list (sorted by uid):");
10785                    printedAnything = true;
10786                    printed = true;
10787                    needSep = true;
10788                }
10789                pw.println(String.format("%sIsolated #%2d: %s",
10790                        "    ", i, r.toString()));
10791            }
10792        }
10793
10794        if (mLruProcesses.size() > 0) {
10795            if (needSep) {
10796                pw.println();
10797            }
10798            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
10799                    pw.print(" total, non-act at ");
10800                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10801                    pw.print(", non-svc at ");
10802                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10803                    pw.println("):");
10804            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
10805            needSep = true;
10806            printedAnything = true;
10807        }
10808
10809        if (dumpAll || dumpPackage != null) {
10810            synchronized (mPidsSelfLocked) {
10811                boolean printed = false;
10812                for (int i=0; i<mPidsSelfLocked.size(); i++) {
10813                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
10814                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10815                        continue;
10816                    }
10817                    if (!printed) {
10818                        if (needSep) pw.println();
10819                        needSep = true;
10820                        pw.println("  PID mappings:");
10821                        printed = true;
10822                        printedAnything = true;
10823                    }
10824                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
10825                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
10826                }
10827            }
10828        }
10829
10830        if (mForegroundProcesses.size() > 0) {
10831            synchronized (mPidsSelfLocked) {
10832                boolean printed = false;
10833                for (int i=0; i<mForegroundProcesses.size(); i++) {
10834                    ProcessRecord r = mPidsSelfLocked.get(
10835                            mForegroundProcesses.valueAt(i).pid);
10836                    if (dumpPackage != null && (r == null
10837                            || !r.pkgList.containsKey(dumpPackage))) {
10838                        continue;
10839                    }
10840                    if (!printed) {
10841                        if (needSep) pw.println();
10842                        needSep = true;
10843                        pw.println("  Foreground Processes:");
10844                        printed = true;
10845                        printedAnything = true;
10846                    }
10847                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
10848                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
10849                }
10850            }
10851        }
10852
10853        if (mPersistentStartingProcesses.size() > 0) {
10854            if (needSep) pw.println();
10855            needSep = true;
10856            printedAnything = true;
10857            pw.println("  Persisent processes that are starting:");
10858            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
10859                    "Starting Norm", "Restarting PERS", dumpPackage);
10860        }
10861
10862        if (mRemovedProcesses.size() > 0) {
10863            if (needSep) pw.println();
10864            needSep = true;
10865            printedAnything = true;
10866            pw.println("  Processes that are being removed:");
10867            dumpProcessList(pw, this, mRemovedProcesses, "    ",
10868                    "Removed Norm", "Removed PERS", dumpPackage);
10869        }
10870
10871        if (mProcessesOnHold.size() > 0) {
10872            if (needSep) pw.println();
10873            needSep = true;
10874            printedAnything = true;
10875            pw.println("  Processes that are on old until the system is ready:");
10876            dumpProcessList(pw, this, mProcessesOnHold, "    ",
10877                    "OnHold Norm", "OnHold PERS", dumpPackage);
10878        }
10879
10880        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
10881
10882        if (mProcessCrashTimes.getMap().size() > 0) {
10883            boolean printed = false;
10884            long now = SystemClock.uptimeMillis();
10885            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
10886            final int NP = pmap.size();
10887            for (int ip=0; ip<NP; ip++) {
10888                String pname = pmap.keyAt(ip);
10889                SparseArray<Long> uids = pmap.valueAt(ip);
10890                final int N = uids.size();
10891                for (int i=0; i<N; i++) {
10892                    int puid = uids.keyAt(i);
10893                    ProcessRecord r = mProcessNames.get(pname, puid);
10894                    if (dumpPackage != null && (r == null
10895                            || !r.pkgList.containsKey(dumpPackage))) {
10896                        continue;
10897                    }
10898                    if (!printed) {
10899                        if (needSep) pw.println();
10900                        needSep = true;
10901                        pw.println("  Time since processes crashed:");
10902                        printed = true;
10903                        printedAnything = true;
10904                    }
10905                    pw.print("    Process "); pw.print(pname);
10906                            pw.print(" uid "); pw.print(puid);
10907                            pw.print(": last crashed ");
10908                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
10909                            pw.println(" ago");
10910                }
10911            }
10912        }
10913
10914        if (mBadProcesses.getMap().size() > 0) {
10915            boolean printed = false;
10916            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
10917            final int NP = pmap.size();
10918            for (int ip=0; ip<NP; ip++) {
10919                String pname = pmap.keyAt(ip);
10920                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
10921                final int N = uids.size();
10922                for (int i=0; i<N; i++) {
10923                    int puid = uids.keyAt(i);
10924                    ProcessRecord r = mProcessNames.get(pname, puid);
10925                    if (dumpPackage != null && (r == null
10926                            || !r.pkgList.containsKey(dumpPackage))) {
10927                        continue;
10928                    }
10929                    if (!printed) {
10930                        if (needSep) pw.println();
10931                        needSep = true;
10932                        pw.println("  Bad processes:");
10933                        printedAnything = true;
10934                    }
10935                    BadProcessInfo info = uids.valueAt(i);
10936                    pw.print("    Bad process "); pw.print(pname);
10937                            pw.print(" uid "); pw.print(puid);
10938                            pw.print(": crashed at time "); pw.println(info.time);
10939                    if (info.shortMsg != null) {
10940                        pw.print("      Short msg: "); pw.println(info.shortMsg);
10941                    }
10942                    if (info.longMsg != null) {
10943                        pw.print("      Long msg: "); pw.println(info.longMsg);
10944                    }
10945                    if (info.stack != null) {
10946                        pw.println("      Stack:");
10947                        int lastPos = 0;
10948                        for (int pos=0; pos<info.stack.length(); pos++) {
10949                            if (info.stack.charAt(pos) == '\n') {
10950                                pw.print("        ");
10951                                pw.write(info.stack, lastPos, pos-lastPos);
10952                                pw.println();
10953                                lastPos = pos+1;
10954                            }
10955                        }
10956                        if (lastPos < info.stack.length()) {
10957                            pw.print("        ");
10958                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
10959                            pw.println();
10960                        }
10961                    }
10962                }
10963            }
10964        }
10965
10966        if (dumpPackage == null) {
10967            pw.println();
10968            needSep = false;
10969            pw.println("  mStartedUsers:");
10970            for (int i=0; i<mStartedUsers.size(); i++) {
10971                UserStartedState uss = mStartedUsers.valueAt(i);
10972                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
10973                        pw.print(": "); uss.dump("", pw);
10974            }
10975            pw.print("  mStartedUserArray: [");
10976            for (int i=0; i<mStartedUserArray.length; i++) {
10977                if (i > 0) pw.print(", ");
10978                pw.print(mStartedUserArray[i]);
10979            }
10980            pw.println("]");
10981            pw.print("  mUserLru: [");
10982            for (int i=0; i<mUserLru.size(); i++) {
10983                if (i > 0) pw.print(", ");
10984                pw.print(mUserLru.get(i));
10985            }
10986            pw.println("]");
10987            if (dumpAll) {
10988                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
10989            }
10990        }
10991        if (mHomeProcess != null && (dumpPackage == null
10992                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
10993            if (needSep) {
10994                pw.println();
10995                needSep = false;
10996            }
10997            pw.println("  mHomeProcess: " + mHomeProcess);
10998        }
10999        if (mPreviousProcess != null && (dumpPackage == null
11000                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11001            if (needSep) {
11002                pw.println();
11003                needSep = false;
11004            }
11005            pw.println("  mPreviousProcess: " + mPreviousProcess);
11006        }
11007        if (dumpAll) {
11008            StringBuilder sb = new StringBuilder(128);
11009            sb.append("  mPreviousProcessVisibleTime: ");
11010            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11011            pw.println(sb);
11012        }
11013        if (mHeavyWeightProcess != null && (dumpPackage == null
11014                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11015            if (needSep) {
11016                pw.println();
11017                needSep = false;
11018            }
11019            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11020        }
11021        if (dumpPackage == null) {
11022            pw.println("  mConfiguration: " + mConfiguration);
11023        }
11024        if (dumpAll) {
11025            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11026            if (mCompatModePackages.getPackages().size() > 0) {
11027                boolean printed = false;
11028                for (Map.Entry<String, Integer> entry
11029                        : mCompatModePackages.getPackages().entrySet()) {
11030                    String pkg = entry.getKey();
11031                    int mode = entry.getValue();
11032                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11033                        continue;
11034                    }
11035                    if (!printed) {
11036                        pw.println("  mScreenCompatPackages:");
11037                        printed = true;
11038                    }
11039                    pw.print("    "); pw.print(pkg); pw.print(": ");
11040                            pw.print(mode); pw.println();
11041                }
11042            }
11043        }
11044        if (dumpPackage == null) {
11045            if (mSleeping || mWentToSleep || mLockScreenShown) {
11046                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11047                        + " mLockScreenShown " + mLockScreenShown);
11048            }
11049            if (mShuttingDown) {
11050                pw.println("  mShuttingDown=" + mShuttingDown);
11051            }
11052        }
11053        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11054                || mOrigWaitForDebugger) {
11055            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11056                    || dumpPackage.equals(mOrigDebugApp)) {
11057                if (needSep) {
11058                    pw.println();
11059                    needSep = false;
11060                }
11061                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11062                        + " mDebugTransient=" + mDebugTransient
11063                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11064            }
11065        }
11066        if (mOpenGlTraceApp != null) {
11067            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11068                if (needSep) {
11069                    pw.println();
11070                    needSep = false;
11071                }
11072                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11073            }
11074        }
11075        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11076                || mProfileFd != null) {
11077            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11078                if (needSep) {
11079                    pw.println();
11080                    needSep = false;
11081                }
11082                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11083                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11084                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11085                        + mAutoStopProfiler);
11086            }
11087        }
11088        if (dumpPackage == null) {
11089            if (mAlwaysFinishActivities || mController != null) {
11090                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11091                        + " mController=" + mController);
11092            }
11093            if (dumpAll) {
11094                pw.println("  Total persistent processes: " + numPers);
11095                pw.println("  mStartRunning=" + mStartRunning
11096                        + " mProcessesReady=" + mProcessesReady
11097                        + " mSystemReady=" + mSystemReady);
11098                pw.println("  mBooting=" + mBooting
11099                        + " mBooted=" + mBooted
11100                        + " mFactoryTest=" + mFactoryTest);
11101                pw.print("  mLastPowerCheckRealtime=");
11102                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11103                        pw.println("");
11104                pw.print("  mLastPowerCheckUptime=");
11105                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11106                        pw.println("");
11107                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11108                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11109                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11110                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11111                        + " (" + mLruProcesses.size() + " total)"
11112                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11113                        + " mNumServiceProcs=" + mNumServiceProcs
11114                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11115                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11116                        + " mLastMemoryLevel" + mLastMemoryLevel
11117                        + " mLastNumProcesses" + mLastNumProcesses);
11118                long now = SystemClock.uptimeMillis();
11119                pw.print("  mLastIdleTime=");
11120                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11121                        pw.print(" mLowRamSinceLastIdle=");
11122                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11123                        pw.println();
11124            }
11125        }
11126
11127        if (!printedAnything) {
11128            pw.println("  (nothing)");
11129        }
11130    }
11131
11132    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11133            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11134        if (mProcessesToGc.size() > 0) {
11135            boolean printed = false;
11136            long now = SystemClock.uptimeMillis();
11137            for (int i=0; i<mProcessesToGc.size(); i++) {
11138                ProcessRecord proc = mProcessesToGc.get(i);
11139                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11140                    continue;
11141                }
11142                if (!printed) {
11143                    if (needSep) pw.println();
11144                    needSep = true;
11145                    pw.println("  Processes that are waiting to GC:");
11146                    printed = true;
11147                }
11148                pw.print("    Process "); pw.println(proc);
11149                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11150                        pw.print(", last gced=");
11151                        pw.print(now-proc.lastRequestedGc);
11152                        pw.print(" ms ago, last lowMem=");
11153                        pw.print(now-proc.lastLowMemory);
11154                        pw.println(" ms ago");
11155
11156            }
11157        }
11158        return needSep;
11159    }
11160
11161    void printOomLevel(PrintWriter pw, String name, int adj) {
11162        pw.print("    ");
11163        if (adj >= 0) {
11164            pw.print(' ');
11165            if (adj < 10) pw.print(' ');
11166        } else {
11167            if (adj > -10) pw.print(' ');
11168        }
11169        pw.print(adj);
11170        pw.print(": ");
11171        pw.print(name);
11172        pw.print(" (");
11173        pw.print(mProcessList.getMemLevel(adj)/1024);
11174        pw.println(" kB)");
11175    }
11176
11177    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11178            int opti, boolean dumpAll) {
11179        boolean needSep = false;
11180
11181        if (mLruProcesses.size() > 0) {
11182            if (needSep) pw.println();
11183            needSep = true;
11184            pw.println("  OOM levels:");
11185            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11186            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11187            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11188            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11189            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11190            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11191            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11192            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11193            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11194            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11195            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11196            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11197            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11198
11199            if (needSep) pw.println();
11200            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11201                    pw.print(" total, non-act at ");
11202                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11203                    pw.print(", non-svc at ");
11204                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11205                    pw.println("):");
11206            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11207            needSep = true;
11208        }
11209
11210        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11211
11212        pw.println();
11213        pw.println("  mHomeProcess: " + mHomeProcess);
11214        pw.println("  mPreviousProcess: " + mPreviousProcess);
11215        if (mHeavyWeightProcess != null) {
11216            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11217        }
11218
11219        return true;
11220    }
11221
11222    /**
11223     * There are three ways to call this:
11224     *  - no provider specified: dump all the providers
11225     *  - a flattened component name that matched an existing provider was specified as the
11226     *    first arg: dump that one provider
11227     *  - the first arg isn't the flattened component name of an existing provider:
11228     *    dump all providers whose component contains the first arg as a substring
11229     */
11230    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11231            int opti, boolean dumpAll) {
11232        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11233    }
11234
11235    static class ItemMatcher {
11236        ArrayList<ComponentName> components;
11237        ArrayList<String> strings;
11238        ArrayList<Integer> objects;
11239        boolean all;
11240
11241        ItemMatcher() {
11242            all = true;
11243        }
11244
11245        void build(String name) {
11246            ComponentName componentName = ComponentName.unflattenFromString(name);
11247            if (componentName != null) {
11248                if (components == null) {
11249                    components = new ArrayList<ComponentName>();
11250                }
11251                components.add(componentName);
11252                all = false;
11253            } else {
11254                int objectId = 0;
11255                // Not a '/' separated full component name; maybe an object ID?
11256                try {
11257                    objectId = Integer.parseInt(name, 16);
11258                    if (objects == null) {
11259                        objects = new ArrayList<Integer>();
11260                    }
11261                    objects.add(objectId);
11262                    all = false;
11263                } catch (RuntimeException e) {
11264                    // Not an integer; just do string match.
11265                    if (strings == null) {
11266                        strings = new ArrayList<String>();
11267                    }
11268                    strings.add(name);
11269                    all = false;
11270                }
11271            }
11272        }
11273
11274        int build(String[] args, int opti) {
11275            for (; opti<args.length; opti++) {
11276                String name = args[opti];
11277                if ("--".equals(name)) {
11278                    return opti+1;
11279                }
11280                build(name);
11281            }
11282            return opti;
11283        }
11284
11285        boolean match(Object object, ComponentName comp) {
11286            if (all) {
11287                return true;
11288            }
11289            if (components != null) {
11290                for (int i=0; i<components.size(); i++) {
11291                    if (components.get(i).equals(comp)) {
11292                        return true;
11293                    }
11294                }
11295            }
11296            if (objects != null) {
11297                for (int i=0; i<objects.size(); i++) {
11298                    if (System.identityHashCode(object) == objects.get(i)) {
11299                        return true;
11300                    }
11301                }
11302            }
11303            if (strings != null) {
11304                String flat = comp.flattenToString();
11305                for (int i=0; i<strings.size(); i++) {
11306                    if (flat.contains(strings.get(i))) {
11307                        return true;
11308                    }
11309                }
11310            }
11311            return false;
11312        }
11313    }
11314
11315    /**
11316     * There are three things that cmd can be:
11317     *  - a flattened component name that matches an existing activity
11318     *  - the cmd arg isn't the flattened component name of an existing activity:
11319     *    dump all activity whose component contains the cmd as a substring
11320     *  - A hex number of the ActivityRecord object instance.
11321     */
11322    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11323            int opti, boolean dumpAll) {
11324        ArrayList<ActivityRecord> activities;
11325
11326        synchronized (this) {
11327            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11328        }
11329
11330        if (activities.size() <= 0) {
11331            return false;
11332        }
11333
11334        String[] newArgs = new String[args.length - opti];
11335        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11336
11337        TaskRecord lastTask = null;
11338        boolean needSep = false;
11339        for (int i=activities.size()-1; i>=0; i--) {
11340            ActivityRecord r = activities.get(i);
11341            if (needSep) {
11342                pw.println();
11343            }
11344            needSep = true;
11345            synchronized (this) {
11346                if (lastTask != r.task) {
11347                    lastTask = r.task;
11348                    pw.print("TASK "); pw.print(lastTask.affinity);
11349                            pw.print(" id="); pw.println(lastTask.taskId);
11350                    if (dumpAll) {
11351                        lastTask.dump(pw, "  ");
11352                    }
11353                }
11354            }
11355            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11356        }
11357        return true;
11358    }
11359
11360    /**
11361     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11362     * there is a thread associated with the activity.
11363     */
11364    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11365            final ActivityRecord r, String[] args, boolean dumpAll) {
11366        String innerPrefix = prefix + "  ";
11367        synchronized (this) {
11368            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11369                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11370                    pw.print(" pid=");
11371                    if (r.app != null) pw.println(r.app.pid);
11372                    else pw.println("(not running)");
11373            if (dumpAll) {
11374                r.dump(pw, innerPrefix);
11375            }
11376        }
11377        if (r.app != null && r.app.thread != null) {
11378            // flush anything that is already in the PrintWriter since the thread is going
11379            // to write to the file descriptor directly
11380            pw.flush();
11381            try {
11382                TransferPipe tp = new TransferPipe();
11383                try {
11384                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11385                            r.appToken, innerPrefix, args);
11386                    tp.go(fd);
11387                } finally {
11388                    tp.kill();
11389                }
11390            } catch (IOException e) {
11391                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11392            } catch (RemoteException e) {
11393                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11394            }
11395        }
11396    }
11397
11398    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11399            int opti, boolean dumpAll, String dumpPackage) {
11400        boolean needSep = false;
11401        boolean onlyHistory = false;
11402        boolean printedAnything = false;
11403
11404        if ("history".equals(dumpPackage)) {
11405            if (opti < args.length && "-s".equals(args[opti])) {
11406                dumpAll = false;
11407            }
11408            onlyHistory = true;
11409            dumpPackage = null;
11410        }
11411
11412        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11413        if (!onlyHistory && dumpAll) {
11414            if (mRegisteredReceivers.size() > 0) {
11415                boolean printed = false;
11416                Iterator it = mRegisteredReceivers.values().iterator();
11417                while (it.hasNext()) {
11418                    ReceiverList r = (ReceiverList)it.next();
11419                    if (dumpPackage != null && (r.app == null ||
11420                            !dumpPackage.equals(r.app.info.packageName))) {
11421                        continue;
11422                    }
11423                    if (!printed) {
11424                        pw.println("  Registered Receivers:");
11425                        needSep = true;
11426                        printed = true;
11427                        printedAnything = true;
11428                    }
11429                    pw.print("  * "); pw.println(r);
11430                    r.dump(pw, "    ");
11431                }
11432            }
11433
11434            if (mReceiverResolver.dump(pw, needSep ?
11435                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11436                    "    ", dumpPackage, false)) {
11437                needSep = true;
11438                printedAnything = true;
11439            }
11440        }
11441
11442        for (BroadcastQueue q : mBroadcastQueues) {
11443            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11444            printedAnything |= needSep;
11445        }
11446
11447        needSep = true;
11448
11449        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11450            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11451                if (needSep) {
11452                    pw.println();
11453                }
11454                needSep = true;
11455                printedAnything = true;
11456                pw.print("  Sticky broadcasts for user ");
11457                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11458                StringBuilder sb = new StringBuilder(128);
11459                for (Map.Entry<String, ArrayList<Intent>> ent
11460                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11461                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11462                    if (dumpAll) {
11463                        pw.println(":");
11464                        ArrayList<Intent> intents = ent.getValue();
11465                        final int N = intents.size();
11466                        for (int i=0; i<N; i++) {
11467                            sb.setLength(0);
11468                            sb.append("    Intent: ");
11469                            intents.get(i).toShortString(sb, false, true, false, false);
11470                            pw.println(sb.toString());
11471                            Bundle bundle = intents.get(i).getExtras();
11472                            if (bundle != null) {
11473                                pw.print("      ");
11474                                pw.println(bundle.toString());
11475                            }
11476                        }
11477                    } else {
11478                        pw.println("");
11479                    }
11480                }
11481            }
11482        }
11483
11484        if (!onlyHistory && dumpAll) {
11485            pw.println();
11486            for (BroadcastQueue queue : mBroadcastQueues) {
11487                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11488                        + queue.mBroadcastsScheduled);
11489            }
11490            pw.println("  mHandler:");
11491            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11492            needSep = true;
11493            printedAnything = true;
11494        }
11495
11496        if (!printedAnything) {
11497            pw.println("  (nothing)");
11498        }
11499    }
11500
11501    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11502            int opti, boolean dumpAll, String dumpPackage) {
11503        boolean needSep;
11504        boolean printedAnything = false;
11505
11506        ItemMatcher matcher = new ItemMatcher();
11507        matcher.build(args, opti);
11508
11509        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11510
11511        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11512        printedAnything |= needSep;
11513
11514        if (mLaunchingProviders.size() > 0) {
11515            boolean printed = false;
11516            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11517                ContentProviderRecord r = mLaunchingProviders.get(i);
11518                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11519                    continue;
11520                }
11521                if (!printed) {
11522                    if (needSep) pw.println();
11523                    needSep = true;
11524                    pw.println("  Launching content providers:");
11525                    printed = true;
11526                    printedAnything = true;
11527                }
11528                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11529                        pw.println(r);
11530            }
11531        }
11532
11533        if (mGrantedUriPermissions.size() > 0) {
11534            boolean printed = false;
11535            int dumpUid = -2;
11536            if (dumpPackage != null) {
11537                try {
11538                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11539                } catch (NameNotFoundException e) {
11540                    dumpUid = -1;
11541                }
11542            }
11543            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11544                int uid = mGrantedUriPermissions.keyAt(i);
11545                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11546                    continue;
11547                }
11548                ArrayMap<Uri, UriPermission> perms
11549                        = mGrantedUriPermissions.valueAt(i);
11550                if (!printed) {
11551                    if (needSep) pw.println();
11552                    needSep = true;
11553                    pw.println("  Granted Uri Permissions:");
11554                    printed = true;
11555                    printedAnything = true;
11556                }
11557                pw.print("  * UID "); pw.print(uid);
11558                        pw.println(" holds:");
11559                for (UriPermission perm : perms.values()) {
11560                    pw.print("    "); pw.println(perm);
11561                    if (dumpAll) {
11562                        perm.dump(pw, "      ");
11563                    }
11564                }
11565            }
11566        }
11567
11568        if (!printedAnything) {
11569            pw.println("  (nothing)");
11570        }
11571    }
11572
11573    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11574            int opti, boolean dumpAll, String dumpPackage) {
11575        boolean printed = false;
11576
11577        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11578
11579        if (mIntentSenderRecords.size() > 0) {
11580            Iterator<WeakReference<PendingIntentRecord>> it
11581                    = mIntentSenderRecords.values().iterator();
11582            while (it.hasNext()) {
11583                WeakReference<PendingIntentRecord> ref = it.next();
11584                PendingIntentRecord rec = ref != null ? ref.get(): null;
11585                if (dumpPackage != null && (rec == null
11586                        || !dumpPackage.equals(rec.key.packageName))) {
11587                    continue;
11588                }
11589                printed = true;
11590                if (rec != null) {
11591                    pw.print("  * "); pw.println(rec);
11592                    if (dumpAll) {
11593                        rec.dump(pw, "    ");
11594                    }
11595                } else {
11596                    pw.print("  * "); pw.println(ref);
11597                }
11598            }
11599        }
11600
11601        if (!printed) {
11602            pw.println("  (nothing)");
11603        }
11604    }
11605
11606    private static final int dumpProcessList(PrintWriter pw,
11607            ActivityManagerService service, List list,
11608            String prefix, String normalLabel, String persistentLabel,
11609            String dumpPackage) {
11610        int numPers = 0;
11611        final int N = list.size()-1;
11612        for (int i=N; i>=0; i--) {
11613            ProcessRecord r = (ProcessRecord)list.get(i);
11614            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11615                continue;
11616            }
11617            pw.println(String.format("%s%s #%2d: %s",
11618                    prefix, (r.persistent ? persistentLabel : normalLabel),
11619                    i, r.toString()));
11620            if (r.persistent) {
11621                numPers++;
11622            }
11623        }
11624        return numPers;
11625    }
11626
11627    private static final boolean dumpProcessOomList(PrintWriter pw,
11628            ActivityManagerService service, List<ProcessRecord> origList,
11629            String prefix, String normalLabel, String persistentLabel,
11630            boolean inclDetails, String dumpPackage) {
11631
11632        ArrayList<Pair<ProcessRecord, Integer>> list
11633                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11634        for (int i=0; i<origList.size(); i++) {
11635            ProcessRecord r = origList.get(i);
11636            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11637                continue;
11638            }
11639            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11640        }
11641
11642        if (list.size() <= 0) {
11643            return false;
11644        }
11645
11646        Comparator<Pair<ProcessRecord, Integer>> comparator
11647                = new Comparator<Pair<ProcessRecord, Integer>>() {
11648            @Override
11649            public int compare(Pair<ProcessRecord, Integer> object1,
11650                    Pair<ProcessRecord, Integer> object2) {
11651                if (object1.first.setAdj != object2.first.setAdj) {
11652                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11653                }
11654                if (object1.second.intValue() != object2.second.intValue()) {
11655                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11656                }
11657                return 0;
11658            }
11659        };
11660
11661        Collections.sort(list, comparator);
11662
11663        final long curRealtime = SystemClock.elapsedRealtime();
11664        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11665        final long curUptime = SystemClock.uptimeMillis();
11666        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11667
11668        for (int i=list.size()-1; i>=0; i--) {
11669            ProcessRecord r = list.get(i).first;
11670            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11671            char schedGroup;
11672            switch (r.setSchedGroup) {
11673                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11674                    schedGroup = 'B';
11675                    break;
11676                case Process.THREAD_GROUP_DEFAULT:
11677                    schedGroup = 'F';
11678                    break;
11679                default:
11680                    schedGroup = '?';
11681                    break;
11682            }
11683            char foreground;
11684            if (r.foregroundActivities) {
11685                foreground = 'A';
11686            } else if (r.foregroundServices) {
11687                foreground = 'S';
11688            } else {
11689                foreground = ' ';
11690            }
11691            String procState = ProcessList.makeProcStateString(r.curProcState);
11692            pw.print(prefix);
11693            pw.print(r.persistent ? persistentLabel : normalLabel);
11694            pw.print(" #");
11695            int num = (origList.size()-1)-list.get(i).second;
11696            if (num < 10) pw.print(' ');
11697            pw.print(num);
11698            pw.print(": ");
11699            pw.print(oomAdj);
11700            pw.print(' ');
11701            pw.print(schedGroup);
11702            pw.print('/');
11703            pw.print(foreground);
11704            pw.print('/');
11705            pw.print(procState);
11706            pw.print(" trm:");
11707            if (r.trimMemoryLevel < 10) pw.print(' ');
11708            pw.print(r.trimMemoryLevel);
11709            pw.print(' ');
11710            pw.print(r.toShortString());
11711            pw.print(" (");
11712            pw.print(r.adjType);
11713            pw.println(')');
11714            if (r.adjSource != null || r.adjTarget != null) {
11715                pw.print(prefix);
11716                pw.print("    ");
11717                if (r.adjTarget instanceof ComponentName) {
11718                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11719                } else if (r.adjTarget != null) {
11720                    pw.print(r.adjTarget.toString());
11721                } else {
11722                    pw.print("{null}");
11723                }
11724                pw.print("<=");
11725                if (r.adjSource instanceof ProcessRecord) {
11726                    pw.print("Proc{");
11727                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11728                    pw.println("}");
11729                } else if (r.adjSource != null) {
11730                    pw.println(r.adjSource.toString());
11731                } else {
11732                    pw.println("{null}");
11733                }
11734            }
11735            if (inclDetails) {
11736                pw.print(prefix);
11737                pw.print("    ");
11738                pw.print("oom: max="); pw.print(r.maxAdj);
11739                pw.print(" curRaw="); pw.print(r.curRawAdj);
11740                pw.print(" setRaw="); pw.print(r.setRawAdj);
11741                pw.print(" cur="); pw.print(r.curAdj);
11742                pw.print(" set="); pw.println(r.setAdj);
11743                pw.print(prefix);
11744                pw.print("    ");
11745                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
11746                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
11747                pw.print(" lastPss="); pw.print(r.lastPss);
11748                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
11749                pw.print(prefix);
11750                pw.print("    ");
11751                pw.print("keeping="); pw.print(r.keeping);
11752                pw.print(" cached="); pw.print(r.cached);
11753                pw.print(" empty="); pw.print(r.empty);
11754                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
11755
11756                if (!r.keeping) {
11757                    if (r.lastWakeTime != 0) {
11758                        long wtime;
11759                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
11760                        synchronized (stats) {
11761                            wtime = stats.getProcessWakeTime(r.info.uid,
11762                                    r.pid, curRealtime);
11763                        }
11764                        long timeUsed = wtime - r.lastWakeTime;
11765                        pw.print(prefix);
11766                        pw.print("    ");
11767                        pw.print("keep awake over ");
11768                        TimeUtils.formatDuration(realtimeSince, pw);
11769                        pw.print(" used ");
11770                        TimeUtils.formatDuration(timeUsed, pw);
11771                        pw.print(" (");
11772                        pw.print((timeUsed*100)/realtimeSince);
11773                        pw.println("%)");
11774                    }
11775                    if (r.lastCpuTime != 0) {
11776                        long timeUsed = r.curCpuTime - r.lastCpuTime;
11777                        pw.print(prefix);
11778                        pw.print("    ");
11779                        pw.print("run cpu over ");
11780                        TimeUtils.formatDuration(uptimeSince, pw);
11781                        pw.print(" used ");
11782                        TimeUtils.formatDuration(timeUsed, pw);
11783                        pw.print(" (");
11784                        pw.print((timeUsed*100)/uptimeSince);
11785                        pw.println("%)");
11786                    }
11787                }
11788            }
11789        }
11790        return true;
11791    }
11792
11793    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
11794        ArrayList<ProcessRecord> procs;
11795        synchronized (this) {
11796            if (args != null && args.length > start
11797                    && args[start].charAt(0) != '-') {
11798                procs = new ArrayList<ProcessRecord>();
11799                int pid = -1;
11800                try {
11801                    pid = Integer.parseInt(args[start]);
11802                } catch (NumberFormatException e) {
11803                }
11804                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11805                    ProcessRecord proc = mLruProcesses.get(i);
11806                    if (proc.pid == pid) {
11807                        procs.add(proc);
11808                    } else if (proc.processName.equals(args[start])) {
11809                        procs.add(proc);
11810                    }
11811                }
11812                if (procs.size() <= 0) {
11813                    return null;
11814                }
11815            } else {
11816                procs = new ArrayList<ProcessRecord>(mLruProcesses);
11817            }
11818        }
11819        return procs;
11820    }
11821
11822    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
11823            PrintWriter pw, String[] args) {
11824        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11825        if (procs == null) {
11826            pw.println("No process found for: " + args[0]);
11827            return;
11828        }
11829
11830        long uptime = SystemClock.uptimeMillis();
11831        long realtime = SystemClock.elapsedRealtime();
11832        pw.println("Applications Graphics Acceleration Info:");
11833        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11834
11835        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11836            ProcessRecord r = procs.get(i);
11837            if (r.thread != null) {
11838                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
11839                pw.flush();
11840                try {
11841                    TransferPipe tp = new TransferPipe();
11842                    try {
11843                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
11844                        tp.go(fd);
11845                    } finally {
11846                        tp.kill();
11847                    }
11848                } catch (IOException e) {
11849                    pw.println("Failure while dumping the app: " + r);
11850                    pw.flush();
11851                } catch (RemoteException e) {
11852                    pw.println("Got a RemoteException while dumping the app " + r);
11853                    pw.flush();
11854                }
11855            }
11856        }
11857    }
11858
11859    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
11860        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11861        if (procs == null) {
11862            pw.println("No process found for: " + args[0]);
11863            return;
11864        }
11865
11866        pw.println("Applications Database Info:");
11867
11868        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11869            ProcessRecord r = procs.get(i);
11870            if (r.thread != null) {
11871                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
11872                pw.flush();
11873                try {
11874                    TransferPipe tp = new TransferPipe();
11875                    try {
11876                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
11877                        tp.go(fd);
11878                    } finally {
11879                        tp.kill();
11880                    }
11881                } catch (IOException e) {
11882                    pw.println("Failure while dumping the app: " + r);
11883                    pw.flush();
11884                } catch (RemoteException e) {
11885                    pw.println("Got a RemoteException while dumping the app " + r);
11886                    pw.flush();
11887                }
11888            }
11889        }
11890    }
11891
11892    final static class MemItem {
11893        final boolean isProc;
11894        final String label;
11895        final String shortLabel;
11896        final long pss;
11897        final int id;
11898        final boolean hasActivities;
11899        ArrayList<MemItem> subitems;
11900
11901        public MemItem(String _label, String _shortLabel, long _pss, int _id,
11902                boolean _hasActivities) {
11903            isProc = true;
11904            label = _label;
11905            shortLabel = _shortLabel;
11906            pss = _pss;
11907            id = _id;
11908            hasActivities = _hasActivities;
11909        }
11910
11911        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
11912            isProc = false;
11913            label = _label;
11914            shortLabel = _shortLabel;
11915            pss = _pss;
11916            id = _id;
11917            hasActivities = false;
11918        }
11919    }
11920
11921    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
11922            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
11923        if (sort && !isCompact) {
11924            Collections.sort(items, new Comparator<MemItem>() {
11925                @Override
11926                public int compare(MemItem lhs, MemItem rhs) {
11927                    if (lhs.pss < rhs.pss) {
11928                        return 1;
11929                    } else if (lhs.pss > rhs.pss) {
11930                        return -1;
11931                    }
11932                    return 0;
11933                }
11934            });
11935        }
11936
11937        for (int i=0; i<items.size(); i++) {
11938            MemItem mi = items.get(i);
11939            if (!isCompact) {
11940                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
11941            } else if (mi.isProc) {
11942                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
11943                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
11944                pw.println(mi.hasActivities ? ",a" : ",e");
11945            } else {
11946                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
11947                pw.println(mi.pss);
11948            }
11949            if (mi.subitems != null) {
11950                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
11951                        true, isCompact);
11952            }
11953        }
11954    }
11955
11956    // These are in KB.
11957    static final long[] DUMP_MEM_BUCKETS = new long[] {
11958        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
11959        120*1024, 160*1024, 200*1024,
11960        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
11961        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
11962    };
11963
11964    static final void appendMemBucket(StringBuilder out, long memKB, String label,
11965            boolean stackLike) {
11966        int start = label.lastIndexOf('.');
11967        if (start >= 0) start++;
11968        else start = 0;
11969        int end = label.length();
11970        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
11971            if (DUMP_MEM_BUCKETS[i] >= memKB) {
11972                long bucket = DUMP_MEM_BUCKETS[i]/1024;
11973                out.append(bucket);
11974                out.append(stackLike ? "MB." : "MB ");
11975                out.append(label, start, end);
11976                return;
11977            }
11978        }
11979        out.append(memKB/1024);
11980        out.append(stackLike ? "MB." : "MB ");
11981        out.append(label, start, end);
11982    }
11983
11984    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
11985            ProcessList.NATIVE_ADJ,
11986            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
11987            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
11988            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
11989            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
11990            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
11991    };
11992    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
11993            "Native",
11994            "System", "Persistent", "Foreground",
11995            "Visible", "Perceptible",
11996            "Heavy Weight", "Backup",
11997            "A Services", "Home",
11998            "Previous", "B Services", "Cached"
11999    };
12000    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12001            "native",
12002            "sys", "pers", "fore",
12003            "vis", "percept",
12004            "heavy", "backup",
12005            "servicea", "home",
12006            "prev", "serviceb", "cached"
12007    };
12008
12009    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12010            long realtime, boolean isCheckinRequest, boolean isCompact) {
12011        if (isCheckinRequest || isCompact) {
12012            // short checkin version
12013            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12014        } else {
12015            pw.println("Applications Memory Usage (kB):");
12016            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12017        }
12018    }
12019
12020    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12021            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12022        boolean dumpDetails = false;
12023        boolean dumpFullDetails = false;
12024        boolean dumpDalvik = false;
12025        boolean oomOnly = false;
12026        boolean isCompact = false;
12027        boolean localOnly = false;
12028
12029        int opti = 0;
12030        while (opti < args.length) {
12031            String opt = args[opti];
12032            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12033                break;
12034            }
12035            opti++;
12036            if ("-a".equals(opt)) {
12037                dumpDetails = true;
12038                dumpFullDetails = true;
12039                dumpDalvik = true;
12040            } else if ("-d".equals(opt)) {
12041                dumpDalvik = true;
12042            } else if ("-c".equals(opt)) {
12043                isCompact = true;
12044            } else if ("--oom".equals(opt)) {
12045                oomOnly = true;
12046            } else if ("--local".equals(opt)) {
12047                localOnly = true;
12048            } else if ("-h".equals(opt)) {
12049                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12050                pw.println("  -a: include all available information for each process.");
12051                pw.println("  -d: include dalvik details when dumping process details.");
12052                pw.println("  -c: dump in a compact machine-parseable representation.");
12053                pw.println("  --oom: only show processes organized by oom adj.");
12054                pw.println("  --local: only collect details locally, don't call process.");
12055                pw.println("If [process] is specified it can be the name or ");
12056                pw.println("pid of a specific process to dump.");
12057                return;
12058            } else {
12059                pw.println("Unknown argument: " + opt + "; use -h for help");
12060            }
12061        }
12062
12063        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12064        long uptime = SystemClock.uptimeMillis();
12065        long realtime = SystemClock.elapsedRealtime();
12066        final long[] tmpLong = new long[1];
12067
12068        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12069        if (procs == null) {
12070            // No Java processes.  Maybe they want to print a native process.
12071            if (args != null && args.length > opti
12072                    && args[opti].charAt(0) != '-') {
12073                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12074                        = new ArrayList<ProcessCpuTracker.Stats>();
12075                updateCpuStatsNow();
12076                int findPid = -1;
12077                try {
12078                    findPid = Integer.parseInt(args[opti]);
12079                } catch (NumberFormatException e) {
12080                }
12081                synchronized (mProcessCpuThread) {
12082                    final int N = mProcessCpuTracker.countStats();
12083                    for (int i=0; i<N; i++) {
12084                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12085                        if (st.pid == findPid || (st.baseName != null
12086                                && st.baseName.equals(args[opti]))) {
12087                            nativeProcs.add(st);
12088                        }
12089                    }
12090                }
12091                if (nativeProcs.size() > 0) {
12092                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12093                            isCompact);
12094                    Debug.MemoryInfo mi = null;
12095                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12096                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12097                        final int pid = r.pid;
12098                        if (!isCheckinRequest && dumpDetails) {
12099                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12100                        }
12101                        if (mi == null) {
12102                            mi = new Debug.MemoryInfo();
12103                        }
12104                        if (dumpDetails || (!brief && !oomOnly)) {
12105                            Debug.getMemoryInfo(pid, mi);
12106                        } else {
12107                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12108                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12109                        }
12110                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12111                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12112                        if (isCheckinRequest) {
12113                            pw.println();
12114                        }
12115                    }
12116                    return;
12117                }
12118            }
12119            pw.println("No process found for: " + args[opti]);
12120            return;
12121        }
12122
12123        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12124            dumpDetails = true;
12125        }
12126
12127        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12128
12129        String[] innerArgs = new String[args.length-opti];
12130        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12131
12132        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12133        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12134        long nativePss=0, dalvikPss=0, otherPss=0;
12135        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12136
12137        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12138        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12139                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12140
12141        long totalPss = 0;
12142        long cachedPss = 0;
12143
12144        Debug.MemoryInfo mi = null;
12145        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12146            final ProcessRecord r = procs.get(i);
12147            final IApplicationThread thread;
12148            final int pid;
12149            final int oomAdj;
12150            final boolean hasActivities;
12151            synchronized (this) {
12152                thread = r.thread;
12153                pid = r.pid;
12154                oomAdj = r.getSetAdjWithServices();
12155                hasActivities = r.activities.size() > 0;
12156            }
12157            if (thread != null) {
12158                if (!isCheckinRequest && dumpDetails) {
12159                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12160                }
12161                if (mi == null) {
12162                    mi = new Debug.MemoryInfo();
12163                }
12164                if (dumpDetails || (!brief && !oomOnly)) {
12165                    Debug.getMemoryInfo(pid, mi);
12166                } else {
12167                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12168                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12169                }
12170                if (dumpDetails) {
12171                    if (localOnly) {
12172                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12173                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12174                        if (isCheckinRequest) {
12175                            pw.println();
12176                        }
12177                    } else {
12178                        try {
12179                            pw.flush();
12180                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12181                                    dumpDalvik, innerArgs);
12182                        } catch (RemoteException e) {
12183                            if (!isCheckinRequest) {
12184                                pw.println("Got RemoteException!");
12185                                pw.flush();
12186                            }
12187                        }
12188                    }
12189                }
12190
12191                final long myTotalPss = mi.getTotalPss();
12192                final long myTotalUss = mi.getTotalUss();
12193
12194                synchronized (this) {
12195                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12196                        // Record this for posterity if the process has been stable.
12197                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12198                    }
12199                }
12200
12201                if (!isCheckinRequest && mi != null) {
12202                    totalPss += myTotalPss;
12203                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12204                            (hasActivities ? " / activities)" : ")"),
12205                            r.processName, myTotalPss, pid, hasActivities);
12206                    procMems.add(pssItem);
12207                    procMemsMap.put(pid, pssItem);
12208
12209                    nativePss += mi.nativePss;
12210                    dalvikPss += mi.dalvikPss;
12211                    otherPss += mi.otherPss;
12212                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12213                        long mem = mi.getOtherPss(j);
12214                        miscPss[j] += mem;
12215                        otherPss -= mem;
12216                    }
12217
12218                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12219                        cachedPss += myTotalPss;
12220                    }
12221
12222                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12223                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12224                                || oomIndex == (oomPss.length-1)) {
12225                            oomPss[oomIndex] += myTotalPss;
12226                            if (oomProcs[oomIndex] == null) {
12227                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12228                            }
12229                            oomProcs[oomIndex].add(pssItem);
12230                            break;
12231                        }
12232                    }
12233                }
12234            }
12235        }
12236
12237        if (!isCheckinRequest && procs.size() > 1) {
12238            // If we are showing aggregations, also look for native processes to
12239            // include so that our aggregations are more accurate.
12240            updateCpuStatsNow();
12241            synchronized (mProcessCpuThread) {
12242                final int N = mProcessCpuTracker.countStats();
12243                for (int i=0; i<N; i++) {
12244                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12245                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12246                        if (mi == null) {
12247                            mi = new Debug.MemoryInfo();
12248                        }
12249                        if (!brief && !oomOnly) {
12250                            Debug.getMemoryInfo(st.pid, mi);
12251                        } else {
12252                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12253                            mi.nativePrivateDirty = (int)tmpLong[0];
12254                        }
12255
12256                        final long myTotalPss = mi.getTotalPss();
12257                        totalPss += myTotalPss;
12258
12259                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12260                                st.name, myTotalPss, st.pid, false);
12261                        procMems.add(pssItem);
12262
12263                        nativePss += mi.nativePss;
12264                        dalvikPss += mi.dalvikPss;
12265                        otherPss += mi.otherPss;
12266                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12267                            long mem = mi.getOtherPss(j);
12268                            miscPss[j] += mem;
12269                            otherPss -= mem;
12270                        }
12271                        oomPss[0] += myTotalPss;
12272                        if (oomProcs[0] == null) {
12273                            oomProcs[0] = new ArrayList<MemItem>();
12274                        }
12275                        oomProcs[0].add(pssItem);
12276                    }
12277                }
12278            }
12279
12280            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12281
12282            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12283            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12284            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12285            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12286                String label = Debug.MemoryInfo.getOtherLabel(j);
12287                catMems.add(new MemItem(label, label, miscPss[j], j));
12288            }
12289
12290            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12291            for (int j=0; j<oomPss.length; j++) {
12292                if (oomPss[j] != 0) {
12293                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12294                            : DUMP_MEM_OOM_LABEL[j];
12295                    MemItem item = new MemItem(label, label, oomPss[j],
12296                            DUMP_MEM_OOM_ADJ[j]);
12297                    item.subitems = oomProcs[j];
12298                    oomMems.add(item);
12299                }
12300            }
12301
12302            if (!brief && !oomOnly && !isCompact) {
12303                pw.println();
12304                pw.println("Total PSS by process:");
12305                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12306                pw.println();
12307            }
12308            if (!isCompact) {
12309                pw.println("Total PSS by OOM adjustment:");
12310            }
12311            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12312            if (!brief && !oomOnly) {
12313                PrintWriter out = categoryPw != null ? categoryPw : pw;
12314                if (!isCompact) {
12315                    out.println();
12316                    out.println("Total PSS by category:");
12317                }
12318                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12319            }
12320            if (!isCompact) {
12321                pw.println();
12322            }
12323            MemInfoReader memInfo = new MemInfoReader();
12324            memInfo.readMemInfo();
12325            if (!brief) {
12326                if (!isCompact) {
12327                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12328                    pw.print(" kB (status ");
12329                    switch (mLastMemoryLevel) {
12330                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12331                            pw.println("normal)");
12332                            break;
12333                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12334                            pw.println("moderate)");
12335                            break;
12336                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12337                            pw.println("low)");
12338                            break;
12339                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12340                            pw.println("critical)");
12341                            break;
12342                        default:
12343                            pw.print(mLastMemoryLevel);
12344                            pw.println(")");
12345                            break;
12346                    }
12347                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12348                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12349                            pw.print(cachedPss); pw.print(" cached pss + ");
12350                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12351                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12352                } else {
12353                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12354                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12355                            + memInfo.getFreeSizeKb()); pw.print(",");
12356                    pw.println(totalPss - cachedPss);
12357                }
12358            }
12359            if (!isCompact) {
12360                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12361                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12362                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12363                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12364                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12365                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12366                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12367                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12368                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12369                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12370                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12371            }
12372            if (!brief) {
12373                if (memInfo.getZramTotalSizeKb() != 0) {
12374                    if (!isCompact) {
12375                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12376                                pw.print(" kB physical used for ");
12377                                pw.print(memInfo.getSwapTotalSizeKb()
12378                                        - memInfo.getSwapFreeSizeKb());
12379                                pw.print(" kB in swap (");
12380                                pw.print(memInfo.getSwapTotalSizeKb());
12381                                pw.println(" kB total swap)");
12382                    } else {
12383                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12384                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12385                                pw.println(memInfo.getSwapFreeSizeKb());
12386                    }
12387                }
12388                final int[] SINGLE_LONG_FORMAT = new int[] {
12389                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12390                };
12391                long[] longOut = new long[1];
12392                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12393                        SINGLE_LONG_FORMAT, null, longOut, null);
12394                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12395                longOut[0] = 0;
12396                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12397                        SINGLE_LONG_FORMAT, null, longOut, null);
12398                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12399                longOut[0] = 0;
12400                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12401                        SINGLE_LONG_FORMAT, null, longOut, null);
12402                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12403                longOut[0] = 0;
12404                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12405                        SINGLE_LONG_FORMAT, null, longOut, null);
12406                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12407                if (!isCompact) {
12408                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12409                        pw.print("      KSM: "); pw.print(sharing);
12410                                pw.print(" kB saved from shared ");
12411                                pw.print(shared); pw.println(" kB");
12412                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12413                                pw.print(voltile); pw.println(" kB volatile");
12414                    }
12415                    pw.print("   Tuning: ");
12416                    pw.print(ActivityManager.staticGetMemoryClass());
12417                    pw.print(" (large ");
12418                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12419                    pw.print("), oom ");
12420                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12421                    pw.print(" kB");
12422                    pw.print(", restore limit ");
12423                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12424                    pw.print(" kB");
12425                    if (ActivityManager.isLowRamDeviceStatic()) {
12426                        pw.print(" (low-ram)");
12427                    }
12428                    if (ActivityManager.isHighEndGfx()) {
12429                        pw.print(" (high-end-gfx)");
12430                    }
12431                    pw.println();
12432                } else {
12433                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12434                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12435                    pw.println(voltile);
12436                    pw.print("tuning,");
12437                    pw.print(ActivityManager.staticGetMemoryClass());
12438                    pw.print(',');
12439                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12440                    pw.print(',');
12441                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12442                    if (ActivityManager.isLowRamDeviceStatic()) {
12443                        pw.print(",low-ram");
12444                    }
12445                    if (ActivityManager.isHighEndGfx()) {
12446                        pw.print(",high-end-gfx");
12447                    }
12448                    pw.println();
12449                }
12450            }
12451        }
12452    }
12453
12454    /**
12455     * Searches array of arguments for the specified string
12456     * @param args array of argument strings
12457     * @param value value to search for
12458     * @return true if the value is contained in the array
12459     */
12460    private static boolean scanArgs(String[] args, String value) {
12461        if (args != null) {
12462            for (String arg : args) {
12463                if (value.equals(arg)) {
12464                    return true;
12465                }
12466            }
12467        }
12468        return false;
12469    }
12470
12471    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12472            ContentProviderRecord cpr, boolean always) {
12473        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12474
12475        if (!inLaunching || always) {
12476            synchronized (cpr) {
12477                cpr.launchingApp = null;
12478                cpr.notifyAll();
12479            }
12480            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12481            String names[] = cpr.info.authority.split(";");
12482            for (int j = 0; j < names.length; j++) {
12483                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12484            }
12485        }
12486
12487        for (int i=0; i<cpr.connections.size(); i++) {
12488            ContentProviderConnection conn = cpr.connections.get(i);
12489            if (conn.waiting) {
12490                // If this connection is waiting for the provider, then we don't
12491                // need to mess with its process unless we are always removing
12492                // or for some reason the provider is not currently launching.
12493                if (inLaunching && !always) {
12494                    continue;
12495                }
12496            }
12497            ProcessRecord capp = conn.client;
12498            conn.dead = true;
12499            if (conn.stableCount > 0) {
12500                if (!capp.persistent && capp.thread != null
12501                        && capp.pid != 0
12502                        && capp.pid != MY_PID) {
12503                    killUnneededProcessLocked(capp, "depends on provider "
12504                            + cpr.name.flattenToShortString()
12505                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12506                }
12507            } else if (capp.thread != null && conn.provider.provider != null) {
12508                try {
12509                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12510                } catch (RemoteException e) {
12511                }
12512                // In the protocol here, we don't expect the client to correctly
12513                // clean up this connection, we'll just remove it.
12514                cpr.connections.remove(i);
12515                conn.client.conProviders.remove(conn);
12516            }
12517        }
12518
12519        if (inLaunching && always) {
12520            mLaunchingProviders.remove(cpr);
12521        }
12522        return inLaunching;
12523    }
12524
12525    /**
12526     * Main code for cleaning up a process when it has gone away.  This is
12527     * called both as a result of the process dying, or directly when stopping
12528     * a process when running in single process mode.
12529     */
12530    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12531            boolean restarting, boolean allowRestart, int index) {
12532        if (index >= 0) {
12533            removeLruProcessLocked(app);
12534            ProcessList.remove(app.pid);
12535        }
12536
12537        mProcessesToGc.remove(app);
12538        mPendingPssProcesses.remove(app);
12539
12540        // Dismiss any open dialogs.
12541        if (app.crashDialog != null && !app.forceCrashReport) {
12542            app.crashDialog.dismiss();
12543            app.crashDialog = null;
12544        }
12545        if (app.anrDialog != null) {
12546            app.anrDialog.dismiss();
12547            app.anrDialog = null;
12548        }
12549        if (app.waitDialog != null) {
12550            app.waitDialog.dismiss();
12551            app.waitDialog = null;
12552        }
12553
12554        app.crashing = false;
12555        app.notResponding = false;
12556
12557        app.resetPackageList(mProcessStats);
12558        app.unlinkDeathRecipient();
12559        app.makeInactive(mProcessStats);
12560        app.forcingToForeground = null;
12561        updateProcessForegroundLocked(app, false, false);
12562        app.foregroundActivities = false;
12563        app.hasShownUi = false;
12564        app.hasAboveClient = false;
12565
12566        mServices.killServicesLocked(app, allowRestart);
12567
12568        boolean restart = false;
12569
12570        // Remove published content providers.
12571        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12572            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12573            final boolean always = app.bad || !allowRestart;
12574            if (removeDyingProviderLocked(app, cpr, always) || always) {
12575                // We left the provider in the launching list, need to
12576                // restart it.
12577                restart = true;
12578            }
12579
12580            cpr.provider = null;
12581            cpr.proc = null;
12582        }
12583        app.pubProviders.clear();
12584
12585        // Take care of any launching providers waiting for this process.
12586        if (checkAppInLaunchingProvidersLocked(app, false)) {
12587            restart = true;
12588        }
12589
12590        // Unregister from connected content providers.
12591        if (!app.conProviders.isEmpty()) {
12592            for (int i=0; i<app.conProviders.size(); i++) {
12593                ContentProviderConnection conn = app.conProviders.get(i);
12594                conn.provider.connections.remove(conn);
12595            }
12596            app.conProviders.clear();
12597        }
12598
12599        // At this point there may be remaining entries in mLaunchingProviders
12600        // where we were the only one waiting, so they are no longer of use.
12601        // Look for these and clean up if found.
12602        // XXX Commented out for now.  Trying to figure out a way to reproduce
12603        // the actual situation to identify what is actually going on.
12604        if (false) {
12605            for (int i=0; i<mLaunchingProviders.size(); i++) {
12606                ContentProviderRecord cpr = (ContentProviderRecord)
12607                        mLaunchingProviders.get(i);
12608                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12609                    synchronized (cpr) {
12610                        cpr.launchingApp = null;
12611                        cpr.notifyAll();
12612                    }
12613                }
12614            }
12615        }
12616
12617        skipCurrentReceiverLocked(app);
12618
12619        // Unregister any receivers.
12620        for (int i=app.receivers.size()-1; i>=0; i--) {
12621            removeReceiverLocked(app.receivers.valueAt(i));
12622        }
12623        app.receivers.clear();
12624
12625        // If the app is undergoing backup, tell the backup manager about it
12626        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12627            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12628                    + mBackupTarget.appInfo + " died during backup");
12629            try {
12630                IBackupManager bm = IBackupManager.Stub.asInterface(
12631                        ServiceManager.getService(Context.BACKUP_SERVICE));
12632                bm.agentDisconnected(app.info.packageName);
12633            } catch (RemoteException e) {
12634                // can't happen; backup manager is local
12635            }
12636        }
12637
12638        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12639            ProcessChangeItem item = mPendingProcessChanges.get(i);
12640            if (item.pid == app.pid) {
12641                mPendingProcessChanges.remove(i);
12642                mAvailProcessChanges.add(item);
12643            }
12644        }
12645        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12646
12647        // If the caller is restarting this app, then leave it in its
12648        // current lists and let the caller take care of it.
12649        if (restarting) {
12650            return;
12651        }
12652
12653        if (!app.persistent || app.isolated) {
12654            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12655                    "Removing non-persistent process during cleanup: " + app);
12656            mProcessNames.remove(app.processName, app.uid);
12657            mIsolatedProcesses.remove(app.uid);
12658            if (mHeavyWeightProcess == app) {
12659                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12660                        mHeavyWeightProcess.userId, 0));
12661                mHeavyWeightProcess = null;
12662            }
12663        } else if (!app.removed) {
12664            // This app is persistent, so we need to keep its record around.
12665            // If it is not already on the pending app list, add it there
12666            // and start a new process for it.
12667            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12668                mPersistentStartingProcesses.add(app);
12669                restart = true;
12670            }
12671        }
12672        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12673                "Clean-up removing on hold: " + app);
12674        mProcessesOnHold.remove(app);
12675
12676        if (app == mHomeProcess) {
12677            mHomeProcess = null;
12678        }
12679        if (app == mPreviousProcess) {
12680            mPreviousProcess = null;
12681        }
12682
12683        if (restart && !app.isolated) {
12684            // We have components that still need to be running in the
12685            // process, so re-launch it.
12686            mProcessNames.put(app.processName, app.uid, app);
12687            startProcessLocked(app, "restart", app.processName);
12688        } else if (app.pid > 0 && app.pid != MY_PID) {
12689            // Goodbye!
12690            boolean removed;
12691            synchronized (mPidsSelfLocked) {
12692                mPidsSelfLocked.remove(app.pid);
12693                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12694            }
12695            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
12696                    app.processName, app.info.uid);
12697            if (app.isolated) {
12698                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
12699            }
12700            app.setPid(0);
12701        }
12702    }
12703
12704    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12705        // Look through the content providers we are waiting to have launched,
12706        // and if any run in this process then either schedule a restart of
12707        // the process or kill the client waiting for it if this process has
12708        // gone bad.
12709        int NL = mLaunchingProviders.size();
12710        boolean restart = false;
12711        for (int i=0; i<NL; i++) {
12712            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12713            if (cpr.launchingApp == app) {
12714                if (!alwaysBad && !app.bad) {
12715                    restart = true;
12716                } else {
12717                    removeDyingProviderLocked(app, cpr, true);
12718                    // cpr should have been removed from mLaunchingProviders
12719                    NL = mLaunchingProviders.size();
12720                    i--;
12721                }
12722            }
12723        }
12724        return restart;
12725    }
12726
12727    // =========================================================
12728    // SERVICES
12729    // =========================================================
12730
12731    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12732            int flags) {
12733        enforceNotIsolatedCaller("getServices");
12734        synchronized (this) {
12735            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12736        }
12737    }
12738
12739    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12740        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12741        synchronized (this) {
12742            return mServices.getRunningServiceControlPanelLocked(name);
12743        }
12744    }
12745
12746    public ComponentName startService(IApplicationThread caller, Intent service,
12747            String resolvedType, int userId) {
12748        enforceNotIsolatedCaller("startService");
12749        // Refuse possible leaked file descriptors
12750        if (service != null && service.hasFileDescriptors() == true) {
12751            throw new IllegalArgumentException("File descriptors passed in Intent");
12752        }
12753
12754        if (DEBUG_SERVICE)
12755            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
12756        synchronized(this) {
12757            final int callingPid = Binder.getCallingPid();
12758            final int callingUid = Binder.getCallingUid();
12759            final long origId = Binder.clearCallingIdentity();
12760            ComponentName res = mServices.startServiceLocked(caller, service,
12761                    resolvedType, callingPid, callingUid, userId);
12762            Binder.restoreCallingIdentity(origId);
12763            return res;
12764        }
12765    }
12766
12767    ComponentName startServiceInPackage(int uid,
12768            Intent service, String resolvedType, int userId) {
12769        synchronized(this) {
12770            if (DEBUG_SERVICE)
12771                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
12772            final long origId = Binder.clearCallingIdentity();
12773            ComponentName res = mServices.startServiceLocked(null, service,
12774                    resolvedType, -1, uid, userId);
12775            Binder.restoreCallingIdentity(origId);
12776            return res;
12777        }
12778    }
12779
12780    public int stopService(IApplicationThread caller, Intent service,
12781            String resolvedType, int userId) {
12782        enforceNotIsolatedCaller("stopService");
12783        // Refuse possible leaked file descriptors
12784        if (service != null && service.hasFileDescriptors() == true) {
12785            throw new IllegalArgumentException("File descriptors passed in Intent");
12786        }
12787
12788        synchronized(this) {
12789            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
12790        }
12791    }
12792
12793    public IBinder peekService(Intent service, String resolvedType) {
12794        enforceNotIsolatedCaller("peekService");
12795        // Refuse possible leaked file descriptors
12796        if (service != null && service.hasFileDescriptors() == true) {
12797            throw new IllegalArgumentException("File descriptors passed in Intent");
12798        }
12799        synchronized(this) {
12800            return mServices.peekServiceLocked(service, resolvedType);
12801        }
12802    }
12803
12804    public boolean stopServiceToken(ComponentName className, IBinder token,
12805            int startId) {
12806        synchronized(this) {
12807            return mServices.stopServiceTokenLocked(className, token, startId);
12808        }
12809    }
12810
12811    public void setServiceForeground(ComponentName className, IBinder token,
12812            int id, Notification notification, boolean removeNotification) {
12813        synchronized(this) {
12814            mServices.setServiceForegroundLocked(className, token, id, notification,
12815                    removeNotification);
12816        }
12817    }
12818
12819    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
12820            boolean requireFull, String name, String callerPackage) {
12821        final int callingUserId = UserHandle.getUserId(callingUid);
12822        if (callingUserId != userId) {
12823            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
12824                if ((requireFull || checkComponentPermission(
12825                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12826                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
12827                        && checkComponentPermission(
12828                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
12829                                callingPid, callingUid, -1, true)
12830                                != PackageManager.PERMISSION_GRANTED) {
12831                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
12832                        // In this case, they would like to just execute as their
12833                        // owner user instead of failing.
12834                        userId = callingUserId;
12835                    } else {
12836                        StringBuilder builder = new StringBuilder(128);
12837                        builder.append("Permission Denial: ");
12838                        builder.append(name);
12839                        if (callerPackage != null) {
12840                            builder.append(" from ");
12841                            builder.append(callerPackage);
12842                        }
12843                        builder.append(" asks to run as user ");
12844                        builder.append(userId);
12845                        builder.append(" but is calling from user ");
12846                        builder.append(UserHandle.getUserId(callingUid));
12847                        builder.append("; this requires ");
12848                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
12849                        if (!requireFull) {
12850                            builder.append(" or ");
12851                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
12852                        }
12853                        String msg = builder.toString();
12854                        Slog.w(TAG, msg);
12855                        throw new SecurityException(msg);
12856                    }
12857                }
12858            }
12859            if (userId == UserHandle.USER_CURRENT
12860                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
12861                // Note that we may be accessing this outside of a lock...
12862                // shouldn't be a big deal, if this is being called outside
12863                // of a locked context there is intrinsically a race with
12864                // the value the caller will receive and someone else changing it.
12865                userId = mCurrentUserId;
12866            }
12867            if (!allowAll && userId < 0) {
12868                throw new IllegalArgumentException(
12869                        "Call does not support special user #" + userId);
12870            }
12871        }
12872        return userId;
12873    }
12874
12875    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
12876            String className, int flags) {
12877        boolean result = false;
12878        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
12879            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
12880                if (ActivityManager.checkUidPermission(
12881                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12882                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
12883                    ComponentName comp = new ComponentName(aInfo.packageName, className);
12884                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
12885                            + " requests FLAG_SINGLE_USER, but app does not hold "
12886                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
12887                    Slog.w(TAG, msg);
12888                    throw new SecurityException(msg);
12889                }
12890                result = true;
12891            }
12892        } else if (componentProcessName == aInfo.packageName) {
12893            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
12894        } else if ("system".equals(componentProcessName)) {
12895            result = true;
12896        }
12897        if (DEBUG_MU) {
12898            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
12899                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
12900        }
12901        return result;
12902    }
12903
12904    public int bindService(IApplicationThread caller, IBinder token,
12905            Intent service, String resolvedType,
12906            IServiceConnection connection, int flags, int userId) {
12907        enforceNotIsolatedCaller("bindService");
12908        // Refuse possible leaked file descriptors
12909        if (service != null && service.hasFileDescriptors() == true) {
12910            throw new IllegalArgumentException("File descriptors passed in Intent");
12911        }
12912
12913        synchronized(this) {
12914            return mServices.bindServiceLocked(caller, token, service, resolvedType,
12915                    connection, flags, userId);
12916        }
12917    }
12918
12919    public boolean unbindService(IServiceConnection connection) {
12920        synchronized (this) {
12921            return mServices.unbindServiceLocked(connection);
12922        }
12923    }
12924
12925    public void publishService(IBinder token, Intent intent, IBinder service) {
12926        // Refuse possible leaked file descriptors
12927        if (intent != null && intent.hasFileDescriptors() == true) {
12928            throw new IllegalArgumentException("File descriptors passed in Intent");
12929        }
12930
12931        synchronized(this) {
12932            if (!(token instanceof ServiceRecord)) {
12933                throw new IllegalArgumentException("Invalid service token");
12934            }
12935            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
12936        }
12937    }
12938
12939    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
12940        // Refuse possible leaked file descriptors
12941        if (intent != null && intent.hasFileDescriptors() == true) {
12942            throw new IllegalArgumentException("File descriptors passed in Intent");
12943        }
12944
12945        synchronized(this) {
12946            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
12947        }
12948    }
12949
12950    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
12951        synchronized(this) {
12952            if (!(token instanceof ServiceRecord)) {
12953                throw new IllegalArgumentException("Invalid service token");
12954            }
12955            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
12956        }
12957    }
12958
12959    // =========================================================
12960    // BACKUP AND RESTORE
12961    // =========================================================
12962
12963    // Cause the target app to be launched if necessary and its backup agent
12964    // instantiated.  The backup agent will invoke backupAgentCreated() on the
12965    // activity manager to announce its creation.
12966    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
12967        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
12968        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
12969
12970        synchronized(this) {
12971            // !!! TODO: currently no check here that we're already bound
12972            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
12973            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12974            synchronized (stats) {
12975                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
12976            }
12977
12978            // Backup agent is now in use, its package can't be stopped.
12979            try {
12980                AppGlobals.getPackageManager().setPackageStoppedState(
12981                        app.packageName, false, UserHandle.getUserId(app.uid));
12982            } catch (RemoteException e) {
12983            } catch (IllegalArgumentException e) {
12984                Slog.w(TAG, "Failed trying to unstop package "
12985                        + app.packageName + ": " + e);
12986            }
12987
12988            BackupRecord r = new BackupRecord(ss, app, backupMode);
12989            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
12990                    ? new ComponentName(app.packageName, app.backupAgentName)
12991                    : new ComponentName("android", "FullBackupAgent");
12992            // startProcessLocked() returns existing proc's record if it's already running
12993            ProcessRecord proc = startProcessLocked(app.processName, app,
12994                    false, 0, "backup", hostingName, false, false, false);
12995            if (proc == null) {
12996                Slog.e(TAG, "Unable to start backup agent process " + r);
12997                return false;
12998            }
12999
13000            r.app = proc;
13001            mBackupTarget = r;
13002            mBackupAppName = app.packageName;
13003
13004            // Try not to kill the process during backup
13005            updateOomAdjLocked(proc);
13006
13007            // If the process is already attached, schedule the creation of the backup agent now.
13008            // If it is not yet live, this will be done when it attaches to the framework.
13009            if (proc.thread != null) {
13010                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13011                try {
13012                    proc.thread.scheduleCreateBackupAgent(app,
13013                            compatibilityInfoForPackageLocked(app), backupMode);
13014                } catch (RemoteException e) {
13015                    // Will time out on the backup manager side
13016                }
13017            } else {
13018                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13019            }
13020            // Invariants: at this point, the target app process exists and the application
13021            // is either already running or in the process of coming up.  mBackupTarget and
13022            // mBackupAppName describe the app, so that when it binds back to the AM we
13023            // know that it's scheduled for a backup-agent operation.
13024        }
13025
13026        return true;
13027    }
13028
13029    @Override
13030    public void clearPendingBackup() {
13031        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13032        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13033
13034        synchronized (this) {
13035            mBackupTarget = null;
13036            mBackupAppName = null;
13037        }
13038    }
13039
13040    // A backup agent has just come up
13041    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13042        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13043                + " = " + agent);
13044
13045        synchronized(this) {
13046            if (!agentPackageName.equals(mBackupAppName)) {
13047                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13048                return;
13049            }
13050        }
13051
13052        long oldIdent = Binder.clearCallingIdentity();
13053        try {
13054            IBackupManager bm = IBackupManager.Stub.asInterface(
13055                    ServiceManager.getService(Context.BACKUP_SERVICE));
13056            bm.agentConnected(agentPackageName, agent);
13057        } catch (RemoteException e) {
13058            // can't happen; the backup manager service is local
13059        } catch (Exception e) {
13060            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13061            e.printStackTrace();
13062        } finally {
13063            Binder.restoreCallingIdentity(oldIdent);
13064        }
13065    }
13066
13067    // done with this agent
13068    public void unbindBackupAgent(ApplicationInfo appInfo) {
13069        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13070        if (appInfo == null) {
13071            Slog.w(TAG, "unbind backup agent for null app");
13072            return;
13073        }
13074
13075        synchronized(this) {
13076            try {
13077                if (mBackupAppName == null) {
13078                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13079                    return;
13080                }
13081
13082                if (!mBackupAppName.equals(appInfo.packageName)) {
13083                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13084                    return;
13085                }
13086
13087                // Not backing this app up any more; reset its OOM adjustment
13088                final ProcessRecord proc = mBackupTarget.app;
13089                updateOomAdjLocked(proc);
13090
13091                // If the app crashed during backup, 'thread' will be null here
13092                if (proc.thread != null) {
13093                    try {
13094                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13095                                compatibilityInfoForPackageLocked(appInfo));
13096                    } catch (Exception e) {
13097                        Slog.e(TAG, "Exception when unbinding backup agent:");
13098                        e.printStackTrace();
13099                    }
13100                }
13101            } finally {
13102                mBackupTarget = null;
13103                mBackupAppName = null;
13104            }
13105        }
13106    }
13107    // =========================================================
13108    // BROADCASTS
13109    // =========================================================
13110
13111    private final List getStickiesLocked(String action, IntentFilter filter,
13112            List cur, int userId) {
13113        final ContentResolver resolver = mContext.getContentResolver();
13114        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13115        if (stickies == null) {
13116            return cur;
13117        }
13118        final ArrayList<Intent> list = stickies.get(action);
13119        if (list == null) {
13120            return cur;
13121        }
13122        int N = list.size();
13123        for (int i=0; i<N; i++) {
13124            Intent intent = list.get(i);
13125            if (filter.match(resolver, intent, true, TAG) >= 0) {
13126                if (cur == null) {
13127                    cur = new ArrayList<Intent>();
13128                }
13129                cur.add(intent);
13130            }
13131        }
13132        return cur;
13133    }
13134
13135    boolean isPendingBroadcastProcessLocked(int pid) {
13136        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13137                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13138    }
13139
13140    void skipPendingBroadcastLocked(int pid) {
13141            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13142            for (BroadcastQueue queue : mBroadcastQueues) {
13143                queue.skipPendingBroadcastLocked(pid);
13144            }
13145    }
13146
13147    // The app just attached; send any pending broadcasts that it should receive
13148    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13149        boolean didSomething = false;
13150        for (BroadcastQueue queue : mBroadcastQueues) {
13151            didSomething |= queue.sendPendingBroadcastsLocked(app);
13152        }
13153        return didSomething;
13154    }
13155
13156    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13157            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13158        enforceNotIsolatedCaller("registerReceiver");
13159        int callingUid;
13160        int callingPid;
13161        synchronized(this) {
13162            ProcessRecord callerApp = null;
13163            if (caller != null) {
13164                callerApp = getRecordForAppLocked(caller);
13165                if (callerApp == null) {
13166                    throw new SecurityException(
13167                            "Unable to find app for caller " + caller
13168                            + " (pid=" + Binder.getCallingPid()
13169                            + ") when registering receiver " + receiver);
13170                }
13171                if (callerApp.info.uid != Process.SYSTEM_UID &&
13172                        !callerApp.pkgList.containsKey(callerPackage) &&
13173                        !"android".equals(callerPackage)) {
13174                    throw new SecurityException("Given caller package " + callerPackage
13175                            + " is not running in process " + callerApp);
13176                }
13177                callingUid = callerApp.info.uid;
13178                callingPid = callerApp.pid;
13179            } else {
13180                callerPackage = null;
13181                callingUid = Binder.getCallingUid();
13182                callingPid = Binder.getCallingPid();
13183            }
13184
13185            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13186                    true, true, "registerReceiver", callerPackage);
13187
13188            List allSticky = null;
13189
13190            // Look for any matching sticky broadcasts...
13191            Iterator actions = filter.actionsIterator();
13192            if (actions != null) {
13193                while (actions.hasNext()) {
13194                    String action = (String)actions.next();
13195                    allSticky = getStickiesLocked(action, filter, allSticky,
13196                            UserHandle.USER_ALL);
13197                    allSticky = getStickiesLocked(action, filter, allSticky,
13198                            UserHandle.getUserId(callingUid));
13199                }
13200            } else {
13201                allSticky = getStickiesLocked(null, filter, allSticky,
13202                        UserHandle.USER_ALL);
13203                allSticky = getStickiesLocked(null, filter, allSticky,
13204                        UserHandle.getUserId(callingUid));
13205            }
13206
13207            // The first sticky in the list is returned directly back to
13208            // the client.
13209            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13210
13211            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13212                    + ": " + sticky);
13213
13214            if (receiver == null) {
13215                return sticky;
13216            }
13217
13218            ReceiverList rl
13219                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13220            if (rl == null) {
13221                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13222                        userId, receiver);
13223                if (rl.app != null) {
13224                    rl.app.receivers.add(rl);
13225                } else {
13226                    try {
13227                        receiver.asBinder().linkToDeath(rl, 0);
13228                    } catch (RemoteException e) {
13229                        return sticky;
13230                    }
13231                    rl.linkedToDeath = true;
13232                }
13233                mRegisteredReceivers.put(receiver.asBinder(), rl);
13234            } else if (rl.uid != callingUid) {
13235                throw new IllegalArgumentException(
13236                        "Receiver requested to register for uid " + callingUid
13237                        + " was previously registered for uid " + rl.uid);
13238            } else if (rl.pid != callingPid) {
13239                throw new IllegalArgumentException(
13240                        "Receiver requested to register for pid " + callingPid
13241                        + " was previously registered for pid " + rl.pid);
13242            } else if (rl.userId != userId) {
13243                throw new IllegalArgumentException(
13244                        "Receiver requested to register for user " + userId
13245                        + " was previously registered for user " + rl.userId);
13246            }
13247            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13248                    permission, callingUid, userId);
13249            rl.add(bf);
13250            if (!bf.debugCheck()) {
13251                Slog.w(TAG, "==> For Dynamic broadast");
13252            }
13253            mReceiverResolver.addFilter(bf);
13254
13255            // Enqueue broadcasts for all existing stickies that match
13256            // this filter.
13257            if (allSticky != null) {
13258                ArrayList receivers = new ArrayList();
13259                receivers.add(bf);
13260
13261                int N = allSticky.size();
13262                for (int i=0; i<N; i++) {
13263                    Intent intent = (Intent)allSticky.get(i);
13264                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13265                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13266                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13267                            null, null, false, true, true, -1);
13268                    queue.enqueueParallelBroadcastLocked(r);
13269                    queue.scheduleBroadcastsLocked();
13270                }
13271            }
13272
13273            return sticky;
13274        }
13275    }
13276
13277    public void unregisterReceiver(IIntentReceiver receiver) {
13278        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13279
13280        final long origId = Binder.clearCallingIdentity();
13281        try {
13282            boolean doTrim = false;
13283
13284            synchronized(this) {
13285                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13286                if (rl != null) {
13287                    if (rl.curBroadcast != null) {
13288                        BroadcastRecord r = rl.curBroadcast;
13289                        final boolean doNext = finishReceiverLocked(
13290                                receiver.asBinder(), r.resultCode, r.resultData,
13291                                r.resultExtras, r.resultAbort);
13292                        if (doNext) {
13293                            doTrim = true;
13294                            r.queue.processNextBroadcast(false);
13295                        }
13296                    }
13297
13298                    if (rl.app != null) {
13299                        rl.app.receivers.remove(rl);
13300                    }
13301                    removeReceiverLocked(rl);
13302                    if (rl.linkedToDeath) {
13303                        rl.linkedToDeath = false;
13304                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13305                    }
13306                }
13307            }
13308
13309            // If we actually concluded any broadcasts, we might now be able
13310            // to trim the recipients' apps from our working set
13311            if (doTrim) {
13312                trimApplications();
13313                return;
13314            }
13315
13316        } finally {
13317            Binder.restoreCallingIdentity(origId);
13318        }
13319    }
13320
13321    void removeReceiverLocked(ReceiverList rl) {
13322        mRegisteredReceivers.remove(rl.receiver.asBinder());
13323        int N = rl.size();
13324        for (int i=0; i<N; i++) {
13325            mReceiverResolver.removeFilter(rl.get(i));
13326        }
13327    }
13328
13329    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13330        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13331            ProcessRecord r = mLruProcesses.get(i);
13332            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13333                try {
13334                    r.thread.dispatchPackageBroadcast(cmd, packages);
13335                } catch (RemoteException ex) {
13336                }
13337            }
13338        }
13339    }
13340
13341    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13342            int[] users) {
13343        List<ResolveInfo> receivers = null;
13344        try {
13345            HashSet<ComponentName> singleUserReceivers = null;
13346            boolean scannedFirstReceivers = false;
13347            for (int user : users) {
13348                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13349                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13350                if (user != 0 && newReceivers != null) {
13351                    // If this is not the primary user, we need to check for
13352                    // any receivers that should be filtered out.
13353                    for (int i=0; i<newReceivers.size(); i++) {
13354                        ResolveInfo ri = newReceivers.get(i);
13355                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13356                            newReceivers.remove(i);
13357                            i--;
13358                        }
13359                    }
13360                }
13361                if (newReceivers != null && newReceivers.size() == 0) {
13362                    newReceivers = null;
13363                }
13364                if (receivers == null) {
13365                    receivers = newReceivers;
13366                } else if (newReceivers != null) {
13367                    // We need to concatenate the additional receivers
13368                    // found with what we have do far.  This would be easy,
13369                    // but we also need to de-dup any receivers that are
13370                    // singleUser.
13371                    if (!scannedFirstReceivers) {
13372                        // Collect any single user receivers we had already retrieved.
13373                        scannedFirstReceivers = true;
13374                        for (int i=0; i<receivers.size(); i++) {
13375                            ResolveInfo ri = receivers.get(i);
13376                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13377                                ComponentName cn = new ComponentName(
13378                                        ri.activityInfo.packageName, ri.activityInfo.name);
13379                                if (singleUserReceivers == null) {
13380                                    singleUserReceivers = new HashSet<ComponentName>();
13381                                }
13382                                singleUserReceivers.add(cn);
13383                            }
13384                        }
13385                    }
13386                    // Add the new results to the existing results, tracking
13387                    // and de-dupping single user receivers.
13388                    for (int i=0; i<newReceivers.size(); i++) {
13389                        ResolveInfo ri = newReceivers.get(i);
13390                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13391                            ComponentName cn = new ComponentName(
13392                                    ri.activityInfo.packageName, ri.activityInfo.name);
13393                            if (singleUserReceivers == null) {
13394                                singleUserReceivers = new HashSet<ComponentName>();
13395                            }
13396                            if (!singleUserReceivers.contains(cn)) {
13397                                singleUserReceivers.add(cn);
13398                                receivers.add(ri);
13399                            }
13400                        } else {
13401                            receivers.add(ri);
13402                        }
13403                    }
13404                }
13405            }
13406        } catch (RemoteException ex) {
13407            // pm is in same process, this will never happen.
13408        }
13409        return receivers;
13410    }
13411
13412    private final int broadcastIntentLocked(ProcessRecord callerApp,
13413            String callerPackage, Intent intent, String resolvedType,
13414            IIntentReceiver resultTo, int resultCode, String resultData,
13415            Bundle map, String requiredPermission, int appOp,
13416            boolean ordered, boolean sticky, int callingPid, int callingUid,
13417            int userId) {
13418        intent = new Intent(intent);
13419
13420        // By default broadcasts do not go to stopped apps.
13421        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13422
13423        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13424            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13425            + " ordered=" + ordered + " userid=" + userId);
13426        if ((resultTo != null) && !ordered) {
13427            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13428        }
13429
13430        userId = handleIncomingUser(callingPid, callingUid, userId,
13431                true, false, "broadcast", callerPackage);
13432
13433        // Make sure that the user who is receiving this broadcast is started.
13434        // If not, we will just skip it.
13435        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13436            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13437                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13438                Slog.w(TAG, "Skipping broadcast of " + intent
13439                        + ": user " + userId + " is stopped");
13440                return ActivityManager.BROADCAST_SUCCESS;
13441            }
13442        }
13443
13444        /*
13445         * Prevent non-system code (defined here to be non-persistent
13446         * processes) from sending protected broadcasts.
13447         */
13448        int callingAppId = UserHandle.getAppId(callingUid);
13449        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13450            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13451            callingUid == 0) {
13452            // Always okay.
13453        } else if (callerApp == null || !callerApp.persistent) {
13454            try {
13455                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13456                        intent.getAction())) {
13457                    String msg = "Permission Denial: not allowed to send broadcast "
13458                            + intent.getAction() + " from pid="
13459                            + callingPid + ", uid=" + callingUid;
13460                    Slog.w(TAG, msg);
13461                    throw new SecurityException(msg);
13462                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13463                    // Special case for compatibility: we don't want apps to send this,
13464                    // but historically it has not been protected and apps may be using it
13465                    // to poke their own app widget.  So, instead of making it protected,
13466                    // just limit it to the caller.
13467                    if (callerApp == null) {
13468                        String msg = "Permission Denial: not allowed to send broadcast "
13469                                + intent.getAction() + " from unknown caller.";
13470                        Slog.w(TAG, msg);
13471                        throw new SecurityException(msg);
13472                    } else if (intent.getComponent() != null) {
13473                        // They are good enough to send to an explicit component...  verify
13474                        // it is being sent to the calling app.
13475                        if (!intent.getComponent().getPackageName().equals(
13476                                callerApp.info.packageName)) {
13477                            String msg = "Permission Denial: not allowed to send broadcast "
13478                                    + intent.getAction() + " to "
13479                                    + intent.getComponent().getPackageName() + " from "
13480                                    + callerApp.info.packageName;
13481                            Slog.w(TAG, msg);
13482                            throw new SecurityException(msg);
13483                        }
13484                    } else {
13485                        // Limit broadcast to their own package.
13486                        intent.setPackage(callerApp.info.packageName);
13487                    }
13488                }
13489            } catch (RemoteException e) {
13490                Slog.w(TAG, "Remote exception", e);
13491                return ActivityManager.BROADCAST_SUCCESS;
13492            }
13493        }
13494
13495        // Handle special intents: if this broadcast is from the package
13496        // manager about a package being removed, we need to remove all of
13497        // its activities from the history stack.
13498        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13499                intent.getAction());
13500        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13501                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13502                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13503                || uidRemoved) {
13504            if (checkComponentPermission(
13505                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13506                    callingPid, callingUid, -1, true)
13507                    == PackageManager.PERMISSION_GRANTED) {
13508                if (uidRemoved) {
13509                    final Bundle intentExtras = intent.getExtras();
13510                    final int uid = intentExtras != null
13511                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13512                    if (uid >= 0) {
13513                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13514                        synchronized (bs) {
13515                            bs.removeUidStatsLocked(uid);
13516                        }
13517                        mAppOpsService.uidRemoved(uid);
13518                    }
13519                } else {
13520                    // If resources are unavailable just force stop all
13521                    // those packages and flush the attribute cache as well.
13522                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13523                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13524                        if (list != null && (list.length > 0)) {
13525                            for (String pkg : list) {
13526                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13527                                        "storage unmount");
13528                            }
13529                            sendPackageBroadcastLocked(
13530                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13531                        }
13532                    } else {
13533                        Uri data = intent.getData();
13534                        String ssp;
13535                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13536                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13537                                    intent.getAction());
13538                            boolean fullUninstall = removed &&
13539                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13540                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13541                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13542                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13543                                        false, fullUninstall, userId,
13544                                        removed ? "pkg removed" : "pkg changed");
13545                            }
13546                            if (removed) {
13547                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13548                                        new String[] {ssp}, userId);
13549                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13550                                    mAppOpsService.packageRemoved(
13551                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13552
13553                                    // Remove all permissions granted from/to this package
13554                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13555                                }
13556                            }
13557                        }
13558                    }
13559                }
13560            } else {
13561                String msg = "Permission Denial: " + intent.getAction()
13562                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13563                        + ", uid=" + callingUid + ")"
13564                        + " requires "
13565                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13566                Slog.w(TAG, msg);
13567                throw new SecurityException(msg);
13568            }
13569
13570        // Special case for adding a package: by default turn on compatibility
13571        // mode.
13572        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13573            Uri data = intent.getData();
13574            String ssp;
13575            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13576                mCompatModePackages.handlePackageAddedLocked(ssp,
13577                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13578            }
13579        }
13580
13581        /*
13582         * If this is the time zone changed action, queue up a message that will reset the timezone
13583         * of all currently running processes. This message will get queued up before the broadcast
13584         * happens.
13585         */
13586        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13587            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13588        }
13589
13590        /*
13591         * If the user set the time, let all running processes know.
13592         */
13593        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
13594            final int is24Hour = intent.getBooleanExtra(
13595                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
13596            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
13597        }
13598
13599        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13600            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13601        }
13602
13603        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13604            ProxyProperties proxy = intent.getParcelableExtra("proxy");
13605            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13606        }
13607
13608        // Add to the sticky list if requested.
13609        if (sticky) {
13610            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13611                    callingPid, callingUid)
13612                    != PackageManager.PERMISSION_GRANTED) {
13613                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13614                        + callingPid + ", uid=" + callingUid
13615                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13616                Slog.w(TAG, msg);
13617                throw new SecurityException(msg);
13618            }
13619            if (requiredPermission != null) {
13620                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13621                        + " and enforce permission " + requiredPermission);
13622                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13623            }
13624            if (intent.getComponent() != null) {
13625                throw new SecurityException(
13626                        "Sticky broadcasts can't target a specific component");
13627            }
13628            // We use userId directly here, since the "all" target is maintained
13629            // as a separate set of sticky broadcasts.
13630            if (userId != UserHandle.USER_ALL) {
13631                // But first, if this is not a broadcast to all users, then
13632                // make sure it doesn't conflict with an existing broadcast to
13633                // all users.
13634                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13635                        UserHandle.USER_ALL);
13636                if (stickies != null) {
13637                    ArrayList<Intent> list = stickies.get(intent.getAction());
13638                    if (list != null) {
13639                        int N = list.size();
13640                        int i;
13641                        for (i=0; i<N; i++) {
13642                            if (intent.filterEquals(list.get(i))) {
13643                                throw new IllegalArgumentException(
13644                                        "Sticky broadcast " + intent + " for user "
13645                                        + userId + " conflicts with existing global broadcast");
13646                            }
13647                        }
13648                    }
13649                }
13650            }
13651            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13652            if (stickies == null) {
13653                stickies = new ArrayMap<String, ArrayList<Intent>>();
13654                mStickyBroadcasts.put(userId, stickies);
13655            }
13656            ArrayList<Intent> list = stickies.get(intent.getAction());
13657            if (list == null) {
13658                list = new ArrayList<Intent>();
13659                stickies.put(intent.getAction(), list);
13660            }
13661            int N = list.size();
13662            int i;
13663            for (i=0; i<N; i++) {
13664                if (intent.filterEquals(list.get(i))) {
13665                    // This sticky already exists, replace it.
13666                    list.set(i, new Intent(intent));
13667                    break;
13668                }
13669            }
13670            if (i >= N) {
13671                list.add(new Intent(intent));
13672            }
13673        }
13674
13675        int[] users;
13676        if (userId == UserHandle.USER_ALL) {
13677            // Caller wants broadcast to go to all started users.
13678            users = mStartedUserArray;
13679        } else {
13680            // Caller wants broadcast to go to one specific user.
13681            users = new int[] {userId};
13682        }
13683
13684        // Figure out who all will receive this broadcast.
13685        List receivers = null;
13686        List<BroadcastFilter> registeredReceivers = null;
13687        // Need to resolve the intent to interested receivers...
13688        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13689                 == 0) {
13690            receivers = collectReceiverComponents(intent, resolvedType, users);
13691        }
13692        if (intent.getComponent() == null) {
13693            registeredReceivers = mReceiverResolver.queryIntent(intent,
13694                    resolvedType, false, userId);
13695        }
13696
13697        final boolean replacePending =
13698                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13699
13700        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13701                + " replacePending=" + replacePending);
13702
13703        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13704        if (!ordered && NR > 0) {
13705            // If we are not serializing this broadcast, then send the
13706            // registered receivers separately so they don't wait for the
13707            // components to be launched.
13708            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13709            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13710                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13711                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13712                    ordered, sticky, false, userId);
13713            if (DEBUG_BROADCAST) Slog.v(
13714                    TAG, "Enqueueing parallel broadcast " + r);
13715            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13716            if (!replaced) {
13717                queue.enqueueParallelBroadcastLocked(r);
13718                queue.scheduleBroadcastsLocked();
13719            }
13720            registeredReceivers = null;
13721            NR = 0;
13722        }
13723
13724        // Merge into one list.
13725        int ir = 0;
13726        if (receivers != null) {
13727            // A special case for PACKAGE_ADDED: do not allow the package
13728            // being added to see this broadcast.  This prevents them from
13729            // using this as a back door to get run as soon as they are
13730            // installed.  Maybe in the future we want to have a special install
13731            // broadcast or such for apps, but we'd like to deliberately make
13732            // this decision.
13733            String skipPackages[] = null;
13734            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13735                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13736                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13737                Uri data = intent.getData();
13738                if (data != null) {
13739                    String pkgName = data.getSchemeSpecificPart();
13740                    if (pkgName != null) {
13741                        skipPackages = new String[] { pkgName };
13742                    }
13743                }
13744            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13745                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13746            }
13747            if (skipPackages != null && (skipPackages.length > 0)) {
13748                for (String skipPackage : skipPackages) {
13749                    if (skipPackage != null) {
13750                        int NT = receivers.size();
13751                        for (int it=0; it<NT; it++) {
13752                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
13753                            if (curt.activityInfo.packageName.equals(skipPackage)) {
13754                                receivers.remove(it);
13755                                it--;
13756                                NT--;
13757                            }
13758                        }
13759                    }
13760                }
13761            }
13762
13763            int NT = receivers != null ? receivers.size() : 0;
13764            int it = 0;
13765            ResolveInfo curt = null;
13766            BroadcastFilter curr = null;
13767            while (it < NT && ir < NR) {
13768                if (curt == null) {
13769                    curt = (ResolveInfo)receivers.get(it);
13770                }
13771                if (curr == null) {
13772                    curr = registeredReceivers.get(ir);
13773                }
13774                if (curr.getPriority() >= curt.priority) {
13775                    // Insert this broadcast record into the final list.
13776                    receivers.add(it, curr);
13777                    ir++;
13778                    curr = null;
13779                    it++;
13780                    NT++;
13781                } else {
13782                    // Skip to the next ResolveInfo in the final list.
13783                    it++;
13784                    curt = null;
13785                }
13786            }
13787        }
13788        while (ir < NR) {
13789            if (receivers == null) {
13790                receivers = new ArrayList();
13791            }
13792            receivers.add(registeredReceivers.get(ir));
13793            ir++;
13794        }
13795
13796        if ((receivers != null && receivers.size() > 0)
13797                || resultTo != null) {
13798            BroadcastQueue queue = broadcastQueueForIntent(intent);
13799            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13800                    callerPackage, callingPid, callingUid, resolvedType,
13801                    requiredPermission, appOp, receivers, resultTo, resultCode,
13802                    resultData, map, ordered, sticky, false, userId);
13803            if (DEBUG_BROADCAST) Slog.v(
13804                    TAG, "Enqueueing ordered broadcast " + r
13805                    + ": prev had " + queue.mOrderedBroadcasts.size());
13806            if (DEBUG_BROADCAST) {
13807                int seq = r.intent.getIntExtra("seq", -1);
13808                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
13809            }
13810            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
13811            if (!replaced) {
13812                queue.enqueueOrderedBroadcastLocked(r);
13813                queue.scheduleBroadcastsLocked();
13814            }
13815        }
13816
13817        return ActivityManager.BROADCAST_SUCCESS;
13818    }
13819
13820    final Intent verifyBroadcastLocked(Intent intent) {
13821        // Refuse possible leaked file descriptors
13822        if (intent != null && intent.hasFileDescriptors() == true) {
13823            throw new IllegalArgumentException("File descriptors passed in Intent");
13824        }
13825
13826        int flags = intent.getFlags();
13827
13828        if (!mProcessesReady) {
13829            // if the caller really truly claims to know what they're doing, go
13830            // ahead and allow the broadcast without launching any receivers
13831            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
13832                intent = new Intent(intent);
13833                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13834            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
13835                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
13836                        + " before boot completion");
13837                throw new IllegalStateException("Cannot broadcast before boot completed");
13838            }
13839        }
13840
13841        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
13842            throw new IllegalArgumentException(
13843                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
13844        }
13845
13846        return intent;
13847    }
13848
13849    public final int broadcastIntent(IApplicationThread caller,
13850            Intent intent, String resolvedType, IIntentReceiver resultTo,
13851            int resultCode, String resultData, Bundle map,
13852            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
13853        enforceNotIsolatedCaller("broadcastIntent");
13854        synchronized(this) {
13855            intent = verifyBroadcastLocked(intent);
13856
13857            final ProcessRecord callerApp = getRecordForAppLocked(caller);
13858            final int callingPid = Binder.getCallingPid();
13859            final int callingUid = Binder.getCallingUid();
13860            final long origId = Binder.clearCallingIdentity();
13861            int res = broadcastIntentLocked(callerApp,
13862                    callerApp != null ? callerApp.info.packageName : null,
13863                    intent, resolvedType, resultTo,
13864                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
13865                    callingPid, callingUid, userId);
13866            Binder.restoreCallingIdentity(origId);
13867            return res;
13868        }
13869    }
13870
13871    int broadcastIntentInPackage(String packageName, int uid,
13872            Intent intent, String resolvedType, IIntentReceiver resultTo,
13873            int resultCode, String resultData, Bundle map,
13874            String requiredPermission, boolean serialized, boolean sticky, int userId) {
13875        synchronized(this) {
13876            intent = verifyBroadcastLocked(intent);
13877
13878            final long origId = Binder.clearCallingIdentity();
13879            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
13880                    resultTo, resultCode, resultData, map, requiredPermission,
13881                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
13882            Binder.restoreCallingIdentity(origId);
13883            return res;
13884        }
13885    }
13886
13887    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
13888        // Refuse possible leaked file descriptors
13889        if (intent != null && intent.hasFileDescriptors() == true) {
13890            throw new IllegalArgumentException("File descriptors passed in Intent");
13891        }
13892
13893        userId = handleIncomingUser(Binder.getCallingPid(),
13894                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
13895
13896        synchronized(this) {
13897            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
13898                    != PackageManager.PERMISSION_GRANTED) {
13899                String msg = "Permission Denial: unbroadcastIntent() from pid="
13900                        + Binder.getCallingPid()
13901                        + ", uid=" + Binder.getCallingUid()
13902                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13903                Slog.w(TAG, msg);
13904                throw new SecurityException(msg);
13905            }
13906            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13907            if (stickies != null) {
13908                ArrayList<Intent> list = stickies.get(intent.getAction());
13909                if (list != null) {
13910                    int N = list.size();
13911                    int i;
13912                    for (i=0; i<N; i++) {
13913                        if (intent.filterEquals(list.get(i))) {
13914                            list.remove(i);
13915                            break;
13916                        }
13917                    }
13918                    if (list.size() <= 0) {
13919                        stickies.remove(intent.getAction());
13920                    }
13921                }
13922                if (stickies.size() <= 0) {
13923                    mStickyBroadcasts.remove(userId);
13924                }
13925            }
13926        }
13927    }
13928
13929    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
13930            String resultData, Bundle resultExtras, boolean resultAbort) {
13931        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
13932        if (r == null) {
13933            Slog.w(TAG, "finishReceiver called but not found on queue");
13934            return false;
13935        }
13936
13937        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
13938    }
13939
13940    void backgroundServicesFinishedLocked(int userId) {
13941        for (BroadcastQueue queue : mBroadcastQueues) {
13942            queue.backgroundServicesFinishedLocked(userId);
13943        }
13944    }
13945
13946    public void finishReceiver(IBinder who, int resultCode, String resultData,
13947            Bundle resultExtras, boolean resultAbort) {
13948        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
13949
13950        // Refuse possible leaked file descriptors
13951        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
13952            throw new IllegalArgumentException("File descriptors passed in Bundle");
13953        }
13954
13955        final long origId = Binder.clearCallingIdentity();
13956        try {
13957            boolean doNext = false;
13958            BroadcastRecord r;
13959
13960            synchronized(this) {
13961                r = broadcastRecordForReceiverLocked(who);
13962                if (r != null) {
13963                    doNext = r.queue.finishReceiverLocked(r, resultCode,
13964                        resultData, resultExtras, resultAbort, true);
13965                }
13966            }
13967
13968            if (doNext) {
13969                r.queue.processNextBroadcast(false);
13970            }
13971            trimApplications();
13972        } finally {
13973            Binder.restoreCallingIdentity(origId);
13974        }
13975    }
13976
13977    // =========================================================
13978    // INSTRUMENTATION
13979    // =========================================================
13980
13981    public boolean startInstrumentation(ComponentName className,
13982            String profileFile, int flags, Bundle arguments,
13983            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
13984            int userId) {
13985        enforceNotIsolatedCaller("startInstrumentation");
13986        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
13987                userId, false, true, "startInstrumentation", null);
13988        // Refuse possible leaked file descriptors
13989        if (arguments != null && arguments.hasFileDescriptors()) {
13990            throw new IllegalArgumentException("File descriptors passed in Bundle");
13991        }
13992
13993        synchronized(this) {
13994            InstrumentationInfo ii = null;
13995            ApplicationInfo ai = null;
13996            try {
13997                ii = mContext.getPackageManager().getInstrumentationInfo(
13998                    className, STOCK_PM_FLAGS);
13999                ai = AppGlobals.getPackageManager().getApplicationInfo(
14000                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14001            } catch (PackageManager.NameNotFoundException e) {
14002            } catch (RemoteException e) {
14003            }
14004            if (ii == null) {
14005                reportStartInstrumentationFailure(watcher, className,
14006                        "Unable to find instrumentation info for: " + className);
14007                return false;
14008            }
14009            if (ai == null) {
14010                reportStartInstrumentationFailure(watcher, className,
14011                        "Unable to find instrumentation target package: " + ii.targetPackage);
14012                return false;
14013            }
14014
14015            int match = mContext.getPackageManager().checkSignatures(
14016                    ii.targetPackage, ii.packageName);
14017            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14018                String msg = "Permission Denial: starting instrumentation "
14019                        + className + " from pid="
14020                        + Binder.getCallingPid()
14021                        + ", uid=" + Binder.getCallingPid()
14022                        + " not allowed because package " + ii.packageName
14023                        + " does not have a signature matching the target "
14024                        + ii.targetPackage;
14025                reportStartInstrumentationFailure(watcher, className, msg);
14026                throw new SecurityException(msg);
14027            }
14028
14029            final long origId = Binder.clearCallingIdentity();
14030            // Instrumentation can kill and relaunch even persistent processes
14031            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14032                    "start instr");
14033            ProcessRecord app = addAppLocked(ai, false);
14034            app.instrumentationClass = className;
14035            app.instrumentationInfo = ai;
14036            app.instrumentationProfileFile = profileFile;
14037            app.instrumentationArguments = arguments;
14038            app.instrumentationWatcher = watcher;
14039            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14040            app.instrumentationResultClass = className;
14041            Binder.restoreCallingIdentity(origId);
14042        }
14043
14044        return true;
14045    }
14046
14047    /**
14048     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14049     * error to the logs, but if somebody is watching, send the report there too.  This enables
14050     * the "am" command to report errors with more information.
14051     *
14052     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14053     * @param cn The component name of the instrumentation.
14054     * @param report The error report.
14055     */
14056    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14057            ComponentName cn, String report) {
14058        Slog.w(TAG, report);
14059        try {
14060            if (watcher != null) {
14061                Bundle results = new Bundle();
14062                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14063                results.putString("Error", report);
14064                watcher.instrumentationStatus(cn, -1, results);
14065            }
14066        } catch (RemoteException e) {
14067            Slog.w(TAG, e);
14068        }
14069    }
14070
14071    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14072        if (app.instrumentationWatcher != null) {
14073            try {
14074                // NOTE:  IInstrumentationWatcher *must* be oneway here
14075                app.instrumentationWatcher.instrumentationFinished(
14076                    app.instrumentationClass,
14077                    resultCode,
14078                    results);
14079            } catch (RemoteException e) {
14080            }
14081        }
14082        if (app.instrumentationUiAutomationConnection != null) {
14083            try {
14084                app.instrumentationUiAutomationConnection.shutdown();
14085            } catch (RemoteException re) {
14086                /* ignore */
14087            }
14088            // Only a UiAutomation can set this flag and now that
14089            // it is finished we make sure it is reset to its default.
14090            mUserIsMonkey = false;
14091        }
14092        app.instrumentationWatcher = null;
14093        app.instrumentationUiAutomationConnection = null;
14094        app.instrumentationClass = null;
14095        app.instrumentationInfo = null;
14096        app.instrumentationProfileFile = null;
14097        app.instrumentationArguments = null;
14098
14099        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14100                "finished inst");
14101    }
14102
14103    public void finishInstrumentation(IApplicationThread target,
14104            int resultCode, Bundle results) {
14105        int userId = UserHandle.getCallingUserId();
14106        // Refuse possible leaked file descriptors
14107        if (results != null && results.hasFileDescriptors()) {
14108            throw new IllegalArgumentException("File descriptors passed in Intent");
14109        }
14110
14111        synchronized(this) {
14112            ProcessRecord app = getRecordForAppLocked(target);
14113            if (app == null) {
14114                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14115                return;
14116            }
14117            final long origId = Binder.clearCallingIdentity();
14118            finishInstrumentationLocked(app, resultCode, results);
14119            Binder.restoreCallingIdentity(origId);
14120        }
14121    }
14122
14123    // =========================================================
14124    // CONFIGURATION
14125    // =========================================================
14126
14127    public ConfigurationInfo getDeviceConfigurationInfo() {
14128        ConfigurationInfo config = new ConfigurationInfo();
14129        synchronized (this) {
14130            config.reqTouchScreen = mConfiguration.touchscreen;
14131            config.reqKeyboardType = mConfiguration.keyboard;
14132            config.reqNavigation = mConfiguration.navigation;
14133            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14134                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14135                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14136            }
14137            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14138                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14139                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14140            }
14141            config.reqGlEsVersion = GL_ES_VERSION;
14142        }
14143        return config;
14144    }
14145
14146    ActivityStack getFocusedStack() {
14147        return mStackSupervisor.getFocusedStack();
14148    }
14149
14150    public Configuration getConfiguration() {
14151        Configuration ci;
14152        synchronized(this) {
14153            ci = new Configuration(mConfiguration);
14154        }
14155        return ci;
14156    }
14157
14158    public void updatePersistentConfiguration(Configuration values) {
14159        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14160                "updateConfiguration()");
14161        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14162                "updateConfiguration()");
14163        if (values == null) {
14164            throw new NullPointerException("Configuration must not be null");
14165        }
14166
14167        synchronized(this) {
14168            final long origId = Binder.clearCallingIdentity();
14169            updateConfigurationLocked(values, null, true, false);
14170            Binder.restoreCallingIdentity(origId);
14171        }
14172    }
14173
14174    public void updateConfiguration(Configuration values) {
14175        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14176                "updateConfiguration()");
14177
14178        synchronized(this) {
14179            if (values == null && mWindowManager != null) {
14180                // sentinel: fetch the current configuration from the window manager
14181                values = mWindowManager.computeNewConfiguration();
14182            }
14183
14184            if (mWindowManager != null) {
14185                mProcessList.applyDisplaySize(mWindowManager);
14186            }
14187
14188            final long origId = Binder.clearCallingIdentity();
14189            if (values != null) {
14190                Settings.System.clearConfiguration(values);
14191            }
14192            updateConfigurationLocked(values, null, false, false);
14193            Binder.restoreCallingIdentity(origId);
14194        }
14195    }
14196
14197    /**
14198     * Do either or both things: (1) change the current configuration, and (2)
14199     * make sure the given activity is running with the (now) current
14200     * configuration.  Returns true if the activity has been left running, or
14201     * false if <var>starting</var> is being destroyed to match the new
14202     * configuration.
14203     * @param persistent TODO
14204     */
14205    boolean updateConfigurationLocked(Configuration values,
14206            ActivityRecord starting, boolean persistent, boolean initLocale) {
14207        int changes = 0;
14208
14209        if (values != null) {
14210            Configuration newConfig = new Configuration(mConfiguration);
14211            changes = newConfig.updateFrom(values);
14212            if (changes != 0) {
14213                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14214                    Slog.i(TAG, "Updating configuration to: " + values);
14215                }
14216
14217                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14218
14219                if (values.locale != null && !initLocale) {
14220                    saveLocaleLocked(values.locale,
14221                                     !values.locale.equals(mConfiguration.locale),
14222                                     values.userSetLocale);
14223                }
14224
14225                mConfigurationSeq++;
14226                if (mConfigurationSeq <= 0) {
14227                    mConfigurationSeq = 1;
14228                }
14229                newConfig.seq = mConfigurationSeq;
14230                mConfiguration = newConfig;
14231                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14232
14233                final Configuration configCopy = new Configuration(mConfiguration);
14234
14235                // TODO: If our config changes, should we auto dismiss any currently
14236                // showing dialogs?
14237                mShowDialogs = shouldShowDialogs(newConfig);
14238
14239                AttributeCache ac = AttributeCache.instance();
14240                if (ac != null) {
14241                    ac.updateConfiguration(configCopy);
14242                }
14243
14244                // Make sure all resources in our process are updated
14245                // right now, so that anyone who is going to retrieve
14246                // resource values after we return will be sure to get
14247                // the new ones.  This is especially important during
14248                // boot, where the first config change needs to guarantee
14249                // all resources have that config before following boot
14250                // code is executed.
14251                mSystemThread.applyConfigurationToResources(configCopy);
14252
14253                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14254                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14255                    msg.obj = new Configuration(configCopy);
14256                    mHandler.sendMessage(msg);
14257                }
14258
14259                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14260                    ProcessRecord app = mLruProcesses.get(i);
14261                    try {
14262                        if (app.thread != null) {
14263                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14264                                    + app.processName + " new config " + mConfiguration);
14265                            app.thread.scheduleConfigurationChanged(configCopy);
14266                        }
14267                    } catch (Exception e) {
14268                    }
14269                }
14270                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14271                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14272                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14273                        | Intent.FLAG_RECEIVER_FOREGROUND);
14274                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14275                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14276                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14277                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14278                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14279                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14280                    broadcastIntentLocked(null, null, intent,
14281                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14282                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14283                }
14284            }
14285        }
14286
14287        boolean kept = true;
14288        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14289        // mainStack is null during startup.
14290        if (mainStack != null) {
14291            if (changes != 0 && starting == null) {
14292                // If the configuration changed, and the caller is not already
14293                // in the process of starting an activity, then find the top
14294                // activity to check if its configuration needs to change.
14295                starting = mainStack.topRunningActivityLocked(null);
14296            }
14297
14298            if (starting != null) {
14299                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14300                // And we need to make sure at this point that all other activities
14301                // are made visible with the correct configuration.
14302                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14303            }
14304        }
14305
14306        if (values != null && mWindowManager != null) {
14307            mWindowManager.setNewConfiguration(mConfiguration);
14308        }
14309
14310        return kept;
14311    }
14312
14313    /**
14314     * Decide based on the configuration whether we should shouw the ANR,
14315     * crash, etc dialogs.  The idea is that if there is no affordnace to
14316     * press the on-screen buttons, we shouldn't show the dialog.
14317     *
14318     * A thought: SystemUI might also want to get told about this, the Power
14319     * dialog / global actions also might want different behaviors.
14320     */
14321    private static final boolean shouldShowDialogs(Configuration config) {
14322        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14323                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14324    }
14325
14326    /**
14327     * Save the locale.  You must be inside a synchronized (this) block.
14328     */
14329    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14330        if(isDiff) {
14331            SystemProperties.set("user.language", l.getLanguage());
14332            SystemProperties.set("user.region", l.getCountry());
14333        }
14334
14335        if(isPersist) {
14336            SystemProperties.set("persist.sys.language", l.getLanguage());
14337            SystemProperties.set("persist.sys.country", l.getCountry());
14338            SystemProperties.set("persist.sys.localevar", l.getVariant());
14339        }
14340    }
14341
14342    @Override
14343    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14344        ActivityRecord srec = ActivityRecord.forToken(token);
14345        return srec != null && srec.task.affinity != null &&
14346                srec.task.affinity.equals(destAffinity);
14347    }
14348
14349    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14350            Intent resultData) {
14351
14352        synchronized (this) {
14353            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14354            if (stack != null) {
14355                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14356            }
14357            return false;
14358        }
14359    }
14360
14361    public int getLaunchedFromUid(IBinder activityToken) {
14362        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14363        if (srec == null) {
14364            return -1;
14365        }
14366        return srec.launchedFromUid;
14367    }
14368
14369    public String getLaunchedFromPackage(IBinder activityToken) {
14370        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14371        if (srec == null) {
14372            return null;
14373        }
14374        return srec.launchedFromPackage;
14375    }
14376
14377    // =========================================================
14378    // LIFETIME MANAGEMENT
14379    // =========================================================
14380
14381    // Returns which broadcast queue the app is the current [or imminent] receiver
14382    // on, or 'null' if the app is not an active broadcast recipient.
14383    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14384        BroadcastRecord r = app.curReceiver;
14385        if (r != null) {
14386            return r.queue;
14387        }
14388
14389        // It's not the current receiver, but it might be starting up to become one
14390        synchronized (this) {
14391            for (BroadcastQueue queue : mBroadcastQueues) {
14392                r = queue.mPendingBroadcast;
14393                if (r != null && r.curApp == app) {
14394                    // found it; report which queue it's in
14395                    return queue;
14396                }
14397            }
14398        }
14399
14400        return null;
14401    }
14402
14403    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14404            boolean doingAll, long now) {
14405        if (mAdjSeq == app.adjSeq) {
14406            // This adjustment has already been computed.
14407            return app.curRawAdj;
14408        }
14409
14410        if (app.thread == null) {
14411            app.adjSeq = mAdjSeq;
14412            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14413            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14414            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14415        }
14416
14417        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14418        app.adjSource = null;
14419        app.adjTarget = null;
14420        app.empty = false;
14421        app.cached = false;
14422
14423        final int activitiesSize = app.activities.size();
14424
14425        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14426            // The max adjustment doesn't allow this app to be anything
14427            // below foreground, so it is not worth doing work for it.
14428            app.adjType = "fixed";
14429            app.adjSeq = mAdjSeq;
14430            app.curRawAdj = app.maxAdj;
14431            app.foregroundActivities = false;
14432            app.keeping = true;
14433            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14434            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14435            // System process can do UI, and when they do we want to have
14436            // them trim their memory after the user leaves the UI.  To
14437            // facilitate this, here we need to determine whether or not it
14438            // is currently showing UI.
14439            app.systemNoUi = true;
14440            if (app == TOP_APP) {
14441                app.systemNoUi = false;
14442            } else if (activitiesSize > 0) {
14443                for (int j = 0; j < activitiesSize; j++) {
14444                    final ActivityRecord r = app.activities.get(j);
14445                    if (r.visible) {
14446                        app.systemNoUi = false;
14447                    }
14448                }
14449            }
14450            if (!app.systemNoUi) {
14451                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14452            }
14453            return (app.curAdj=app.maxAdj);
14454        }
14455
14456        app.keeping = false;
14457        app.systemNoUi = false;
14458
14459        // Determine the importance of the process, starting with most
14460        // important to least, and assign an appropriate OOM adjustment.
14461        int adj;
14462        int schedGroup;
14463        int procState;
14464        boolean foregroundActivities = false;
14465        boolean interesting = false;
14466        BroadcastQueue queue;
14467        if (app == TOP_APP) {
14468            // The last app on the list is the foreground app.
14469            adj = ProcessList.FOREGROUND_APP_ADJ;
14470            schedGroup = Process.THREAD_GROUP_DEFAULT;
14471            app.adjType = "top-activity";
14472            foregroundActivities = true;
14473            interesting = true;
14474            procState = ActivityManager.PROCESS_STATE_TOP;
14475        } else if (app.instrumentationClass != null) {
14476            // Don't want to kill running instrumentation.
14477            adj = ProcessList.FOREGROUND_APP_ADJ;
14478            schedGroup = Process.THREAD_GROUP_DEFAULT;
14479            app.adjType = "instrumentation";
14480            interesting = true;
14481            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14482        } else if ((queue = isReceivingBroadcast(app)) != null) {
14483            // An app that is currently receiving a broadcast also
14484            // counts as being in the foreground for OOM killer purposes.
14485            // It's placed in a sched group based on the nature of the
14486            // broadcast as reflected by which queue it's active in.
14487            adj = ProcessList.FOREGROUND_APP_ADJ;
14488            schedGroup = (queue == mFgBroadcastQueue)
14489                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14490            app.adjType = "broadcast";
14491            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14492        } else if (app.executingServices.size() > 0) {
14493            // An app that is currently executing a service callback also
14494            // counts as being in the foreground.
14495            adj = ProcessList.FOREGROUND_APP_ADJ;
14496            schedGroup = app.execServicesFg ?
14497                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14498            app.adjType = "exec-service";
14499            procState = ActivityManager.PROCESS_STATE_SERVICE;
14500            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14501        } else {
14502            // As far as we know the process is empty.  We may change our mind later.
14503            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14504            // At this point we don't actually know the adjustment.  Use the cached adj
14505            // value that the caller wants us to.
14506            adj = cachedAdj;
14507            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14508            app.cached = true;
14509            app.empty = true;
14510            app.adjType = "cch-empty";
14511        }
14512
14513        // Examine all activities if not already foreground.
14514        if (!foregroundActivities && activitiesSize > 0) {
14515            for (int j = 0; j < activitiesSize; j++) {
14516                final ActivityRecord r = app.activities.get(j);
14517                if (r.app != app) {
14518                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14519                            + app + "?!?");
14520                    continue;
14521                }
14522                if (r.visible) {
14523                    // App has a visible activity; only upgrade adjustment.
14524                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14525                        adj = ProcessList.VISIBLE_APP_ADJ;
14526                        app.adjType = "visible";
14527                    }
14528                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14529                        procState = ActivityManager.PROCESS_STATE_TOP;
14530                    }
14531                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14532                    app.cached = false;
14533                    app.empty = false;
14534                    foregroundActivities = true;
14535                    break;
14536                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14537                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14538                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14539                        app.adjType = "pausing";
14540                    }
14541                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14542                        procState = ActivityManager.PROCESS_STATE_TOP;
14543                    }
14544                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14545                    app.cached = false;
14546                    app.empty = false;
14547                    foregroundActivities = true;
14548                } else if (r.state == ActivityState.STOPPING) {
14549                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14550                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14551                        app.adjType = "stopping";
14552                    }
14553                    // For the process state, we will at this point consider the
14554                    // process to be cached.  It will be cached either as an activity
14555                    // or empty depending on whether the activity is finishing.  We do
14556                    // this so that we can treat the process as cached for purposes of
14557                    // memory trimming (determing current memory level, trim command to
14558                    // send to process) since there can be an arbitrary number of stopping
14559                    // processes and they should soon all go into the cached state.
14560                    if (!r.finishing) {
14561                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14562                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14563                        }
14564                    }
14565                    app.cached = false;
14566                    app.empty = false;
14567                    foregroundActivities = true;
14568                } else {
14569                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14570                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14571                        app.adjType = "cch-act";
14572                    }
14573                }
14574            }
14575        }
14576
14577        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14578            if (app.foregroundServices) {
14579                // The user is aware of this app, so make it visible.
14580                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14581                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14582                app.cached = false;
14583                app.adjType = "fg-service";
14584                schedGroup = Process.THREAD_GROUP_DEFAULT;
14585            } else if (app.forcingToForeground != null) {
14586                // The user is aware of this app, so make it visible.
14587                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14588                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14589                app.cached = false;
14590                app.adjType = "force-fg";
14591                app.adjSource = app.forcingToForeground;
14592                schedGroup = Process.THREAD_GROUP_DEFAULT;
14593            }
14594        }
14595
14596        if (app.foregroundServices) {
14597            interesting = true;
14598        }
14599
14600        if (app == mHeavyWeightProcess) {
14601            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14602                // We don't want to kill the current heavy-weight process.
14603                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14604                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14605                app.cached = false;
14606                app.adjType = "heavy";
14607            }
14608            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14609                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14610            }
14611        }
14612
14613        if (app == mHomeProcess) {
14614            if (adj > ProcessList.HOME_APP_ADJ) {
14615                // This process is hosting what we currently consider to be the
14616                // home app, so we don't want to let it go into the background.
14617                adj = ProcessList.HOME_APP_ADJ;
14618                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14619                app.cached = false;
14620                app.adjType = "home";
14621            }
14622            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14623                procState = ActivityManager.PROCESS_STATE_HOME;
14624            }
14625        }
14626
14627        if (app == mPreviousProcess && app.activities.size() > 0) {
14628            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14629                // This was the previous process that showed UI to the user.
14630                // We want to try to keep it around more aggressively, to give
14631                // a good experience around switching between two apps.
14632                adj = ProcessList.PREVIOUS_APP_ADJ;
14633                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14634                app.cached = false;
14635                app.adjType = "previous";
14636            }
14637            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14638                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14639            }
14640        }
14641
14642        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14643                + " reason=" + app.adjType);
14644
14645        // By default, we use the computed adjustment.  It may be changed if
14646        // there are applications dependent on our services or providers, but
14647        // this gives us a baseline and makes sure we don't get into an
14648        // infinite recursion.
14649        app.adjSeq = mAdjSeq;
14650        app.curRawAdj = adj;
14651        app.hasStartedServices = false;
14652
14653        if (mBackupTarget != null && app == mBackupTarget.app) {
14654            // If possible we want to avoid killing apps while they're being backed up
14655            if (adj > ProcessList.BACKUP_APP_ADJ) {
14656                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14657                adj = ProcessList.BACKUP_APP_ADJ;
14658                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14659                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14660                }
14661                app.adjType = "backup";
14662                app.cached = false;
14663            }
14664            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14665                procState = ActivityManager.PROCESS_STATE_BACKUP;
14666            }
14667        }
14668
14669        boolean mayBeTop = false;
14670
14671        for (int is = app.services.size()-1;
14672                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14673                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14674                        || procState > ActivityManager.PROCESS_STATE_TOP);
14675                is--) {
14676            ServiceRecord s = app.services.valueAt(is);
14677            if (s.startRequested) {
14678                app.hasStartedServices = true;
14679                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14680                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14681                }
14682                if (app.hasShownUi && app != mHomeProcess) {
14683                    // If this process has shown some UI, let it immediately
14684                    // go to the LRU list because it may be pretty heavy with
14685                    // UI stuff.  We'll tag it with a label just to help
14686                    // debug and understand what is going on.
14687                    if (adj > ProcessList.SERVICE_ADJ) {
14688                        app.adjType = "cch-started-ui-services";
14689                    }
14690                } else {
14691                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14692                        // This service has seen some activity within
14693                        // recent memory, so we will keep its process ahead
14694                        // of the background processes.
14695                        if (adj > ProcessList.SERVICE_ADJ) {
14696                            adj = ProcessList.SERVICE_ADJ;
14697                            app.adjType = "started-services";
14698                            app.cached = false;
14699                        }
14700                    }
14701                    // If we have let the service slide into the background
14702                    // state, still have some text describing what it is doing
14703                    // even though the service no longer has an impact.
14704                    if (adj > ProcessList.SERVICE_ADJ) {
14705                        app.adjType = "cch-started-services";
14706                    }
14707                }
14708                // Don't kill this process because it is doing work; it
14709                // has said it is doing work.
14710                app.keeping = true;
14711            }
14712            for (int conni = s.connections.size()-1;
14713                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14714                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14715                            || procState > ActivityManager.PROCESS_STATE_TOP);
14716                    conni--) {
14717                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14718                for (int i = 0;
14719                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14720                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14721                                || procState > ActivityManager.PROCESS_STATE_TOP);
14722                        i++) {
14723                    // XXX should compute this based on the max of
14724                    // all connected clients.
14725                    ConnectionRecord cr = clist.get(i);
14726                    if (cr.binding.client == app) {
14727                        // Binding to ourself is not interesting.
14728                        continue;
14729                    }
14730                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14731                        ProcessRecord client = cr.binding.client;
14732                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14733                                TOP_APP, doingAll, now);
14734                        int clientProcState = client.curProcState;
14735                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14736                            // If the other app is cached for any reason, for purposes here
14737                            // we are going to consider it empty.  The specific cached state
14738                            // doesn't propagate except under certain conditions.
14739                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14740                        }
14741                        String adjType = null;
14742                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14743                            // Not doing bind OOM management, so treat
14744                            // this guy more like a started service.
14745                            if (app.hasShownUi && app != mHomeProcess) {
14746                                // If this process has shown some UI, let it immediately
14747                                // go to the LRU list because it may be pretty heavy with
14748                                // UI stuff.  We'll tag it with a label just to help
14749                                // debug and understand what is going on.
14750                                if (adj > clientAdj) {
14751                                    adjType = "cch-bound-ui-services";
14752                                }
14753                                app.cached = false;
14754                                clientAdj = adj;
14755                                clientProcState = procState;
14756                            } else {
14757                                if (now >= (s.lastActivity
14758                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14759                                    // This service has not seen activity within
14760                                    // recent memory, so allow it to drop to the
14761                                    // LRU list if there is no other reason to keep
14762                                    // it around.  We'll also tag it with a label just
14763                                    // to help debug and undertand what is going on.
14764                                    if (adj > clientAdj) {
14765                                        adjType = "cch-bound-services";
14766                                    }
14767                                    clientAdj = adj;
14768                                }
14769                            }
14770                        }
14771                        if (adj > clientAdj) {
14772                            // If this process has recently shown UI, and
14773                            // the process that is binding to it is less
14774                            // important than being visible, then we don't
14775                            // care about the binding as much as we care
14776                            // about letting this process get into the LRU
14777                            // list to be killed and restarted if needed for
14778                            // memory.
14779                            if (app.hasShownUi && app != mHomeProcess
14780                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14781                                adjType = "cch-bound-ui-services";
14782                            } else {
14783                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14784                                        |Context.BIND_IMPORTANT)) != 0) {
14785                                    adj = clientAdj;
14786                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14787                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14788                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14789                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14790                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
14791                                    adj = clientAdj;
14792                                } else {
14793                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14794                                        adj = ProcessList.VISIBLE_APP_ADJ;
14795                                    }
14796                                }
14797                                if (!client.cached) {
14798                                    app.cached = false;
14799                                }
14800                                if (client.keeping) {
14801                                    app.keeping = true;
14802                                }
14803                                adjType = "service";
14804                            }
14805                        }
14806                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14807                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14808                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14809                            }
14810                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14811                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14812                                    // Special handling of clients who are in the top state.
14813                                    // We *may* want to consider this process to be in the
14814                                    // top state as well, but only if there is not another
14815                                    // reason for it to be running.  Being on the top is a
14816                                    // special state, meaning you are specifically running
14817                                    // for the current top app.  If the process is already
14818                                    // running in the background for some other reason, it
14819                                    // is more important to continue considering it to be
14820                                    // in the background state.
14821                                    mayBeTop = true;
14822                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14823                                } else {
14824                                    // Special handling for above-top states (persistent
14825                                    // processes).  These should not bring the current process
14826                                    // into the top state, since they are not on top.  Instead
14827                                    // give them the best state after that.
14828                                    clientProcState =
14829                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14830                                }
14831                            }
14832                        } else {
14833                            if (clientProcState <
14834                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14835                                clientProcState =
14836                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14837                            }
14838                        }
14839                        if (procState > clientProcState) {
14840                            procState = clientProcState;
14841                        }
14842                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
14843                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
14844                            app.pendingUiClean = true;
14845                        }
14846                        if (adjType != null) {
14847                            app.adjType = adjType;
14848                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14849                                    .REASON_SERVICE_IN_USE;
14850                            app.adjSource = cr.binding.client;
14851                            app.adjSourceOom = clientAdj;
14852                            app.adjTarget = s.name;
14853                        }
14854                    }
14855                    final ActivityRecord a = cr.activity;
14856                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
14857                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
14858                                (a.visible || a.state == ActivityState.RESUMED
14859                                 || a.state == ActivityState.PAUSING)) {
14860                            adj = ProcessList.FOREGROUND_APP_ADJ;
14861                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14862                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14863                            }
14864                            app.cached = false;
14865                            app.adjType = "service";
14866                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14867                                    .REASON_SERVICE_IN_USE;
14868                            app.adjSource = a;
14869                            app.adjSourceOom = adj;
14870                            app.adjTarget = s.name;
14871                        }
14872                    }
14873                }
14874            }
14875        }
14876
14877        for (int provi = app.pubProviders.size()-1;
14878                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14879                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14880                        || procState > ActivityManager.PROCESS_STATE_TOP);
14881                provi--) {
14882            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
14883            for (int i = cpr.connections.size()-1;
14884                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14885                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14886                            || procState > ActivityManager.PROCESS_STATE_TOP);
14887                    i--) {
14888                ContentProviderConnection conn = cpr.connections.get(i);
14889                ProcessRecord client = conn.client;
14890                if (client == app) {
14891                    // Being our own client is not interesting.
14892                    continue;
14893                }
14894                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
14895                int clientProcState = client.curProcState;
14896                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14897                    // If the other app is cached for any reason, for purposes here
14898                    // we are going to consider it empty.
14899                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14900                }
14901                if (adj > clientAdj) {
14902                    if (app.hasShownUi && app != mHomeProcess
14903                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14904                        app.adjType = "cch-ui-provider";
14905                    } else {
14906                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
14907                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
14908                        app.adjType = "provider";
14909                    }
14910                    app.cached &= client.cached;
14911                    app.keeping |= client.keeping;
14912                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14913                            .REASON_PROVIDER_IN_USE;
14914                    app.adjSource = client;
14915                    app.adjSourceOom = clientAdj;
14916                    app.adjTarget = cpr.name;
14917                }
14918                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14919                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14920                        // Special handling of clients who are in the top state.
14921                        // We *may* want to consider this process to be in the
14922                        // top state as well, but only if there is not another
14923                        // reason for it to be running.  Being on the top is a
14924                        // special state, meaning you are specifically running
14925                        // for the current top app.  If the process is already
14926                        // running in the background for some other reason, it
14927                        // is more important to continue considering it to be
14928                        // in the background state.
14929                        mayBeTop = true;
14930                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14931                    } else {
14932                        // Special handling for above-top states (persistent
14933                        // processes).  These should not bring the current process
14934                        // into the top state, since they are not on top.  Instead
14935                        // give them the best state after that.
14936                        clientProcState =
14937                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14938                    }
14939                }
14940                if (procState > clientProcState) {
14941                    procState = clientProcState;
14942                }
14943                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14944                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14945                }
14946            }
14947            // If the provider has external (non-framework) process
14948            // dependencies, ensure that its adjustment is at least
14949            // FOREGROUND_APP_ADJ.
14950            if (cpr.hasExternalProcessHandles()) {
14951                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
14952                    adj = ProcessList.FOREGROUND_APP_ADJ;
14953                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14954                    app.cached = false;
14955                    app.keeping = true;
14956                    app.adjType = "provider";
14957                    app.adjTarget = cpr.name;
14958                }
14959                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
14960                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14961                }
14962            }
14963        }
14964
14965        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
14966            // A client of one of our services or providers is in the top state.  We
14967            // *may* want to be in the top state, but not if we are already running in
14968            // the background for some other reason.  For the decision here, we are going
14969            // to pick out a few specific states that we want to remain in when a client
14970            // is top (states that tend to be longer-term) and otherwise allow it to go
14971            // to the top state.
14972            switch (procState) {
14973                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
14974                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
14975                case ActivityManager.PROCESS_STATE_SERVICE:
14976                    // These all are longer-term states, so pull them up to the top
14977                    // of the background states, but not all the way to the top state.
14978                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14979                    break;
14980                default:
14981                    // Otherwise, top is a better choice, so take it.
14982                    procState = ActivityManager.PROCESS_STATE_TOP;
14983                    break;
14984            }
14985        }
14986
14987        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) {
14988            // This is a cached process, but with client activities.  Mark it so.
14989            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
14990            app.adjType = "cch-client-act";
14991        }
14992
14993        if (adj == ProcessList.SERVICE_ADJ) {
14994            if (doingAll) {
14995                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
14996                mNewNumServiceProcs++;
14997                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
14998                if (!app.serviceb) {
14999                    // This service isn't far enough down on the LRU list to
15000                    // normally be a B service, but if we are low on RAM and it
15001                    // is large we want to force it down since we would prefer to
15002                    // keep launcher over it.
15003                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15004                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15005                        app.serviceHighRam = true;
15006                        app.serviceb = true;
15007                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15008                    } else {
15009                        mNewNumAServiceProcs++;
15010                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15011                    }
15012                } else {
15013                    app.serviceHighRam = false;
15014                }
15015            }
15016            if (app.serviceb) {
15017                adj = ProcessList.SERVICE_B_ADJ;
15018            }
15019        }
15020
15021        app.curRawAdj = adj;
15022
15023        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15024        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15025        if (adj > app.maxAdj) {
15026            adj = app.maxAdj;
15027            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15028                schedGroup = Process.THREAD_GROUP_DEFAULT;
15029            }
15030        }
15031        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15032            app.keeping = true;
15033        }
15034
15035        // Do final modification to adj.  Everything we do between here and applying
15036        // the final setAdj must be done in this function, because we will also use
15037        // it when computing the final cached adj later.  Note that we don't need to
15038        // worry about this for max adj above, since max adj will always be used to
15039        // keep it out of the cached vaues.
15040        adj = app.modifyRawOomAdj(adj);
15041
15042        app.curProcState = procState;
15043
15044        int importance = app.memImportance;
15045        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
15046            app.curAdj = adj;
15047            app.curSchedGroup = schedGroup;
15048            if (!interesting) {
15049                // For this reporting, if there is not something explicitly
15050                // interesting in this process then we will push it to the
15051                // background importance.
15052                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
15053            } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
15054                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
15055            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
15056                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
15057            } else if (adj >= ProcessList.HOME_APP_ADJ) {
15058                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
15059            } else if (adj >= ProcessList.SERVICE_ADJ) {
15060                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
15061            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15062                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
15063            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
15064                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
15065            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
15066                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
15067            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
15068                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
15069            } else {
15070                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
15071            }
15072        }
15073
15074        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
15075        if (foregroundActivities != app.foregroundActivities) {
15076            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15077        }
15078        if (changes != 0) {
15079            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15080            app.memImportance = importance;
15081            app.foregroundActivities = foregroundActivities;
15082            int i = mPendingProcessChanges.size()-1;
15083            ProcessChangeItem item = null;
15084            while (i >= 0) {
15085                item = mPendingProcessChanges.get(i);
15086                if (item.pid == app.pid) {
15087                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15088                    break;
15089                }
15090                i--;
15091            }
15092            if (i < 0) {
15093                // No existing item in pending changes; need a new one.
15094                final int NA = mAvailProcessChanges.size();
15095                if (NA > 0) {
15096                    item = mAvailProcessChanges.remove(NA-1);
15097                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15098                } else {
15099                    item = new ProcessChangeItem();
15100                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15101                }
15102                item.changes = 0;
15103                item.pid = app.pid;
15104                item.uid = app.info.uid;
15105                if (mPendingProcessChanges.size() == 0) {
15106                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15107                            "*** Enqueueing dispatch processes changed!");
15108                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15109                }
15110                mPendingProcessChanges.add(item);
15111            }
15112            item.changes |= changes;
15113            item.importance = importance;
15114            item.foregroundActivities = foregroundActivities;
15115            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
15116                    + Integer.toHexString(System.identityHashCode(item))
15117                    + " " + app.toShortString() + ": changes=" + item.changes
15118                    + " importance=" + item.importance
15119                    + " foreground=" + item.foregroundActivities
15120                    + " type=" + app.adjType + " source=" + app.adjSource
15121                    + " target=" + app.adjTarget);
15122        }
15123
15124        return app.curRawAdj;
15125    }
15126
15127    /**
15128     * Schedule PSS collection of a process.
15129     */
15130    void requestPssLocked(ProcessRecord proc, int procState) {
15131        if (mPendingPssProcesses.contains(proc)) {
15132            return;
15133        }
15134        if (mPendingPssProcesses.size() == 0) {
15135            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15136        }
15137        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15138        proc.pssProcState = procState;
15139        mPendingPssProcesses.add(proc);
15140    }
15141
15142    /**
15143     * Schedule PSS collection of all processes.
15144     */
15145    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15146        if (!always) {
15147            if (now < (mLastFullPssTime +
15148                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15149                return;
15150            }
15151        }
15152        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15153        mLastFullPssTime = now;
15154        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15155        mPendingPssProcesses.clear();
15156        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15157            ProcessRecord app = mLruProcesses.get(i);
15158            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15159                app.pssProcState = app.setProcState;
15160                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15161                        mSleeping, now);
15162                mPendingPssProcesses.add(app);
15163            }
15164        }
15165        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15166    }
15167
15168    /**
15169     * Ask a given process to GC right now.
15170     */
15171    final void performAppGcLocked(ProcessRecord app) {
15172        try {
15173            app.lastRequestedGc = SystemClock.uptimeMillis();
15174            if (app.thread != null) {
15175                if (app.reportLowMemory) {
15176                    app.reportLowMemory = false;
15177                    app.thread.scheduleLowMemory();
15178                } else {
15179                    app.thread.processInBackground();
15180                }
15181            }
15182        } catch (Exception e) {
15183            // whatever.
15184        }
15185    }
15186
15187    /**
15188     * Returns true if things are idle enough to perform GCs.
15189     */
15190    private final boolean canGcNowLocked() {
15191        boolean processingBroadcasts = false;
15192        for (BroadcastQueue q : mBroadcastQueues) {
15193            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15194                processingBroadcasts = true;
15195            }
15196        }
15197        return !processingBroadcasts
15198                && (mSleeping || mStackSupervisor.allResumedActivitiesIdle());
15199    }
15200
15201    /**
15202     * Perform GCs on all processes that are waiting for it, but only
15203     * if things are idle.
15204     */
15205    final void performAppGcsLocked() {
15206        final int N = mProcessesToGc.size();
15207        if (N <= 0) {
15208            return;
15209        }
15210        if (canGcNowLocked()) {
15211            while (mProcessesToGc.size() > 0) {
15212                ProcessRecord proc = mProcessesToGc.remove(0);
15213                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15214                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15215                            <= SystemClock.uptimeMillis()) {
15216                        // To avoid spamming the system, we will GC processes one
15217                        // at a time, waiting a few seconds between each.
15218                        performAppGcLocked(proc);
15219                        scheduleAppGcsLocked();
15220                        return;
15221                    } else {
15222                        // It hasn't been long enough since we last GCed this
15223                        // process...  put it in the list to wait for its time.
15224                        addProcessToGcListLocked(proc);
15225                        break;
15226                    }
15227                }
15228            }
15229
15230            scheduleAppGcsLocked();
15231        }
15232    }
15233
15234    /**
15235     * If all looks good, perform GCs on all processes waiting for them.
15236     */
15237    final void performAppGcsIfAppropriateLocked() {
15238        if (canGcNowLocked()) {
15239            performAppGcsLocked();
15240            return;
15241        }
15242        // Still not idle, wait some more.
15243        scheduleAppGcsLocked();
15244    }
15245
15246    /**
15247     * Schedule the execution of all pending app GCs.
15248     */
15249    final void scheduleAppGcsLocked() {
15250        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15251
15252        if (mProcessesToGc.size() > 0) {
15253            // Schedule a GC for the time to the next process.
15254            ProcessRecord proc = mProcessesToGc.get(0);
15255            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15256
15257            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15258            long now = SystemClock.uptimeMillis();
15259            if (when < (now+GC_TIMEOUT)) {
15260                when = now + GC_TIMEOUT;
15261            }
15262            mHandler.sendMessageAtTime(msg, when);
15263        }
15264    }
15265
15266    /**
15267     * Add a process to the array of processes waiting to be GCed.  Keeps the
15268     * list in sorted order by the last GC time.  The process can't already be
15269     * on the list.
15270     */
15271    final void addProcessToGcListLocked(ProcessRecord proc) {
15272        boolean added = false;
15273        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15274            if (mProcessesToGc.get(i).lastRequestedGc <
15275                    proc.lastRequestedGc) {
15276                added = true;
15277                mProcessesToGc.add(i+1, proc);
15278                break;
15279            }
15280        }
15281        if (!added) {
15282            mProcessesToGc.add(0, proc);
15283        }
15284    }
15285
15286    /**
15287     * Set up to ask a process to GC itself.  This will either do it
15288     * immediately, or put it on the list of processes to gc the next
15289     * time things are idle.
15290     */
15291    final void scheduleAppGcLocked(ProcessRecord app) {
15292        long now = SystemClock.uptimeMillis();
15293        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15294            return;
15295        }
15296        if (!mProcessesToGc.contains(app)) {
15297            addProcessToGcListLocked(app);
15298            scheduleAppGcsLocked();
15299        }
15300    }
15301
15302    final void checkExcessivePowerUsageLocked(boolean doKills) {
15303        updateCpuStatsNow();
15304
15305        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15306        boolean doWakeKills = doKills;
15307        boolean doCpuKills = doKills;
15308        if (mLastPowerCheckRealtime == 0) {
15309            doWakeKills = false;
15310        }
15311        if (mLastPowerCheckUptime == 0) {
15312            doCpuKills = false;
15313        }
15314        if (stats.isScreenOn()) {
15315            doWakeKills = false;
15316        }
15317        final long curRealtime = SystemClock.elapsedRealtime();
15318        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15319        final long curUptime = SystemClock.uptimeMillis();
15320        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15321        mLastPowerCheckRealtime = curRealtime;
15322        mLastPowerCheckUptime = curUptime;
15323        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15324            doWakeKills = false;
15325        }
15326        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15327            doCpuKills = false;
15328        }
15329        int i = mLruProcesses.size();
15330        while (i > 0) {
15331            i--;
15332            ProcessRecord app = mLruProcesses.get(i);
15333            if (!app.keeping) {
15334                long wtime;
15335                synchronized (stats) {
15336                    wtime = stats.getProcessWakeTime(app.info.uid,
15337                            app.pid, curRealtime);
15338                }
15339                long wtimeUsed = wtime - app.lastWakeTime;
15340                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15341                if (DEBUG_POWER) {
15342                    StringBuilder sb = new StringBuilder(128);
15343                    sb.append("Wake for ");
15344                    app.toShortString(sb);
15345                    sb.append(": over ");
15346                    TimeUtils.formatDuration(realtimeSince, sb);
15347                    sb.append(" used ");
15348                    TimeUtils.formatDuration(wtimeUsed, sb);
15349                    sb.append(" (");
15350                    sb.append((wtimeUsed*100)/realtimeSince);
15351                    sb.append("%)");
15352                    Slog.i(TAG, sb.toString());
15353                    sb.setLength(0);
15354                    sb.append("CPU for ");
15355                    app.toShortString(sb);
15356                    sb.append(": over ");
15357                    TimeUtils.formatDuration(uptimeSince, sb);
15358                    sb.append(" used ");
15359                    TimeUtils.formatDuration(cputimeUsed, sb);
15360                    sb.append(" (");
15361                    sb.append((cputimeUsed*100)/uptimeSince);
15362                    sb.append("%)");
15363                    Slog.i(TAG, sb.toString());
15364                }
15365                // If a process has held a wake lock for more
15366                // than 50% of the time during this period,
15367                // that sounds bad.  Kill!
15368                if (doWakeKills && realtimeSince > 0
15369                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15370                    synchronized (stats) {
15371                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15372                                realtimeSince, wtimeUsed);
15373                    }
15374                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15375                            + " during " + realtimeSince);
15376                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15377                } else if (doCpuKills && uptimeSince > 0
15378                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15379                    synchronized (stats) {
15380                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15381                                uptimeSince, cputimeUsed);
15382                    }
15383                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15384                            + " during " + uptimeSince);
15385                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15386                } else {
15387                    app.lastWakeTime = wtime;
15388                    app.lastCpuTime = app.curCpuTime;
15389                }
15390            }
15391        }
15392    }
15393
15394    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15395            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15396        boolean success = true;
15397
15398        if (app.curRawAdj != app.setRawAdj) {
15399            if (wasKeeping && !app.keeping) {
15400                // This app is no longer something we want to keep.  Note
15401                // its current wake lock time to later know to kill it if
15402                // it is not behaving well.
15403                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15404                synchronized (stats) {
15405                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15406                            app.pid, SystemClock.elapsedRealtime());
15407                }
15408                app.lastCpuTime = app.curCpuTime;
15409            }
15410
15411            app.setRawAdj = app.curRawAdj;
15412        }
15413
15414        if (app.curAdj != app.setAdj) {
15415            ProcessList.setOomAdj(app.pid, app.curAdj);
15416            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15417                TAG, "Set " + app.pid + " " + app.processName +
15418                " adj " + app.curAdj + ": " + app.adjType);
15419            app.setAdj = app.curAdj;
15420        }
15421
15422        if (app.setSchedGroup != app.curSchedGroup) {
15423            app.setSchedGroup = app.curSchedGroup;
15424            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15425                    "Setting process group of " + app.processName
15426                    + " to " + app.curSchedGroup);
15427            if (app.waitingToKill != null &&
15428                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15429                killUnneededProcessLocked(app, app.waitingToKill);
15430                success = false;
15431            } else {
15432                if (true) {
15433                    long oldId = Binder.clearCallingIdentity();
15434                    try {
15435                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15436                    } catch (Exception e) {
15437                        Slog.w(TAG, "Failed setting process group of " + app.pid
15438                                + " to " + app.curSchedGroup);
15439                        e.printStackTrace();
15440                    } finally {
15441                        Binder.restoreCallingIdentity(oldId);
15442                    }
15443                } else {
15444                    if (app.thread != null) {
15445                        try {
15446                            app.thread.setSchedulingGroup(app.curSchedGroup);
15447                        } catch (RemoteException e) {
15448                        }
15449                    }
15450                }
15451                Process.setSwappiness(app.pid,
15452                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15453            }
15454        }
15455        if (app.repProcState != app.curProcState) {
15456            app.repProcState = app.curProcState;
15457            if (!reportingProcessState && app.thread != null) {
15458                try {
15459                    if (false) {
15460                        //RuntimeException h = new RuntimeException("here");
15461                        Slog.i(TAG, "Sending new process state " + app.repProcState
15462                                + " to " + app /*, h*/);
15463                    }
15464                    app.thread.setProcessState(app.repProcState);
15465                } catch (RemoteException e) {
15466                }
15467            }
15468        }
15469        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15470                app.setProcState)) {
15471            app.lastStateTime = now;
15472            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15473                    mSleeping, now);
15474            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15475                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15476                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15477                    + (app.nextPssTime-now) + ": " + app);
15478        } else {
15479            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15480                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15481                requestPssLocked(app, app.setProcState);
15482                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15483                        mSleeping, now);
15484            } else if (false && DEBUG_PSS) {
15485                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15486            }
15487        }
15488        if (app.setProcState != app.curProcState) {
15489            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15490                    "Proc state change of " + app.processName
15491                    + " to " + app.curProcState);
15492            app.setProcState = app.curProcState;
15493            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15494                app.notCachedSinceIdle = false;
15495            }
15496            if (!doingAll) {
15497                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15498            } else {
15499                app.procStateChanged = true;
15500            }
15501        }
15502        return success;
15503    }
15504
15505    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15506        if (proc.thread != null && proc.baseProcessTracker != null) {
15507            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15508        }
15509    }
15510
15511    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15512            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15513        if (app.thread == null) {
15514            return false;
15515        }
15516
15517        final boolean wasKeeping = app.keeping;
15518
15519        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15520
15521        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll,
15522                reportingProcessState, now);
15523    }
15524
15525    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15526            boolean oomAdj) {
15527        if (isForeground != proc.foregroundServices) {
15528            proc.foregroundServices = isForeground;
15529            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15530                    proc.info.uid);
15531            if (isForeground) {
15532                if (curProcs == null) {
15533                    curProcs = new ArrayList<ProcessRecord>();
15534                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15535                }
15536                if (!curProcs.contains(proc)) {
15537                    curProcs.add(proc);
15538                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15539                            proc.info.packageName, proc.info.uid);
15540                }
15541            } else {
15542                if (curProcs != null) {
15543                    if (curProcs.remove(proc)) {
15544                        mBatteryStatsService.noteEvent(
15545                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15546                                proc.info.packageName, proc.info.uid);
15547                        if (curProcs.size() <= 0) {
15548                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15549                        }
15550                    }
15551                }
15552            }
15553            if (oomAdj) {
15554                updateOomAdjLocked();
15555            }
15556        }
15557    }
15558
15559    private final ActivityRecord resumedAppLocked() {
15560        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15561        String pkg;
15562        int uid;
15563        if (act != null) {
15564            pkg = act.packageName;
15565            uid = act.info.applicationInfo.uid;
15566        } else {
15567            pkg = null;
15568            uid = -1;
15569        }
15570        // Has the UID or resumed package name changed?
15571        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15572                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15573            if (mCurResumedPackage != null) {
15574                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15575                        mCurResumedPackage, mCurResumedUid);
15576            }
15577            mCurResumedPackage = pkg;
15578            mCurResumedUid = uid;
15579            if (mCurResumedPackage != null) {
15580                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15581                        mCurResumedPackage, mCurResumedUid);
15582            }
15583        }
15584        return act;
15585    }
15586
15587    final boolean updateOomAdjLocked(ProcessRecord app) {
15588        return updateOomAdjLocked(app, false);
15589    }
15590
15591    final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) {
15592        final ActivityRecord TOP_ACT = resumedAppLocked();
15593        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15594        final boolean wasCached = app.cached;
15595
15596        mAdjSeq++;
15597
15598        // This is the desired cached adjusment we want to tell it to use.
15599        // If our app is currently cached, we know it, and that is it.  Otherwise,
15600        // we don't know it yet, and it needs to now be cached we will then
15601        // need to do a complete oom adj.
15602        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15603                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15604        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState,
15605                SystemClock.uptimeMillis());
15606        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15607            // Changed to/from cached state, so apps after it in the LRU
15608            // list may also be changed.
15609            updateOomAdjLocked();
15610        }
15611        return success;
15612    }
15613
15614    final void updateOomAdjLocked() {
15615        final ActivityRecord TOP_ACT = resumedAppLocked();
15616        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15617        final long now = SystemClock.uptimeMillis();
15618        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15619        final int N = mLruProcesses.size();
15620
15621        if (false) {
15622            RuntimeException e = new RuntimeException();
15623            e.fillInStackTrace();
15624            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15625        }
15626
15627        mAdjSeq++;
15628        mNewNumServiceProcs = 0;
15629        mNewNumAServiceProcs = 0;
15630
15631        final int emptyProcessLimit;
15632        final int cachedProcessLimit;
15633        if (mProcessLimit <= 0) {
15634            emptyProcessLimit = cachedProcessLimit = 0;
15635        } else if (mProcessLimit == 1) {
15636            emptyProcessLimit = 1;
15637            cachedProcessLimit = 0;
15638        } else {
15639            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15640            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15641        }
15642
15643        // Let's determine how many processes we have running vs.
15644        // how many slots we have for background processes; we may want
15645        // to put multiple processes in a slot of there are enough of
15646        // them.
15647        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15648                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15649        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15650        if (numEmptyProcs > cachedProcessLimit) {
15651            // If there are more empty processes than our limit on cached
15652            // processes, then use the cached process limit for the factor.
15653            // This ensures that the really old empty processes get pushed
15654            // down to the bottom, so if we are running low on memory we will
15655            // have a better chance at keeping around more cached processes
15656            // instead of a gazillion empty processes.
15657            numEmptyProcs = cachedProcessLimit;
15658        }
15659        int emptyFactor = numEmptyProcs/numSlots;
15660        if (emptyFactor < 1) emptyFactor = 1;
15661        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15662        if (cachedFactor < 1) cachedFactor = 1;
15663        int stepCached = 0;
15664        int stepEmpty = 0;
15665        int numCached = 0;
15666        int numEmpty = 0;
15667        int numTrimming = 0;
15668
15669        mNumNonCachedProcs = 0;
15670        mNumCachedHiddenProcs = 0;
15671
15672        // First update the OOM adjustment for each of the
15673        // application processes based on their current state.
15674        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15675        int nextCachedAdj = curCachedAdj+1;
15676        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15677        int nextEmptyAdj = curEmptyAdj+2;
15678        for (int i=N-1; i>=0; i--) {
15679            ProcessRecord app = mLruProcesses.get(i);
15680            if (!app.killedByAm && app.thread != null) {
15681                app.procStateChanged = false;
15682                final boolean wasKeeping = app.keeping;
15683                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15684
15685                // If we haven't yet assigned the final cached adj
15686                // to the process, do that now.
15687                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15688                    switch (app.curProcState) {
15689                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15690                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15691                            // This process is a cached process holding activities...
15692                            // assign it the next cached value for that type, and then
15693                            // step that cached level.
15694                            app.curRawAdj = curCachedAdj;
15695                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15696                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15697                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15698                                    + ")");
15699                            if (curCachedAdj != nextCachedAdj) {
15700                                stepCached++;
15701                                if (stepCached >= cachedFactor) {
15702                                    stepCached = 0;
15703                                    curCachedAdj = nextCachedAdj;
15704                                    nextCachedAdj += 2;
15705                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15706                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15707                                    }
15708                                }
15709                            }
15710                            break;
15711                        default:
15712                            // For everything else, assign next empty cached process
15713                            // level and bump that up.  Note that this means that
15714                            // long-running services that have dropped down to the
15715                            // cached level will be treated as empty (since their process
15716                            // state is still as a service), which is what we want.
15717                            app.curRawAdj = curEmptyAdj;
15718                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15719                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15720                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15721                                    + ")");
15722                            if (curEmptyAdj != nextEmptyAdj) {
15723                                stepEmpty++;
15724                                if (stepEmpty >= emptyFactor) {
15725                                    stepEmpty = 0;
15726                                    curEmptyAdj = nextEmptyAdj;
15727                                    nextEmptyAdj += 2;
15728                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15729                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15730                                    }
15731                                }
15732                            }
15733                            break;
15734                    }
15735                }
15736
15737                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now);
15738
15739                // Count the number of process types.
15740                switch (app.curProcState) {
15741                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15742                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15743                        mNumCachedHiddenProcs++;
15744                        numCached++;
15745                        if (numCached > cachedProcessLimit) {
15746                            killUnneededProcessLocked(app, "cached #" + numCached);
15747                        }
15748                        break;
15749                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15750                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15751                                && app.lastActivityTime < oldTime) {
15752                            killUnneededProcessLocked(app, "empty for "
15753                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15754                                    / 1000) + "s");
15755                        } else {
15756                            numEmpty++;
15757                            if (numEmpty > emptyProcessLimit) {
15758                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15759                            }
15760                        }
15761                        break;
15762                    default:
15763                        mNumNonCachedProcs++;
15764                        break;
15765                }
15766
15767                if (app.isolated && app.services.size() <= 0) {
15768                    // If this is an isolated process, and there are no
15769                    // services running in it, then the process is no longer
15770                    // needed.  We agressively kill these because we can by
15771                    // definition not re-use the same process again, and it is
15772                    // good to avoid having whatever code was running in them
15773                    // left sitting around after no longer needed.
15774                    killUnneededProcessLocked(app, "isolated not needed");
15775                }
15776
15777                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15778                        && !app.killedByAm) {
15779                    numTrimming++;
15780                }
15781            }
15782        }
15783
15784        mNumServiceProcs = mNewNumServiceProcs;
15785
15786        // Now determine the memory trimming level of background processes.
15787        // Unfortunately we need to start at the back of the list to do this
15788        // properly.  We only do this if the number of background apps we
15789        // are managing to keep around is less than half the maximum we desire;
15790        // if we are keeping a good number around, we'll let them use whatever
15791        // memory they want.
15792        final int numCachedAndEmpty = numCached + numEmpty;
15793        int memFactor;
15794        if (numCached <= ProcessList.TRIM_CACHED_APPS
15795                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
15796            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
15797                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
15798            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
15799                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
15800            } else {
15801                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
15802            }
15803        } else {
15804            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
15805        }
15806        // We always allow the memory level to go up (better).  We only allow it to go
15807        // down if we are in a state where that is allowed, *and* the total number of processes
15808        // has gone down since last time.
15809        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
15810                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
15811                + " last=" + mLastNumProcesses);
15812        if (memFactor > mLastMemoryLevel) {
15813            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
15814                memFactor = mLastMemoryLevel;
15815                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
15816            }
15817        }
15818        mLastMemoryLevel = memFactor;
15819        mLastNumProcesses = mLruProcesses.size();
15820        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now);
15821        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
15822        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
15823            if (mLowRamStartTime == 0) {
15824                mLowRamStartTime = now;
15825            }
15826            int step = 0;
15827            int fgTrimLevel;
15828            switch (memFactor) {
15829                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15830                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
15831                    break;
15832                case ProcessStats.ADJ_MEM_FACTOR_LOW:
15833                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
15834                    break;
15835                default:
15836                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
15837                    break;
15838            }
15839            int factor = numTrimming/3;
15840            int minFactor = 2;
15841            if (mHomeProcess != null) minFactor++;
15842            if (mPreviousProcess != null) minFactor++;
15843            if (factor < minFactor) factor = minFactor;
15844            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
15845            for (int i=N-1; i>=0; i--) {
15846                ProcessRecord app = mLruProcesses.get(i);
15847                if (allChanged || app.procStateChanged) {
15848                    setProcessTrackerState(app, trackerMemFactor, now);
15849                    app.procStateChanged = false;
15850                }
15851                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15852                        && !app.killedByAm) {
15853                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
15854                        try {
15855                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15856                                    "Trimming memory of " + app.processName
15857                                    + " to " + curLevel);
15858                            app.thread.scheduleTrimMemory(curLevel);
15859                        } catch (RemoteException e) {
15860                        }
15861                        if (false) {
15862                            // For now we won't do this; our memory trimming seems
15863                            // to be good enough at this point that destroying
15864                            // activities causes more harm than good.
15865                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
15866                                    && app != mHomeProcess && app != mPreviousProcess) {
15867                                // Need to do this on its own message because the stack may not
15868                                // be in a consistent state at this point.
15869                                // For these apps we will also finish their activities
15870                                // to help them free memory.
15871                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
15872                            }
15873                        }
15874                    }
15875                    app.trimMemoryLevel = curLevel;
15876                    step++;
15877                    if (step >= factor) {
15878                        step = 0;
15879                        switch (curLevel) {
15880                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
15881                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
15882                                break;
15883                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
15884                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15885                                break;
15886                        }
15887                    }
15888                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15889                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
15890                            && app.thread != null) {
15891                        try {
15892                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15893                                    "Trimming memory of heavy-weight " + app.processName
15894                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15895                            app.thread.scheduleTrimMemory(
15896                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15897                        } catch (RemoteException e) {
15898                        }
15899                    }
15900                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15901                } else {
15902                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15903                            || app.systemNoUi) && app.pendingUiClean) {
15904                        // If this application is now in the background and it
15905                        // had done UI, then give it the special trim level to
15906                        // have it free UI resources.
15907                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
15908                        if (app.trimMemoryLevel < level && app.thread != null) {
15909                            try {
15910                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15911                                        "Trimming memory of bg-ui " + app.processName
15912                                        + " to " + level);
15913                                app.thread.scheduleTrimMemory(level);
15914                            } catch (RemoteException e) {
15915                            }
15916                        }
15917                        app.pendingUiClean = false;
15918                    }
15919                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
15920                        try {
15921                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15922                                    "Trimming memory of fg " + app.processName
15923                                    + " to " + fgTrimLevel);
15924                            app.thread.scheduleTrimMemory(fgTrimLevel);
15925                        } catch (RemoteException e) {
15926                        }
15927                    }
15928                    app.trimMemoryLevel = fgTrimLevel;
15929                }
15930            }
15931        } else {
15932            if (mLowRamStartTime != 0) {
15933                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
15934                mLowRamStartTime = 0;
15935            }
15936            for (int i=N-1; i>=0; i--) {
15937                ProcessRecord app = mLruProcesses.get(i);
15938                if (allChanged || app.procStateChanged) {
15939                    setProcessTrackerState(app, trackerMemFactor, now);
15940                    app.procStateChanged = false;
15941                }
15942                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15943                        || app.systemNoUi) && app.pendingUiClean) {
15944                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
15945                            && app.thread != null) {
15946                        try {
15947                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15948                                    "Trimming memory of ui hidden " + app.processName
15949                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15950                            app.thread.scheduleTrimMemory(
15951                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15952                        } catch (RemoteException e) {
15953                        }
15954                    }
15955                    app.pendingUiClean = false;
15956                }
15957                app.trimMemoryLevel = 0;
15958            }
15959        }
15960
15961        if (mAlwaysFinishActivities) {
15962            // Need to do this on its own message because the stack may not
15963            // be in a consistent state at this point.
15964            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
15965        }
15966
15967        if (allChanged) {
15968            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
15969        }
15970
15971        if (mProcessStats.shouldWriteNowLocked(now)) {
15972            mHandler.post(new Runnable() {
15973                @Override public void run() {
15974                    synchronized (ActivityManagerService.this) {
15975                        mProcessStats.writeStateAsyncLocked();
15976                    }
15977                }
15978            });
15979        }
15980
15981        if (DEBUG_OOM_ADJ) {
15982            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
15983        }
15984    }
15985
15986    final void trimApplications() {
15987        synchronized (this) {
15988            int i;
15989
15990            // First remove any unused application processes whose package
15991            // has been removed.
15992            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
15993                final ProcessRecord app = mRemovedProcesses.get(i);
15994                if (app.activities.size() == 0
15995                        && app.curReceiver == null && app.services.size() == 0) {
15996                    Slog.i(
15997                        TAG, "Exiting empty application process "
15998                        + app.processName + " ("
15999                        + (app.thread != null ? app.thread.asBinder() : null)
16000                        + ")\n");
16001                    if (app.pid > 0 && app.pid != MY_PID) {
16002                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16003                                app.processName, app.setAdj, "empty");
16004                        app.killedByAm = true;
16005                        Process.killProcessQuiet(app.pid);
16006                    } else {
16007                        try {
16008                            app.thread.scheduleExit();
16009                        } catch (Exception e) {
16010                            // Ignore exceptions.
16011                        }
16012                    }
16013                    cleanUpApplicationRecordLocked(app, false, true, -1);
16014                    mRemovedProcesses.remove(i);
16015
16016                    if (app.persistent) {
16017                        if (app.persistent) {
16018                            addAppLocked(app.info, false);
16019                        }
16020                    }
16021                }
16022            }
16023
16024            // Now update the oom adj for all processes.
16025            updateOomAdjLocked();
16026        }
16027    }
16028
16029    /** This method sends the specified signal to each of the persistent apps */
16030    public void signalPersistentProcesses(int sig) throws RemoteException {
16031        if (sig != Process.SIGNAL_USR1) {
16032            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16033        }
16034
16035        synchronized (this) {
16036            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16037                    != PackageManager.PERMISSION_GRANTED) {
16038                throw new SecurityException("Requires permission "
16039                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16040            }
16041
16042            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16043                ProcessRecord r = mLruProcesses.get(i);
16044                if (r.thread != null && r.persistent) {
16045                    Process.sendSignal(r.pid, sig);
16046                }
16047            }
16048        }
16049    }
16050
16051    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16052        if (proc == null || proc == mProfileProc) {
16053            proc = mProfileProc;
16054            path = mProfileFile;
16055            profileType = mProfileType;
16056            clearProfilerLocked();
16057        }
16058        if (proc == null) {
16059            return;
16060        }
16061        try {
16062            proc.thread.profilerControl(false, path, null, profileType);
16063        } catch (RemoteException e) {
16064            throw new IllegalStateException("Process disappeared");
16065        }
16066    }
16067
16068    private void clearProfilerLocked() {
16069        if (mProfileFd != null) {
16070            try {
16071                mProfileFd.close();
16072            } catch (IOException e) {
16073            }
16074        }
16075        mProfileApp = null;
16076        mProfileProc = null;
16077        mProfileFile = null;
16078        mProfileType = 0;
16079        mAutoStopProfiler = false;
16080    }
16081
16082    public boolean profileControl(String process, int userId, boolean start,
16083            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16084
16085        try {
16086            synchronized (this) {
16087                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16088                // its own permission.
16089                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16090                        != PackageManager.PERMISSION_GRANTED) {
16091                    throw new SecurityException("Requires permission "
16092                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16093                }
16094
16095                if (start && fd == null) {
16096                    throw new IllegalArgumentException("null fd");
16097                }
16098
16099                ProcessRecord proc = null;
16100                if (process != null) {
16101                    proc = findProcessLocked(process, userId, "profileControl");
16102                }
16103
16104                if (start && (proc == null || proc.thread == null)) {
16105                    throw new IllegalArgumentException("Unknown process: " + process);
16106                }
16107
16108                if (start) {
16109                    stopProfilerLocked(null, null, 0);
16110                    setProfileApp(proc.info, proc.processName, path, fd, false);
16111                    mProfileProc = proc;
16112                    mProfileType = profileType;
16113                    try {
16114                        fd = fd.dup();
16115                    } catch (IOException e) {
16116                        fd = null;
16117                    }
16118                    proc.thread.profilerControl(start, path, fd, profileType);
16119                    fd = null;
16120                    mProfileFd = null;
16121                } else {
16122                    stopProfilerLocked(proc, path, profileType);
16123                    if (fd != null) {
16124                        try {
16125                            fd.close();
16126                        } catch (IOException e) {
16127                        }
16128                    }
16129                }
16130
16131                return true;
16132            }
16133        } catch (RemoteException e) {
16134            throw new IllegalStateException("Process disappeared");
16135        } finally {
16136            if (fd != null) {
16137                try {
16138                    fd.close();
16139                } catch (IOException e) {
16140                }
16141            }
16142        }
16143    }
16144
16145    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16146        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16147                userId, true, true, callName, null);
16148        ProcessRecord proc = null;
16149        try {
16150            int pid = Integer.parseInt(process);
16151            synchronized (mPidsSelfLocked) {
16152                proc = mPidsSelfLocked.get(pid);
16153            }
16154        } catch (NumberFormatException e) {
16155        }
16156
16157        if (proc == null) {
16158            ArrayMap<String, SparseArray<ProcessRecord>> all
16159                    = mProcessNames.getMap();
16160            SparseArray<ProcessRecord> procs = all.get(process);
16161            if (procs != null && procs.size() > 0) {
16162                proc = procs.valueAt(0);
16163                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16164                    for (int i=1; i<procs.size(); i++) {
16165                        ProcessRecord thisProc = procs.valueAt(i);
16166                        if (thisProc.userId == userId) {
16167                            proc = thisProc;
16168                            break;
16169                        }
16170                    }
16171                }
16172            }
16173        }
16174
16175        return proc;
16176    }
16177
16178    public boolean dumpHeap(String process, int userId, boolean managed,
16179            String path, ParcelFileDescriptor fd) throws RemoteException {
16180
16181        try {
16182            synchronized (this) {
16183                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16184                // its own permission (same as profileControl).
16185                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16186                        != PackageManager.PERMISSION_GRANTED) {
16187                    throw new SecurityException("Requires permission "
16188                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16189                }
16190
16191                if (fd == null) {
16192                    throw new IllegalArgumentException("null fd");
16193                }
16194
16195                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16196                if (proc == null || proc.thread == null) {
16197                    throw new IllegalArgumentException("Unknown process: " + process);
16198                }
16199
16200                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16201                if (!isDebuggable) {
16202                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16203                        throw new SecurityException("Process not debuggable: " + proc);
16204                    }
16205                }
16206
16207                proc.thread.dumpHeap(managed, path, fd);
16208                fd = null;
16209                return true;
16210            }
16211        } catch (RemoteException e) {
16212            throw new IllegalStateException("Process disappeared");
16213        } finally {
16214            if (fd != null) {
16215                try {
16216                    fd.close();
16217                } catch (IOException e) {
16218                }
16219            }
16220        }
16221    }
16222
16223    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16224    public void monitor() {
16225        synchronized (this) { }
16226    }
16227
16228    void onCoreSettingsChange(Bundle settings) {
16229        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16230            ProcessRecord processRecord = mLruProcesses.get(i);
16231            try {
16232                if (processRecord.thread != null) {
16233                    processRecord.thread.setCoreSettings(settings);
16234                }
16235            } catch (RemoteException re) {
16236                /* ignore */
16237            }
16238        }
16239    }
16240
16241    // Multi-user methods
16242
16243    /**
16244     * Start user, if its not already running, but don't bring it to foreground.
16245     */
16246    @Override
16247    public boolean startUserInBackground(final int userId) {
16248        return startUser(userId, /* foreground */ false);
16249    }
16250
16251    /**
16252     * Refreshes the list of users related to the current user when either a
16253     * user switch happens or when a new related user is started in the
16254     * background.
16255     */
16256    private void updateRelatedUserIdsLocked() {
16257        final List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(mCurrentUserId);
16258        int[] relatedUserIds = new int[relatedUsers.size()]; // relatedUsers will not be null
16259        for (int i = 0; i < relatedUserIds.length; i++) {
16260            relatedUserIds[i] = relatedUsers.get(i).id;
16261        }
16262        mRelatedUserIds = relatedUserIds;
16263    }
16264
16265    @Override
16266    public boolean switchUser(final int userId) {
16267        return startUser(userId, /* foregound */ true);
16268    }
16269
16270    private boolean startUser(final int userId, boolean foreground) {
16271        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16272                != PackageManager.PERMISSION_GRANTED) {
16273            String msg = "Permission Denial: switchUser() from pid="
16274                    + Binder.getCallingPid()
16275                    + ", uid=" + Binder.getCallingUid()
16276                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16277            Slog.w(TAG, msg);
16278            throw new SecurityException(msg);
16279        }
16280
16281        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16282
16283        final long ident = Binder.clearCallingIdentity();
16284        try {
16285            synchronized (this) {
16286                final int oldUserId = mCurrentUserId;
16287                if (oldUserId == userId) {
16288                    return true;
16289                }
16290
16291                mStackSupervisor.setLockTaskModeLocked(null);
16292
16293                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16294                if (userInfo == null) {
16295                    Slog.w(TAG, "No user info for user #" + userId);
16296                    return false;
16297                }
16298
16299                if (foreground) {
16300                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16301                            R.anim.screen_user_enter);
16302                }
16303
16304                boolean needStart = false;
16305
16306                // If the user we are switching to is not currently started, then
16307                // we need to start it now.
16308                if (mStartedUsers.get(userId) == null) {
16309                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16310                    updateStartedUserArrayLocked();
16311                    needStart = true;
16312                }
16313
16314                final Integer userIdInt = Integer.valueOf(userId);
16315                mUserLru.remove(userIdInt);
16316                mUserLru.add(userIdInt);
16317
16318                if (foreground) {
16319                    mCurrentUserId = userId;
16320                    updateRelatedUserIdsLocked();
16321                    mWindowManager.setCurrentUser(userId, mRelatedUserIds);
16322                    // Once the internal notion of the active user has switched, we lock the device
16323                    // with the option to show the user switcher on the keyguard.
16324                    mWindowManager.lockNow(null);
16325                } else {
16326                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16327                    updateRelatedUserIdsLocked();
16328                    mWindowManager.updateRelatedUserIds(mRelatedUserIds);
16329                    mUserLru.remove(currentUserIdInt);
16330                    mUserLru.add(currentUserIdInt);
16331                }
16332
16333                final UserStartedState uss = mStartedUsers.get(userId);
16334
16335                // Make sure user is in the started state.  If it is currently
16336                // stopping, we need to knock that off.
16337                if (uss.mState == UserStartedState.STATE_STOPPING) {
16338                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16339                    // so we can just fairly silently bring the user back from
16340                    // the almost-dead.
16341                    uss.mState = UserStartedState.STATE_RUNNING;
16342                    updateStartedUserArrayLocked();
16343                    needStart = true;
16344                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16345                    // This means ACTION_SHUTDOWN has been sent, so we will
16346                    // need to treat this as a new boot of the user.
16347                    uss.mState = UserStartedState.STATE_BOOTING;
16348                    updateStartedUserArrayLocked();
16349                    needStart = true;
16350                }
16351
16352                if (foreground) {
16353                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16354                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16355                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16356                            oldUserId, userId, uss));
16357                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16358                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16359                }
16360
16361                if (needStart) {
16362                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16363                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16364                            | Intent.FLAG_RECEIVER_FOREGROUND);
16365                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16366                    broadcastIntentLocked(null, null, intent,
16367                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16368                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16369                }
16370
16371                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16372                    if (userId != 0) {
16373                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16374                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16375                        broadcastIntentLocked(null, null, intent, null,
16376                                new IIntentReceiver.Stub() {
16377                                    public void performReceive(Intent intent, int resultCode,
16378                                            String data, Bundle extras, boolean ordered,
16379                                            boolean sticky, int sendingUser) {
16380                                        userInitialized(uss, userId);
16381                                    }
16382                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16383                                true, false, MY_PID, Process.SYSTEM_UID,
16384                                userId);
16385                        uss.initializing = true;
16386                    } else {
16387                        getUserManagerLocked().makeInitialized(userInfo.id);
16388                    }
16389                }
16390
16391                if (foreground) {
16392                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16393                    if (homeInFront) {
16394                        startHomeActivityLocked(userId);
16395                    } else {
16396                        mStackSupervisor.resumeTopActivitiesLocked();
16397                    }
16398                    EventLogTags.writeAmSwitchUser(userId);
16399                    getUserManagerLocked().userForeground(userId);
16400                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16401                }
16402
16403                if (needStart) {
16404                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16405                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16406                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16407                    broadcastIntentLocked(null, null, intent,
16408                            null, new IIntentReceiver.Stub() {
16409                                @Override
16410                                public void performReceive(Intent intent, int resultCode, String data,
16411                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16412                                        throws RemoteException {
16413                                }
16414                            }, 0, null, null,
16415                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16416                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16417                }
16418            }
16419        } finally {
16420            Binder.restoreCallingIdentity(ident);
16421        }
16422
16423        return true;
16424    }
16425
16426    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16427        long ident = Binder.clearCallingIdentity();
16428        try {
16429            Intent intent;
16430            if (oldUserId >= 0) {
16431                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16432                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16433                        | Intent.FLAG_RECEIVER_FOREGROUND);
16434                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16435                broadcastIntentLocked(null, null, intent,
16436                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16437                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16438            }
16439            if (newUserId >= 0) {
16440                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16441                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16442                        | Intent.FLAG_RECEIVER_FOREGROUND);
16443                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16444                broadcastIntentLocked(null, null, intent,
16445                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16446                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16447                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16448                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16449                        | Intent.FLAG_RECEIVER_FOREGROUND);
16450                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16451                broadcastIntentLocked(null, null, intent,
16452                        null, null, 0, null, null,
16453                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16454                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16455            }
16456        } finally {
16457            Binder.restoreCallingIdentity(ident);
16458        }
16459    }
16460
16461    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16462            final int newUserId) {
16463        final int N = mUserSwitchObservers.beginBroadcast();
16464        if (N > 0) {
16465            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16466                int mCount = 0;
16467                @Override
16468                public void sendResult(Bundle data) throws RemoteException {
16469                    synchronized (ActivityManagerService.this) {
16470                        if (mCurUserSwitchCallback == this) {
16471                            mCount++;
16472                            if (mCount == N) {
16473                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16474                            }
16475                        }
16476                    }
16477                }
16478            };
16479            synchronized (this) {
16480                uss.switching = true;
16481                mCurUserSwitchCallback = callback;
16482            }
16483            for (int i=0; i<N; i++) {
16484                try {
16485                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16486                            newUserId, callback);
16487                } catch (RemoteException e) {
16488                }
16489            }
16490        } else {
16491            synchronized (this) {
16492                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16493            }
16494        }
16495        mUserSwitchObservers.finishBroadcast();
16496    }
16497
16498    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16499        synchronized (this) {
16500            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16501            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16502        }
16503    }
16504
16505    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16506        mCurUserSwitchCallback = null;
16507        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16508        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16509                oldUserId, newUserId, uss));
16510    }
16511
16512    void userInitialized(UserStartedState uss, int newUserId) {
16513        completeSwitchAndInitalize(uss, newUserId, true, false);
16514    }
16515
16516    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16517        completeSwitchAndInitalize(uss, newUserId, false, true);
16518    }
16519
16520    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16521            boolean clearInitializing, boolean clearSwitching) {
16522        boolean unfrozen = false;
16523        synchronized (this) {
16524            if (clearInitializing) {
16525                uss.initializing = false;
16526                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16527            }
16528            if (clearSwitching) {
16529                uss.switching = false;
16530            }
16531            if (!uss.switching && !uss.initializing) {
16532                mWindowManager.stopFreezingScreen();
16533                unfrozen = true;
16534            }
16535        }
16536        if (unfrozen) {
16537            final int N = mUserSwitchObservers.beginBroadcast();
16538            for (int i=0; i<N; i++) {
16539                try {
16540                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16541                } catch (RemoteException e) {
16542                }
16543            }
16544            mUserSwitchObservers.finishBroadcast();
16545        }
16546    }
16547
16548    void scheduleStartRelatedUsersLocked() {
16549        if (!mHandler.hasMessages(START_RELATED_USERS_MSG)) {
16550            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_RELATED_USERS_MSG),
16551                    DateUtils.SECOND_IN_MILLIS);
16552        }
16553    }
16554
16555    void startRelatedUsersLocked() {
16556        if (DEBUG_MU) Slog.i(TAG_MU, "startRelatedUsersLocked");
16557        List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(mCurrentUserId);
16558        List<UserInfo> toStart = new ArrayList<UserInfo>(relatedUsers.size());
16559        for (UserInfo relatedUser : relatedUsers) {
16560            if ((relatedUser.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED) {
16561                toStart.add(relatedUser);
16562            }
16563        }
16564        final int n = toStart.size();
16565        int i = 0;
16566        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
16567            startUserInBackground(toStart.get(i).id);
16568        }
16569        if (i < n) {
16570            Slog.w(TAG_MU, "More related users than MAX_RUNNING_USERS");
16571        }
16572    }
16573
16574    void finishUserSwitch(UserStartedState uss) {
16575        synchronized (this) {
16576            if (uss.mState == UserStartedState.STATE_BOOTING
16577                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16578                uss.mState = UserStartedState.STATE_RUNNING;
16579                final int userId = uss.mHandle.getIdentifier();
16580                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16581                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16582                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16583                broadcastIntentLocked(null, null, intent,
16584                        null, null, 0, null, null,
16585                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16586                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16587            }
16588
16589            startRelatedUsersLocked();
16590
16591            int num = mUserLru.size();
16592            int i = 0;
16593            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16594                Integer oldUserId = mUserLru.get(i);
16595                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16596                if (oldUss == null) {
16597                    // Shouldn't happen, but be sane if it does.
16598                    mUserLru.remove(i);
16599                    num--;
16600                    continue;
16601                }
16602                if (oldUss.mState == UserStartedState.STATE_STOPPING
16603                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16604                    // This user is already stopping, doesn't count.
16605                    num--;
16606                    i++;
16607                    continue;
16608                }
16609                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16610                    // Owner and current can't be stopped, but count as running.
16611                    i++;
16612                    continue;
16613                }
16614                // This is a user to be stopped.
16615                stopUserLocked(oldUserId, null);
16616                num--;
16617                i++;
16618            }
16619        }
16620    }
16621
16622    @Override
16623    public int stopUser(final int userId, final IStopUserCallback callback) {
16624        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16625                != PackageManager.PERMISSION_GRANTED) {
16626            String msg = "Permission Denial: switchUser() from pid="
16627                    + Binder.getCallingPid()
16628                    + ", uid=" + Binder.getCallingUid()
16629                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16630            Slog.w(TAG, msg);
16631            throw new SecurityException(msg);
16632        }
16633        if (userId <= 0) {
16634            throw new IllegalArgumentException("Can't stop primary user " + userId);
16635        }
16636        synchronized (this) {
16637            return stopUserLocked(userId, callback);
16638        }
16639    }
16640
16641    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16642        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
16643        if (mCurrentUserId == userId) {
16644            return ActivityManager.USER_OP_IS_CURRENT;
16645        }
16646
16647        final UserStartedState uss = mStartedUsers.get(userId);
16648        if (uss == null) {
16649            // User is not started, nothing to do...  but we do need to
16650            // callback if requested.
16651            if (callback != null) {
16652                mHandler.post(new Runnable() {
16653                    @Override
16654                    public void run() {
16655                        try {
16656                            callback.userStopped(userId);
16657                        } catch (RemoteException e) {
16658                        }
16659                    }
16660                });
16661            }
16662            return ActivityManager.USER_OP_SUCCESS;
16663        }
16664
16665        if (callback != null) {
16666            uss.mStopCallbacks.add(callback);
16667        }
16668
16669        if (uss.mState != UserStartedState.STATE_STOPPING
16670                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16671            uss.mState = UserStartedState.STATE_STOPPING;
16672            updateStartedUserArrayLocked();
16673
16674            long ident = Binder.clearCallingIdentity();
16675            try {
16676                // We are going to broadcast ACTION_USER_STOPPING and then
16677                // once that is done send a final ACTION_SHUTDOWN and then
16678                // stop the user.
16679                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16680                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16681                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16682                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16683                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16684                // This is the result receiver for the final shutdown broadcast.
16685                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16686                    @Override
16687                    public void performReceive(Intent intent, int resultCode, String data,
16688                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16689                        finishUserStop(uss);
16690                    }
16691                };
16692                // This is the result receiver for the initial stopping broadcast.
16693                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16694                    @Override
16695                    public void performReceive(Intent intent, int resultCode, String data,
16696                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16697                        // On to the next.
16698                        synchronized (ActivityManagerService.this) {
16699                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16700                                // Whoops, we are being started back up.  Abort, abort!
16701                                return;
16702                            }
16703                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16704                        }
16705                        broadcastIntentLocked(null, null, shutdownIntent,
16706                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16707                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16708                    }
16709                };
16710                // Kick things off.
16711                broadcastIntentLocked(null, null, stoppingIntent,
16712                        null, stoppingReceiver, 0, null, null,
16713                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16714                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16715            } finally {
16716                Binder.restoreCallingIdentity(ident);
16717            }
16718        }
16719
16720        return ActivityManager.USER_OP_SUCCESS;
16721    }
16722
16723    void finishUserStop(UserStartedState uss) {
16724        final int userId = uss.mHandle.getIdentifier();
16725        boolean stopped;
16726        ArrayList<IStopUserCallback> callbacks;
16727        synchronized (this) {
16728            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16729            if (mStartedUsers.get(userId) != uss) {
16730                stopped = false;
16731            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16732                stopped = false;
16733            } else {
16734                stopped = true;
16735                // User can no longer run.
16736                mStartedUsers.remove(userId);
16737                mUserLru.remove(Integer.valueOf(userId));
16738                updateStartedUserArrayLocked();
16739
16740                // Clean up all state and processes associated with the user.
16741                // Kill all the processes for the user.
16742                forceStopUserLocked(userId, "finish user");
16743            }
16744        }
16745
16746        for (int i=0; i<callbacks.size(); i++) {
16747            try {
16748                if (stopped) callbacks.get(i).userStopped(userId);
16749                else callbacks.get(i).userStopAborted(userId);
16750            } catch (RemoteException e) {
16751            }
16752        }
16753
16754        mStackSupervisor.removeUserLocked(userId);
16755    }
16756
16757    @Override
16758    public UserInfo getCurrentUser() {
16759        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16760                != PackageManager.PERMISSION_GRANTED) && (
16761                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16762                != PackageManager.PERMISSION_GRANTED)) {
16763            String msg = "Permission Denial: getCurrentUser() from pid="
16764                    + Binder.getCallingPid()
16765                    + ", uid=" + Binder.getCallingUid()
16766                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16767            Slog.w(TAG, msg);
16768            throw new SecurityException(msg);
16769        }
16770        synchronized (this) {
16771            return getUserManagerLocked().getUserInfo(mCurrentUserId);
16772        }
16773    }
16774
16775    int getCurrentUserIdLocked() {
16776        return mCurrentUserId;
16777    }
16778
16779    @Override
16780    public boolean isUserRunning(int userId, boolean orStopped) {
16781        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16782                != PackageManager.PERMISSION_GRANTED) {
16783            String msg = "Permission Denial: isUserRunning() from pid="
16784                    + Binder.getCallingPid()
16785                    + ", uid=" + Binder.getCallingUid()
16786                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16787            Slog.w(TAG, msg);
16788            throw new SecurityException(msg);
16789        }
16790        synchronized (this) {
16791            return isUserRunningLocked(userId, orStopped);
16792        }
16793    }
16794
16795    boolean isUserRunningLocked(int userId, boolean orStopped) {
16796        UserStartedState state = mStartedUsers.get(userId);
16797        if (state == null) {
16798            return false;
16799        }
16800        if (orStopped) {
16801            return true;
16802        }
16803        return state.mState != UserStartedState.STATE_STOPPING
16804                && state.mState != UserStartedState.STATE_SHUTDOWN;
16805    }
16806
16807    @Override
16808    public int[] getRunningUserIds() {
16809        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16810                != PackageManager.PERMISSION_GRANTED) {
16811            String msg = "Permission Denial: isUserRunning() from pid="
16812                    + Binder.getCallingPid()
16813                    + ", uid=" + Binder.getCallingUid()
16814                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16815            Slog.w(TAG, msg);
16816            throw new SecurityException(msg);
16817        }
16818        synchronized (this) {
16819            return mStartedUserArray;
16820        }
16821    }
16822
16823    private void updateStartedUserArrayLocked() {
16824        int num = 0;
16825        for (int i=0; i<mStartedUsers.size();  i++) {
16826            UserStartedState uss = mStartedUsers.valueAt(i);
16827            // This list does not include stopping users.
16828            if (uss.mState != UserStartedState.STATE_STOPPING
16829                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16830                num++;
16831            }
16832        }
16833        mStartedUserArray = new int[num];
16834        num = 0;
16835        for (int i=0; i<mStartedUsers.size();  i++) {
16836            UserStartedState uss = mStartedUsers.valueAt(i);
16837            if (uss.mState != UserStartedState.STATE_STOPPING
16838                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16839                mStartedUserArray[num] = mStartedUsers.keyAt(i);
16840                num++;
16841            }
16842        }
16843    }
16844
16845    @Override
16846    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
16847        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16848                != PackageManager.PERMISSION_GRANTED) {
16849            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
16850                    + Binder.getCallingPid()
16851                    + ", uid=" + Binder.getCallingUid()
16852                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16853            Slog.w(TAG, msg);
16854            throw new SecurityException(msg);
16855        }
16856
16857        mUserSwitchObservers.register(observer);
16858    }
16859
16860    @Override
16861    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
16862        mUserSwitchObservers.unregister(observer);
16863    }
16864
16865    private boolean userExists(int userId) {
16866        if (userId == 0) {
16867            return true;
16868        }
16869        UserManagerService ums = getUserManagerLocked();
16870        return ums != null ? (ums.getUserInfo(userId) != null) : false;
16871    }
16872
16873    int[] getUsersLocked() {
16874        UserManagerService ums = getUserManagerLocked();
16875        return ums != null ? ums.getUserIds() : new int[] { 0 };
16876    }
16877
16878    UserManagerService getUserManagerLocked() {
16879        if (mUserManager == null) {
16880            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
16881            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
16882        }
16883        return mUserManager;
16884    }
16885
16886    private int applyUserId(int uid, int userId) {
16887        return UserHandle.getUid(userId, uid);
16888    }
16889
16890    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
16891        if (info == null) return null;
16892        ApplicationInfo newInfo = new ApplicationInfo(info);
16893        newInfo.uid = applyUserId(info.uid, userId);
16894        newInfo.dataDir = USER_DATA_DIR + userId + "/"
16895                + info.packageName;
16896        return newInfo;
16897    }
16898
16899    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
16900        if (aInfo == null
16901                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
16902            return aInfo;
16903        }
16904
16905        ActivityInfo info = new ActivityInfo(aInfo);
16906        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
16907        return info;
16908    }
16909}
16910