ActivityManagerService.java revision 2fbd7541804f816171849413b095fcfc70e06c1e
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.content.pm.PackageManager.PERMISSION_GRANTED;
20import static com.android.internal.util.XmlUtils.readIntAttribute;
21import static com.android.internal.util.XmlUtils.readLongAttribute;
22import static com.android.internal.util.XmlUtils.writeIntAttribute;
23import static com.android.internal.util.XmlUtils.writeLongAttribute;
24import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
25import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
26import static org.xmlpull.v1.XmlPullParser.START_TAG;
27
28import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
29
30import android.app.AppOpsManager;
31import android.app.IActivityContainer;
32import android.app.IActivityContainerCallback;
33import android.appwidget.AppWidgetManager;
34import android.graphics.Rect;
35import android.os.BatteryStats;
36import android.util.ArrayMap;
37import com.android.internal.R;
38import com.android.internal.annotations.GuardedBy;
39import com.android.internal.app.IAppOpsService;
40import com.android.internal.app.ProcessMap;
41import com.android.internal.app.ProcessStats;
42import com.android.internal.os.BackgroundThread;
43import com.android.internal.os.BatteryStatsImpl;
44import com.android.internal.os.ProcessCpuTracker;
45import com.android.internal.os.TransferPipe;
46import com.android.internal.util.FastPrintWriter;
47import com.android.internal.util.FastXmlSerializer;
48import com.android.internal.util.MemInfoReader;
49import com.android.internal.util.Preconditions;
50import com.android.server.AppOpsService;
51import com.android.server.AttributeCache;
52import com.android.server.IntentResolver;
53import com.android.server.ServiceThread;
54import com.android.server.SystemService;
55import com.android.server.Watchdog;
56import com.android.server.am.ActivityStack.ActivityState;
57import com.android.server.firewall.IntentFirewall;
58import com.android.server.pm.UserManagerService;
59import com.android.server.wm.AppTransition;
60import com.android.server.wm.WindowManagerService;
61import com.google.android.collect.Lists;
62import com.google.android.collect.Maps;
63
64import dalvik.system.Zygote;
65
66import libcore.io.IoUtils;
67
68import org.xmlpull.v1.XmlPullParser;
69import org.xmlpull.v1.XmlPullParserException;
70import org.xmlpull.v1.XmlSerializer;
71
72import android.app.Activity;
73import android.app.ActivityManager;
74import android.app.ActivityManager.RunningTaskInfo;
75import android.app.ActivityManager.StackInfo;
76import android.app.ActivityManagerNative;
77import android.app.ActivityOptions;
78import android.app.ActivityThread;
79import android.app.AlertDialog;
80import android.app.AppGlobals;
81import android.app.ApplicationErrorReport;
82import android.app.Dialog;
83import android.app.IActivityController;
84import android.app.IApplicationThread;
85import android.app.IInstrumentationWatcher;
86import android.app.INotificationManager;
87import android.app.IProcessObserver;
88import android.app.IServiceConnection;
89import android.app.IStopUserCallback;
90import android.app.IThumbnailReceiver;
91import android.app.IUiAutomationConnection;
92import android.app.IUserSwitchObserver;
93import android.app.Instrumentation;
94import android.app.Notification;
95import android.app.NotificationManager;
96import android.app.PendingIntent;
97import android.app.backup.IBackupManager;
98import android.content.ActivityNotFoundException;
99import android.content.BroadcastReceiver;
100import android.content.ClipData;
101import android.content.ComponentCallbacks2;
102import android.content.ComponentName;
103import android.content.ContentProvider;
104import android.content.ContentResolver;
105import android.content.Context;
106import android.content.DialogInterface;
107import android.content.IContentProvider;
108import android.content.IIntentReceiver;
109import android.content.IIntentSender;
110import android.content.Intent;
111import android.content.IntentFilter;
112import android.content.IntentSender;
113import android.content.pm.ActivityInfo;
114import android.content.pm.ApplicationInfo;
115import android.content.pm.ConfigurationInfo;
116import android.content.pm.IPackageDataObserver;
117import android.content.pm.IPackageManager;
118import android.content.pm.InstrumentationInfo;
119import android.content.pm.PackageInfo;
120import android.content.pm.PackageManager;
121import android.content.pm.ParceledListSlice;
122import android.content.pm.UserInfo;
123import android.content.pm.PackageManager.NameNotFoundException;
124import android.content.pm.PathPermission;
125import android.content.pm.ProviderInfo;
126import android.content.pm.ResolveInfo;
127import android.content.pm.ServiceInfo;
128import android.content.res.CompatibilityInfo;
129import android.content.res.Configuration;
130import android.graphics.Bitmap;
131import android.net.Proxy;
132import android.net.ProxyProperties;
133import android.net.Uri;
134import android.os.Binder;
135import android.os.Build;
136import android.os.Bundle;
137import android.os.Debug;
138import android.os.DropBoxManager;
139import android.os.Environment;
140import android.os.FactoryTest;
141import android.os.FileObserver;
142import android.os.FileUtils;
143import android.os.Handler;
144import android.os.IBinder;
145import android.os.IPermissionController;
146import android.os.IRemoteCallback;
147import android.os.IUserManager;
148import android.os.Looper;
149import android.os.Message;
150import android.os.Parcel;
151import android.os.ParcelFileDescriptor;
152import android.os.Process;
153import android.os.RemoteCallbackList;
154import android.os.RemoteException;
155import android.os.SELinux;
156import android.os.ServiceManager;
157import android.os.StrictMode;
158import android.os.SystemClock;
159import android.os.SystemProperties;
160import android.os.UpdateLock;
161import android.os.UserHandle;
162import android.provider.Settings;
163import android.text.format.DateUtils;
164import android.text.format.Time;
165import android.util.AtomicFile;
166import android.util.EventLog;
167import android.util.Log;
168import android.util.Pair;
169import android.util.PrintWriterPrinter;
170import android.util.Slog;
171import android.util.SparseArray;
172import android.util.TimeUtils;
173import android.util.Xml;
174import android.view.Gravity;
175import android.view.LayoutInflater;
176import android.view.View;
177import android.view.WindowManager;
178
179import java.io.BufferedInputStream;
180import java.io.BufferedOutputStream;
181import java.io.DataInputStream;
182import java.io.DataOutputStream;
183import java.io.File;
184import java.io.FileDescriptor;
185import java.io.FileInputStream;
186import java.io.FileNotFoundException;
187import java.io.FileOutputStream;
188import java.io.IOException;
189import java.io.InputStreamReader;
190import java.io.PrintWriter;
191import java.io.StringWriter;
192import java.lang.ref.WeakReference;
193import java.util.ArrayList;
194import java.util.Arrays;
195import java.util.Collections;
196import java.util.Comparator;
197import java.util.HashMap;
198import java.util.HashSet;
199import java.util.Iterator;
200import java.util.List;
201import java.util.Locale;
202import java.util.Map;
203import java.util.Set;
204import java.util.concurrent.atomic.AtomicBoolean;
205import java.util.concurrent.atomic.AtomicLong;
206
207public final class ActivityManagerService extends ActivityManagerNative
208        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
209    private static final String USER_DATA_DIR = "/data/user/";
210    static final String TAG = "ActivityManager";
211    static final String TAG_MU = "ActivityManagerServiceMU";
212    static final boolean DEBUG = false;
213    static final boolean localLOGV = DEBUG;
214    static final boolean DEBUG_BACKUP = localLOGV || false;
215    static final boolean DEBUG_BROADCAST = localLOGV || false;
216    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
217    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
218    static final boolean DEBUG_CLEANUP = localLOGV || false;
219    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
220    static final boolean DEBUG_FOCUS = false;
221    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
222    static final boolean DEBUG_MU = localLOGV || false;
223    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
224    static final boolean DEBUG_LRU = localLOGV || false;
225    static final boolean DEBUG_PAUSE = localLOGV || false;
226    static final boolean DEBUG_POWER = localLOGV || false;
227    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
228    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
229    static final boolean DEBUG_PROCESSES = localLOGV || false;
230    static final boolean DEBUG_PROVIDER = localLOGV || false;
231    static final boolean DEBUG_RESULTS = localLOGV || false;
232    static final boolean DEBUG_SERVICE = localLOGV || false;
233    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
234    static final boolean DEBUG_STACK = localLOGV || false;
235    static final boolean DEBUG_SWITCH = localLOGV || false;
236    static final boolean DEBUG_TASKS = localLOGV || false;
237    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
238    static final boolean DEBUG_TRANSITION = localLOGV || false;
239    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
240    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
241    static final boolean DEBUG_VISBILITY = localLOGV || false;
242    static final boolean DEBUG_PSS = localLOGV || false;
243    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
244    static final boolean VALIDATE_TOKENS = false;
245    static final boolean SHOW_ACTIVITY_START_TIME = true;
246
247    // Control over CPU and battery monitoring.
248    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
249    static final boolean MONITOR_CPU_USAGE = true;
250    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
251    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
252    static final boolean MONITOR_THREAD_CPU_USAGE = false;
253
254    // The flags that are set for all calls we make to the package manager.
255    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
256
257    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
258
259    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
260
261    // Maximum number of recent tasks that we can remember.
262    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20;
263
264    // Amount of time after a call to stopAppSwitches() during which we will
265    // prevent further untrusted switches from happening.
266    static final long APP_SWITCH_DELAY_TIME = 5*1000;
267
268    // How long we wait for a launched process to attach to the activity manager
269    // before we decide it's never going to come up for real.
270    static final int PROC_START_TIMEOUT = 10*1000;
271
272    // How long we wait for a launched process to attach to the activity manager
273    // before we decide it's never going to come up for real, when the process was
274    // started with a wrapper for instrumentation (such as Valgrind) because it
275    // could take much longer than usual.
276    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
277
278    // How long to wait after going idle before forcing apps to GC.
279    static final int GC_TIMEOUT = 5*1000;
280
281    // The minimum amount of time between successive GC requests for a process.
282    static final int GC_MIN_INTERVAL = 60*1000;
283
284    // The minimum amount of time between successive PSS requests for a process.
285    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
286
287    // The minimum amount of time between successive PSS requests for a process
288    // when the request is due to the memory state being lowered.
289    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
290
291    // The rate at which we check for apps using excessive power -- 15 mins.
292    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
293
294    // The minimum sample duration we will allow before deciding we have
295    // enough data on wake locks to start killing things.
296    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
297
298    // The minimum sample duration we will allow before deciding we have
299    // enough data on CPU usage to start killing things.
300    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
301
302    // How long we allow a receiver to run before giving up on it.
303    static final int BROADCAST_FG_TIMEOUT = 10*1000;
304    static final int BROADCAST_BG_TIMEOUT = 60*1000;
305
306    // How long we wait until we timeout on key dispatching.
307    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
308
309    // How long we wait until we timeout on key dispatching during instrumentation.
310    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
311
312    // Amount of time we wait for observers to handle a user switch before
313    // giving up on them and unfreezing the screen.
314    static final int USER_SWITCH_TIMEOUT = 2*1000;
315
316    // Maximum number of users we allow to be running at a time.
317    static final int MAX_RUNNING_USERS = 3;
318
319    // How long to wait in getAssistContextExtras for the activity and foreground services
320    // to respond with the result.
321    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
322
323    // Maximum number of persisted Uri grants a package is allowed
324    static final int MAX_PERSISTED_URI_GRANTS = 128;
325
326    static final int MY_PID = Process.myPid();
327
328    static final String[] EMPTY_STRING_ARRAY = new String[0];
329
330    // How many bytes to write into the dropbox log before truncating
331    static final int DROPBOX_MAX_SIZE = 256 * 1024;
332
333    /** Run all ActivityStacks through this */
334    ActivityStackSupervisor mStackSupervisor;
335
336    public IntentFirewall mIntentFirewall;
337
338    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
339    // default actuion automatically.  Important for devices without direct input
340    // devices.
341    private boolean mShowDialogs = true;
342
343    /**
344     * Description of a request to start a new activity, which has been held
345     * due to app switches being disabled.
346     */
347    static class PendingActivityLaunch {
348        final ActivityRecord r;
349        final ActivityRecord sourceRecord;
350        final int startFlags;
351        final ActivityStack stack;
352
353        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
354                int _startFlags, ActivityStack _stack) {
355            r = _r;
356            sourceRecord = _sourceRecord;
357            startFlags = _startFlags;
358            stack = _stack;
359        }
360    }
361
362    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
363            = new ArrayList<PendingActivityLaunch>();
364
365    BroadcastQueue mFgBroadcastQueue;
366    BroadcastQueue mBgBroadcastQueue;
367    // Convenient for easy iteration over the queues. Foreground is first
368    // so that dispatch of foreground broadcasts gets precedence.
369    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
370
371    BroadcastQueue broadcastQueueForIntent(Intent intent) {
372        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
373        if (DEBUG_BACKGROUND_BROADCAST) {
374            Slog.i(TAG, "Broadcast intent " + intent + " on "
375                    + (isFg ? "foreground" : "background")
376                    + " queue");
377        }
378        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
379    }
380
381    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
382        for (BroadcastQueue queue : mBroadcastQueues) {
383            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
384            if (r != null) {
385                return r;
386            }
387        }
388        return null;
389    }
390
391    /**
392     * Activity we have told the window manager to have key focus.
393     */
394    ActivityRecord mFocusedActivity = null;
395
396    /**
397     * List of intents that were used to start the most recent tasks.
398     */
399    private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
400
401    public class PendingAssistExtras extends Binder implements Runnable {
402        public final ActivityRecord activity;
403        public boolean haveResult = false;
404        public Bundle result = null;
405        public PendingAssistExtras(ActivityRecord _activity) {
406            activity = _activity;
407        }
408        @Override
409        public void run() {
410            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
411            synchronized (this) {
412                haveResult = true;
413                notifyAll();
414            }
415        }
416    }
417
418    final ArrayList<PendingAssistExtras> mPendingAssistExtras
419            = new ArrayList<PendingAssistExtras>();
420
421    /**
422     * Process management.
423     */
424    final ProcessList mProcessList = new ProcessList();
425
426    /**
427     * All of the applications we currently have running organized by name.
428     * The keys are strings of the application package name (as
429     * returned by the package manager), and the keys are ApplicationRecord
430     * objects.
431     */
432    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
433
434    /**
435     * Tracking long-term execution of processes to look for abuse and other
436     * bad app behavior.
437     */
438    final ProcessStatsService mProcessStats;
439
440    /**
441     * The currently running isolated processes.
442     */
443    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
444
445    /**
446     * Counter for assigning isolated process uids, to avoid frequently reusing the
447     * same ones.
448     */
449    int mNextIsolatedProcessUid = 0;
450
451    /**
452     * The currently running heavy-weight process, if any.
453     */
454    ProcessRecord mHeavyWeightProcess = null;
455
456    /**
457     * The last time that various processes have crashed.
458     */
459    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
460
461    /**
462     * Information about a process that is currently marked as bad.
463     */
464    static final class BadProcessInfo {
465        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
466            this.time = time;
467            this.shortMsg = shortMsg;
468            this.longMsg = longMsg;
469            this.stack = stack;
470        }
471
472        final long time;
473        final String shortMsg;
474        final String longMsg;
475        final String stack;
476    }
477
478    /**
479     * Set of applications that we consider to be bad, and will reject
480     * incoming broadcasts from (which the user has no control over).
481     * Processes are added to this set when they have crashed twice within
482     * a minimum amount of time; they are removed from it when they are
483     * later restarted (hopefully due to some user action).  The value is the
484     * time it was added to the list.
485     */
486    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
487
488    /**
489     * All of the processes we currently have running organized by pid.
490     * The keys are the pid running the application.
491     *
492     * <p>NOTE: This object is protected by its own lock, NOT the global
493     * activity manager lock!
494     */
495    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
496
497    /**
498     * All of the processes that have been forced to be foreground.  The key
499     * is the pid of the caller who requested it (we hold a death
500     * link on it).
501     */
502    abstract class ForegroundToken implements IBinder.DeathRecipient {
503        int pid;
504        IBinder token;
505    }
506    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
507
508    /**
509     * List of records for processes that someone had tried to start before the
510     * system was ready.  We don't start them at that point, but ensure they
511     * are started by the time booting is complete.
512     */
513    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
514
515    /**
516     * List of persistent applications that are in the process
517     * of being started.
518     */
519    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
520
521    /**
522     * Processes that are being forcibly torn down.
523     */
524    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
525
526    /**
527     * List of running applications, sorted by recent usage.
528     * The first entry in the list is the least recently used.
529     */
530    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
531
532    /**
533     * Where in mLruProcesses that the processes hosting activities start.
534     */
535    int mLruProcessActivityStart = 0;
536
537    /**
538     * Where in mLruProcesses that the processes hosting services start.
539     * This is after (lower index) than mLruProcessesActivityStart.
540     */
541    int mLruProcessServiceStart = 0;
542
543    /**
544     * List of processes that should gc as soon as things are idle.
545     */
546    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
547
548    /**
549     * Processes we want to collect PSS data from.
550     */
551    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
552
553    /**
554     * Last time we requested PSS data of all processes.
555     */
556    long mLastFullPssTime = SystemClock.uptimeMillis();
557
558    /**
559     * This is the process holding what we currently consider to be
560     * the "home" activity.
561     */
562    ProcessRecord mHomeProcess;
563
564    /**
565     * This is the process holding the activity the user last visited that
566     * is in a different process from the one they are currently in.
567     */
568    ProcessRecord mPreviousProcess;
569
570    /**
571     * The time at which the previous process was last visible.
572     */
573    long mPreviousProcessVisibleTime;
574
575    /**
576     * Which uses have been started, so are allowed to run code.
577     */
578    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
579
580    /**
581     * LRU list of history of current users.  Most recently current is at the end.
582     */
583    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
584
585    /**
586     * Constant array of the users that are currently started.
587     */
588    int[] mStartedUserArray = new int[] { 0 };
589
590    /**
591     * Registered observers of the user switching mechanics.
592     */
593    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
594            = new RemoteCallbackList<IUserSwitchObserver>();
595
596    /**
597     * Currently active user switch.
598     */
599    Object mCurUserSwitchCallback;
600
601    /**
602     * Packages that the user has asked to have run in screen size
603     * compatibility mode instead of filling the screen.
604     */
605    final CompatModePackages mCompatModePackages;
606
607    /**
608     * Set of IntentSenderRecord objects that are currently active.
609     */
610    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
611            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
612
613    /**
614     * Fingerprints (hashCode()) of stack traces that we've
615     * already logged DropBox entries for.  Guarded by itself.  If
616     * something (rogue user app) forces this over
617     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
618     */
619    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
620    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
621
622    /**
623     * Strict Mode background batched logging state.
624     *
625     * The string buffer is guarded by itself, and its lock is also
626     * used to determine if another batched write is already
627     * in-flight.
628     */
629    private final StringBuilder mStrictModeBuffer = new StringBuilder();
630
631    /**
632     * Keeps track of all IIntentReceivers that have been registered for
633     * broadcasts.  Hash keys are the receiver IBinder, hash value is
634     * a ReceiverList.
635     */
636    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
637            new HashMap<IBinder, ReceiverList>();
638
639    /**
640     * Resolver for broadcast intents to registered receivers.
641     * Holds BroadcastFilter (subclass of IntentFilter).
642     */
643    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
644            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
645        @Override
646        protected boolean allowFilterResult(
647                BroadcastFilter filter, List<BroadcastFilter> dest) {
648            IBinder target = filter.receiverList.receiver.asBinder();
649            for (int i=dest.size()-1; i>=0; i--) {
650                if (dest.get(i).receiverList.receiver.asBinder() == target) {
651                    return false;
652                }
653            }
654            return true;
655        }
656
657        @Override
658        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
659            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
660                    || userId == filter.owningUserId) {
661                return super.newResult(filter, match, userId);
662            }
663            return null;
664        }
665
666        @Override
667        protected BroadcastFilter[] newArray(int size) {
668            return new BroadcastFilter[size];
669        }
670
671        @Override
672        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
673            return packageName.equals(filter.packageName);
674        }
675    };
676
677    /**
678     * State of all active sticky broadcasts per user.  Keys are the action of the
679     * sticky Intent, values are an ArrayList of all broadcasted intents with
680     * that action (which should usually be one).  The SparseArray is keyed
681     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
682     * for stickies that are sent to all users.
683     */
684    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
685            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
686
687    final ActiveServices mServices;
688
689    /**
690     * Backup/restore process management
691     */
692    String mBackupAppName = null;
693    BackupRecord mBackupTarget = null;
694
695    /**
696     * List of PendingThumbnailsRecord objects of clients who are still
697     * waiting to receive all of the thumbnails for a task.
698     */
699    final ArrayList<PendingThumbnailsRecord> mPendingThumbnails =
700            new ArrayList<PendingThumbnailsRecord>();
701
702    final ProviderMap mProviderMap;
703
704    /**
705     * List of content providers who have clients waiting for them.  The
706     * application is currently being launched and the provider will be
707     * removed from this list once it is published.
708     */
709    final ArrayList<ContentProviderRecord> mLaunchingProviders
710            = new ArrayList<ContentProviderRecord>();
711
712    /**
713     * File storing persisted {@link #mGrantedUriPermissions}.
714     */
715    private final AtomicFile mGrantFile;
716
717    /** XML constants used in {@link #mGrantFile} */
718    private static final String TAG_URI_GRANTS = "uri-grants";
719    private static final String TAG_URI_GRANT = "uri-grant";
720    private static final String ATTR_USER_HANDLE = "userHandle";
721    private static final String ATTR_SOURCE_PKG = "sourcePkg";
722    private static final String ATTR_TARGET_PKG = "targetPkg";
723    private static final String ATTR_URI = "uri";
724    private static final String ATTR_MODE_FLAGS = "modeFlags";
725    private static final String ATTR_CREATED_TIME = "createdTime";
726
727    /**
728     * Global set of specific {@link Uri} permissions that have been granted.
729     * This optimized lookup structure maps from {@link UriPermission#targetUid}
730     * to {@link UriPermission#uri} to {@link UriPermission}.
731     */
732    @GuardedBy("this")
733    private final SparseArray<ArrayMap<Uri, UriPermission>>
734            mGrantedUriPermissions = new SparseArray<ArrayMap<Uri, UriPermission>>();
735
736    CoreSettingsObserver mCoreSettingsObserver;
737
738    /**
739     * Thread-local storage used to carry caller permissions over through
740     * indirect content-provider access.
741     */
742    private class Identity {
743        public int pid;
744        public int uid;
745
746        Identity(int _pid, int _uid) {
747            pid = _pid;
748            uid = _uid;
749        }
750    }
751
752    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
753
754    /**
755     * All information we have collected about the runtime performance of
756     * any user id that can impact battery performance.
757     */
758    final BatteryStatsService mBatteryStatsService;
759
760    /**
761     * Information about component usage
762     */
763    final UsageStatsService mUsageStatsService;
764
765    /**
766     * Information about and control over application operations
767     */
768    final AppOpsService mAppOpsService;
769
770    /**
771     * Current configuration information.  HistoryRecord objects are given
772     * a reference to this object to indicate which configuration they are
773     * currently running in, so this object must be kept immutable.
774     */
775    Configuration mConfiguration = new Configuration();
776
777    /**
778     * Current sequencing integer of the configuration, for skipping old
779     * configurations.
780     */
781    int mConfigurationSeq = 0;
782
783    /**
784     * Hardware-reported OpenGLES version.
785     */
786    final int GL_ES_VERSION;
787
788    /**
789     * List of initialization arguments to pass to all processes when binding applications to them.
790     * For example, references to the commonly used services.
791     */
792    HashMap<String, IBinder> mAppBindArgs;
793
794    /**
795     * Temporary to avoid allocations.  Protected by main lock.
796     */
797    final StringBuilder mStringBuilder = new StringBuilder(256);
798
799    /**
800     * Used to control how we initialize the service.
801     */
802    boolean mStartRunning = false;
803    ComponentName mTopComponent;
804    String mTopAction;
805    String mTopData;
806    boolean mProcessesReady = false;
807    boolean mSystemReady = false;
808    boolean mBooting = false;
809    boolean mWaitingUpdate = false;
810    boolean mDidUpdate = false;
811    boolean mOnBattery = false;
812    boolean mLaunchWarningShown = false;
813
814    Context mContext;
815
816    int mFactoryTest;
817
818    boolean mCheckedForSetup;
819
820    /**
821     * The time at which we will allow normal application switches again,
822     * after a call to {@link #stopAppSwitches()}.
823     */
824    long mAppSwitchesAllowedTime;
825
826    /**
827     * This is set to true after the first switch after mAppSwitchesAllowedTime
828     * is set; any switches after that will clear the time.
829     */
830    boolean mDidAppSwitch;
831
832    /**
833     * Last time (in realtime) at which we checked for power usage.
834     */
835    long mLastPowerCheckRealtime;
836
837    /**
838     * Last time (in uptime) at which we checked for power usage.
839     */
840    long mLastPowerCheckUptime;
841
842    /**
843     * Set while we are wanting to sleep, to prevent any
844     * activities from being started/resumed.
845     */
846    boolean mSleeping = false;
847
848    /**
849     * State of external calls telling us if the device is asleep.
850     */
851    boolean mWentToSleep = false;
852
853    /**
854     * State of external call telling us if the lock screen is shown.
855     */
856    boolean mLockScreenShown = false;
857
858    /**
859     * Set if we are shutting down the system, similar to sleeping.
860     */
861    boolean mShuttingDown = false;
862
863    /**
864     * Current sequence id for oom_adj computation traversal.
865     */
866    int mAdjSeq = 0;
867
868    /**
869     * Current sequence id for process LRU updating.
870     */
871    int mLruSeq = 0;
872
873    /**
874     * Keep track of the non-cached/empty process we last found, to help
875     * determine how to distribute cached/empty processes next time.
876     */
877    int mNumNonCachedProcs = 0;
878
879    /**
880     * Keep track of the number of cached hidden procs, to balance oom adj
881     * distribution between those and empty procs.
882     */
883    int mNumCachedHiddenProcs = 0;
884
885    /**
886     * Keep track of the number of service processes we last found, to
887     * determine on the next iteration which should be B services.
888     */
889    int mNumServiceProcs = 0;
890    int mNewNumAServiceProcs = 0;
891    int mNewNumServiceProcs = 0;
892
893    /**
894     * Allow the current computed overall memory level of the system to go down?
895     * This is set to false when we are killing processes for reasons other than
896     * memory management, so that the now smaller process list will not be taken as
897     * an indication that memory is tighter.
898     */
899    boolean mAllowLowerMemLevel = false;
900
901    /**
902     * The last computed memory level, for holding when we are in a state that
903     * processes are going away for other reasons.
904     */
905    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
906
907    /**
908     * The last total number of process we have, to determine if changes actually look
909     * like a shrinking number of process due to lower RAM.
910     */
911    int mLastNumProcesses;
912
913    /**
914     * The uptime of the last time we performed idle maintenance.
915     */
916    long mLastIdleTime = SystemClock.uptimeMillis();
917
918    /**
919     * Total time spent with RAM that has been added in the past since the last idle time.
920     */
921    long mLowRamTimeSinceLastIdle = 0;
922
923    /**
924     * If RAM is currently low, when that horrible situation started.
925     */
926    long mLowRamStartTime = 0;
927
928    /**
929     * For reporting to battery stats the current top application.
930     */
931    private String mCurResumedPackage = null;
932    private int mCurResumedUid = -1;
933
934    /**
935     * For reporting to battery stats the apps currently running foreground
936     * service.  The ProcessMap is package/uid tuples; each of these contain
937     * an array of the currently foreground processes.
938     */
939    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
940            = new ProcessMap<ArrayList<ProcessRecord>>();
941
942    /**
943     * This is set if we had to do a delayed dexopt of an app before launching
944     * it, to increasing the ANR timeouts in that case.
945     */
946    boolean mDidDexOpt;
947
948    String mDebugApp = null;
949    boolean mWaitForDebugger = false;
950    boolean mDebugTransient = false;
951    String mOrigDebugApp = null;
952    boolean mOrigWaitForDebugger = false;
953    boolean mAlwaysFinishActivities = false;
954    IActivityController mController = null;
955    String mProfileApp = null;
956    ProcessRecord mProfileProc = null;
957    String mProfileFile;
958    ParcelFileDescriptor mProfileFd;
959    int mProfileType = 0;
960    boolean mAutoStopProfiler = false;
961    String mOpenGlTraceApp = null;
962
963    static class ProcessChangeItem {
964        static final int CHANGE_ACTIVITIES = 1<<0;
965        static final int CHANGE_IMPORTANCE= 1<<1;
966        int changes;
967        int uid;
968        int pid;
969        int importance;
970        boolean foregroundActivities;
971    }
972
973    final RemoteCallbackList<IProcessObserver> mProcessObservers
974            = new RemoteCallbackList<IProcessObserver>();
975    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
976
977    final ArrayList<ProcessChangeItem> mPendingProcessChanges
978            = new ArrayList<ProcessChangeItem>();
979    final ArrayList<ProcessChangeItem> mAvailProcessChanges
980            = new ArrayList<ProcessChangeItem>();
981
982    /**
983     * Runtime CPU use collection thread.  This object's lock is used to
984     * protect all related state.
985     */
986    final Thread mProcessCpuThread;
987
988    /**
989     * Used to collect process stats when showing not responding dialog.
990     * Protected by mProcessCpuThread.
991     */
992    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
993            MONITOR_THREAD_CPU_USAGE);
994    final AtomicLong mLastCpuTime = new AtomicLong(0);
995    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
996
997    long mLastWriteTime = 0;
998
999    /**
1000     * Used to retain an update lock when the foreground activity is in
1001     * immersive mode.
1002     */
1003    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1004
1005    /**
1006     * Set to true after the system has finished booting.
1007     */
1008    boolean mBooted = false;
1009
1010    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1011    int mProcessLimitOverride = -1;
1012
1013    WindowManagerService mWindowManager;
1014
1015    final ActivityThread mSystemThread;
1016
1017    int mCurrentUserId = 0;
1018    int[] mRelatedUserIds = new int[0]; // Accessed by ActivityStack
1019    private UserManagerService mUserManager;
1020
1021    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1022        final ProcessRecord mApp;
1023        final int mPid;
1024        final IApplicationThread mAppThread;
1025
1026        AppDeathRecipient(ProcessRecord app, int pid,
1027                IApplicationThread thread) {
1028            if (localLOGV) Slog.v(
1029                TAG, "New death recipient " + this
1030                + " for thread " + thread.asBinder());
1031            mApp = app;
1032            mPid = pid;
1033            mAppThread = thread;
1034        }
1035
1036        @Override
1037        public void binderDied() {
1038            if (localLOGV) Slog.v(
1039                TAG, "Death received in " + this
1040                + " for thread " + mAppThread.asBinder());
1041            synchronized(ActivityManagerService.this) {
1042                appDiedLocked(mApp, mPid, mAppThread);
1043            }
1044        }
1045    }
1046
1047    static final int SHOW_ERROR_MSG = 1;
1048    static final int SHOW_NOT_RESPONDING_MSG = 2;
1049    static final int SHOW_FACTORY_ERROR_MSG = 3;
1050    static final int UPDATE_CONFIGURATION_MSG = 4;
1051    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1052    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1053    static final int SERVICE_TIMEOUT_MSG = 12;
1054    static final int UPDATE_TIME_ZONE = 13;
1055    static final int SHOW_UID_ERROR_MSG = 14;
1056    static final int IM_FEELING_LUCKY_MSG = 15;
1057    static final int PROC_START_TIMEOUT_MSG = 20;
1058    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1059    static final int KILL_APPLICATION_MSG = 22;
1060    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1061    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1062    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1063    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1064    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1065    static final int CLEAR_DNS_CACHE_MSG = 28;
1066    static final int UPDATE_HTTP_PROXY_MSG = 29;
1067    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1068    static final int DISPATCH_PROCESSES_CHANGED = 31;
1069    static final int DISPATCH_PROCESS_DIED = 32;
1070    static final int REPORT_MEM_USAGE_MSG = 33;
1071    static final int REPORT_USER_SWITCH_MSG = 34;
1072    static final int CONTINUE_USER_SWITCH_MSG = 35;
1073    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1074    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1075    static final int PERSIST_URI_GRANTS_MSG = 38;
1076    static final int REQUEST_ALL_PSS_MSG = 39;
1077    static final int START_RELATED_USERS_MSG = 40;
1078    static final int UPDATE_TIME = 41;
1079
1080    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1081    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1082    static final int FIRST_COMPAT_MODE_MSG = 300;
1083    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1084
1085    AlertDialog mUidAlert;
1086    CompatModeDialog mCompatModeDialog;
1087    long mLastMemUsageReportTime = 0;
1088
1089    /**
1090     * Flag whether the current user is a "monkey", i.e. whether
1091     * the UI is driven by a UI automation tool.
1092     */
1093    private boolean mUserIsMonkey;
1094
1095    final ServiceThread mHandlerThread;
1096    final MainHandler mHandler;
1097
1098    final class MainHandler extends Handler {
1099        public MainHandler(Looper looper) {
1100            super(looper, null, true);
1101        }
1102
1103        @Override
1104        public void handleMessage(Message msg) {
1105            switch (msg.what) {
1106            case SHOW_ERROR_MSG: {
1107                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1108                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1109                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1110                synchronized (ActivityManagerService.this) {
1111                    ProcessRecord proc = (ProcessRecord)data.get("app");
1112                    AppErrorResult res = (AppErrorResult) data.get("result");
1113                    if (proc != null && proc.crashDialog != null) {
1114                        Slog.e(TAG, "App already has crash dialog: " + proc);
1115                        if (res != null) {
1116                            res.set(0);
1117                        }
1118                        return;
1119                    }
1120                    if (!showBackground && UserHandle.getAppId(proc.uid)
1121                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1122                            && proc.pid != MY_PID) {
1123                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1124                        if (res != null) {
1125                            res.set(0);
1126                        }
1127                        return;
1128                    }
1129                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1130                        Dialog d = new AppErrorDialog(mContext,
1131                                ActivityManagerService.this, res, proc);
1132                        d.show();
1133                        proc.crashDialog = d;
1134                    } else {
1135                        // The device is asleep, so just pretend that the user
1136                        // saw a crash dialog and hit "force quit".
1137                        if (res != null) {
1138                            res.set(0);
1139                        }
1140                    }
1141                }
1142
1143                ensureBootCompleted();
1144            } break;
1145            case SHOW_NOT_RESPONDING_MSG: {
1146                synchronized (ActivityManagerService.this) {
1147                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1148                    ProcessRecord proc = (ProcessRecord)data.get("app");
1149                    if (proc != null && proc.anrDialog != null) {
1150                        Slog.e(TAG, "App already has anr dialog: " + proc);
1151                        return;
1152                    }
1153
1154                    Intent intent = new Intent("android.intent.action.ANR");
1155                    if (!mProcessesReady) {
1156                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1157                                | Intent.FLAG_RECEIVER_FOREGROUND);
1158                    }
1159                    broadcastIntentLocked(null, null, intent,
1160                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1161                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1162
1163                    if (mShowDialogs) {
1164                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1165                                mContext, proc, (ActivityRecord)data.get("activity"),
1166                                msg.arg1 != 0);
1167                        d.show();
1168                        proc.anrDialog = d;
1169                    } else {
1170                        // Just kill the app if there is no dialog to be shown.
1171                        killAppAtUsersRequest(proc, null);
1172                    }
1173                }
1174
1175                ensureBootCompleted();
1176            } break;
1177            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1178                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1179                synchronized (ActivityManagerService.this) {
1180                    ProcessRecord proc = (ProcessRecord) data.get("app");
1181                    if (proc == null) {
1182                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1183                        break;
1184                    }
1185                    if (proc.crashDialog != null) {
1186                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1187                        return;
1188                    }
1189                    AppErrorResult res = (AppErrorResult) data.get("result");
1190                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1191                        Dialog d = new StrictModeViolationDialog(mContext,
1192                                ActivityManagerService.this, res, proc);
1193                        d.show();
1194                        proc.crashDialog = d;
1195                    } else {
1196                        // The device is asleep, so just pretend that the user
1197                        // saw a crash dialog and hit "force quit".
1198                        res.set(0);
1199                    }
1200                }
1201                ensureBootCompleted();
1202            } break;
1203            case SHOW_FACTORY_ERROR_MSG: {
1204                Dialog d = new FactoryErrorDialog(
1205                    mContext, msg.getData().getCharSequence("msg"));
1206                d.show();
1207                ensureBootCompleted();
1208            } break;
1209            case UPDATE_CONFIGURATION_MSG: {
1210                final ContentResolver resolver = mContext.getContentResolver();
1211                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1212            } break;
1213            case GC_BACKGROUND_PROCESSES_MSG: {
1214                synchronized (ActivityManagerService.this) {
1215                    performAppGcsIfAppropriateLocked();
1216                }
1217            } break;
1218            case WAIT_FOR_DEBUGGER_MSG: {
1219                synchronized (ActivityManagerService.this) {
1220                    ProcessRecord app = (ProcessRecord)msg.obj;
1221                    if (msg.arg1 != 0) {
1222                        if (!app.waitedForDebugger) {
1223                            Dialog d = new AppWaitingForDebuggerDialog(
1224                                    ActivityManagerService.this,
1225                                    mContext, app);
1226                            app.waitDialog = d;
1227                            app.waitedForDebugger = true;
1228                            d.show();
1229                        }
1230                    } else {
1231                        if (app.waitDialog != null) {
1232                            app.waitDialog.dismiss();
1233                            app.waitDialog = null;
1234                        }
1235                    }
1236                }
1237            } break;
1238            case SERVICE_TIMEOUT_MSG: {
1239                if (mDidDexOpt) {
1240                    mDidDexOpt = false;
1241                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1242                    nmsg.obj = msg.obj;
1243                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1244                    return;
1245                }
1246                mServices.serviceTimeout((ProcessRecord)msg.obj);
1247            } break;
1248            case UPDATE_TIME_ZONE: {
1249                synchronized (ActivityManagerService.this) {
1250                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1251                        ProcessRecord r = mLruProcesses.get(i);
1252                        if (r.thread != null) {
1253                            try {
1254                                r.thread.updateTimeZone();
1255                            } catch (RemoteException ex) {
1256                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1257                            }
1258                        }
1259                    }
1260                }
1261            } break;
1262            case CLEAR_DNS_CACHE_MSG: {
1263                synchronized (ActivityManagerService.this) {
1264                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1265                        ProcessRecord r = mLruProcesses.get(i);
1266                        if (r.thread != null) {
1267                            try {
1268                                r.thread.clearDnsCache();
1269                            } catch (RemoteException ex) {
1270                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1271                            }
1272                        }
1273                    }
1274                }
1275            } break;
1276            case UPDATE_HTTP_PROXY_MSG: {
1277                ProxyProperties proxy = (ProxyProperties)msg.obj;
1278                String host = "";
1279                String port = "";
1280                String exclList = "";
1281                String pacFileUrl = null;
1282                if (proxy != null) {
1283                    host = proxy.getHost();
1284                    port = Integer.toString(proxy.getPort());
1285                    exclList = proxy.getExclusionList();
1286                    pacFileUrl = proxy.getPacFileUrl();
1287                }
1288                synchronized (ActivityManagerService.this) {
1289                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1290                        ProcessRecord r = mLruProcesses.get(i);
1291                        if (r.thread != null) {
1292                            try {
1293                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1294                            } catch (RemoteException ex) {
1295                                Slog.w(TAG, "Failed to update http proxy for: " +
1296                                        r.info.processName);
1297                            }
1298                        }
1299                    }
1300                }
1301            } break;
1302            case SHOW_UID_ERROR_MSG: {
1303                String title = "System UIDs Inconsistent";
1304                String text = "UIDs on the system are inconsistent, you need to wipe your"
1305                        + " data partition or your device will be unstable.";
1306                Log.e(TAG, title + ": " + text);
1307                if (mShowDialogs) {
1308                    // XXX This is a temporary dialog, no need to localize.
1309                    AlertDialog d = new BaseErrorDialog(mContext);
1310                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1311                    d.setCancelable(false);
1312                    d.setTitle(title);
1313                    d.setMessage(text);
1314                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1315                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1316                    mUidAlert = d;
1317                    d.show();
1318                }
1319            } break;
1320            case IM_FEELING_LUCKY_MSG: {
1321                if (mUidAlert != null) {
1322                    mUidAlert.dismiss();
1323                    mUidAlert = null;
1324                }
1325            } break;
1326            case PROC_START_TIMEOUT_MSG: {
1327                if (mDidDexOpt) {
1328                    mDidDexOpt = false;
1329                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1330                    nmsg.obj = msg.obj;
1331                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1332                    return;
1333                }
1334                ProcessRecord app = (ProcessRecord)msg.obj;
1335                synchronized (ActivityManagerService.this) {
1336                    processStartTimedOutLocked(app);
1337                }
1338            } break;
1339            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1340                synchronized (ActivityManagerService.this) {
1341                    doPendingActivityLaunchesLocked(true);
1342                }
1343            } break;
1344            case KILL_APPLICATION_MSG: {
1345                synchronized (ActivityManagerService.this) {
1346                    int appid = msg.arg1;
1347                    boolean restart = (msg.arg2 == 1);
1348                    Bundle bundle = (Bundle)msg.obj;
1349                    String pkg = bundle.getString("pkg");
1350                    String reason = bundle.getString("reason");
1351                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1352                            false, UserHandle.USER_ALL, reason);
1353                }
1354            } break;
1355            case FINALIZE_PENDING_INTENT_MSG: {
1356                ((PendingIntentRecord)msg.obj).completeFinalize();
1357            } break;
1358            case POST_HEAVY_NOTIFICATION_MSG: {
1359                INotificationManager inm = NotificationManager.getService();
1360                if (inm == null) {
1361                    return;
1362                }
1363
1364                ActivityRecord root = (ActivityRecord)msg.obj;
1365                ProcessRecord process = root.app;
1366                if (process == null) {
1367                    return;
1368                }
1369
1370                try {
1371                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1372                    String text = mContext.getString(R.string.heavy_weight_notification,
1373                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1374                    Notification notification = new Notification();
1375                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1376                    notification.when = 0;
1377                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1378                    notification.tickerText = text;
1379                    notification.defaults = 0; // please be quiet
1380                    notification.sound = null;
1381                    notification.vibrate = null;
1382                    notification.setLatestEventInfo(context, text,
1383                            mContext.getText(R.string.heavy_weight_notification_detail),
1384                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1385                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1386                                    new UserHandle(root.userId)));
1387
1388                    try {
1389                        int[] outId = new int[1];
1390                        inm.enqueueNotificationWithTag("android", "android", null,
1391                                R.string.heavy_weight_notification,
1392                                notification, outId, root.userId);
1393                    } catch (RuntimeException e) {
1394                        Slog.w(ActivityManagerService.TAG,
1395                                "Error showing notification for heavy-weight app", e);
1396                    } catch (RemoteException e) {
1397                    }
1398                } catch (NameNotFoundException e) {
1399                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1400                }
1401            } break;
1402            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1403                INotificationManager inm = NotificationManager.getService();
1404                if (inm == null) {
1405                    return;
1406                }
1407                try {
1408                    inm.cancelNotificationWithTag("android", null,
1409                            R.string.heavy_weight_notification,  msg.arg1);
1410                } catch (RuntimeException e) {
1411                    Slog.w(ActivityManagerService.TAG,
1412                            "Error canceling notification for service", e);
1413                } catch (RemoteException e) {
1414                }
1415            } break;
1416            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1417                synchronized (ActivityManagerService.this) {
1418                    checkExcessivePowerUsageLocked(true);
1419                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1420                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1421                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1422                }
1423            } break;
1424            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1425                synchronized (ActivityManagerService.this) {
1426                    ActivityRecord ar = (ActivityRecord)msg.obj;
1427                    if (mCompatModeDialog != null) {
1428                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1429                                ar.info.applicationInfo.packageName)) {
1430                            return;
1431                        }
1432                        mCompatModeDialog.dismiss();
1433                        mCompatModeDialog = null;
1434                    }
1435                    if (ar != null && false) {
1436                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1437                                ar.packageName)) {
1438                            int mode = mCompatModePackages.computeCompatModeLocked(
1439                                    ar.info.applicationInfo);
1440                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1441                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1442                                mCompatModeDialog = new CompatModeDialog(
1443                                        ActivityManagerService.this, mContext,
1444                                        ar.info.applicationInfo);
1445                                mCompatModeDialog.show();
1446                            }
1447                        }
1448                    }
1449                }
1450                break;
1451            }
1452            case DISPATCH_PROCESSES_CHANGED: {
1453                dispatchProcessesChanged();
1454                break;
1455            }
1456            case DISPATCH_PROCESS_DIED: {
1457                final int pid = msg.arg1;
1458                final int uid = msg.arg2;
1459                dispatchProcessDied(pid, uid);
1460                break;
1461            }
1462            case REPORT_MEM_USAGE_MSG: {
1463                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1464                Thread thread = new Thread() {
1465                    @Override public void run() {
1466                        final SparseArray<ProcessMemInfo> infoMap
1467                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1468                        for (int i=0, N=memInfos.size(); i<N; i++) {
1469                            ProcessMemInfo mi = memInfos.get(i);
1470                            infoMap.put(mi.pid, mi);
1471                        }
1472                        updateCpuStatsNow();
1473                        synchronized (mProcessCpuThread) {
1474                            final int N = mProcessCpuTracker.countStats();
1475                            for (int i=0; i<N; i++) {
1476                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1477                                if (st.vsize > 0) {
1478                                    long pss = Debug.getPss(st.pid, null);
1479                                    if (pss > 0) {
1480                                        if (infoMap.indexOfKey(st.pid) < 0) {
1481                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1482                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1483                                            mi.pss = pss;
1484                                            memInfos.add(mi);
1485                                        }
1486                                    }
1487                                }
1488                            }
1489                        }
1490
1491                        long totalPss = 0;
1492                        for (int i=0, N=memInfos.size(); i<N; i++) {
1493                            ProcessMemInfo mi = memInfos.get(i);
1494                            if (mi.pss == 0) {
1495                                mi.pss = Debug.getPss(mi.pid, null);
1496                            }
1497                            totalPss += mi.pss;
1498                        }
1499                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1500                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1501                                if (lhs.oomAdj != rhs.oomAdj) {
1502                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1503                                }
1504                                if (lhs.pss != rhs.pss) {
1505                                    return lhs.pss < rhs.pss ? 1 : -1;
1506                                }
1507                                return 0;
1508                            }
1509                        });
1510
1511                        StringBuilder tag = new StringBuilder(128);
1512                        StringBuilder stack = new StringBuilder(128);
1513                        tag.append("Low on memory -- ");
1514                        appendMemBucket(tag, totalPss, "total", false);
1515                        appendMemBucket(stack, totalPss, "total", true);
1516
1517                        StringBuilder logBuilder = new StringBuilder(1024);
1518                        logBuilder.append("Low on memory:\n");
1519
1520                        boolean firstLine = true;
1521                        int lastOomAdj = Integer.MIN_VALUE;
1522                        for (int i=0, N=memInfos.size(); i<N; i++) {
1523                            ProcessMemInfo mi = memInfos.get(i);
1524
1525                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1526                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1527                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1528                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1529                                if (lastOomAdj != mi.oomAdj) {
1530                                    lastOomAdj = mi.oomAdj;
1531                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1532                                        tag.append(" / ");
1533                                    }
1534                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1535                                        if (firstLine) {
1536                                            stack.append(":");
1537                                            firstLine = false;
1538                                        }
1539                                        stack.append("\n\t at ");
1540                                    } else {
1541                                        stack.append("$");
1542                                    }
1543                                } else {
1544                                    tag.append(" ");
1545                                    stack.append("$");
1546                                }
1547                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1548                                    appendMemBucket(tag, mi.pss, mi.name, false);
1549                                }
1550                                appendMemBucket(stack, mi.pss, mi.name, true);
1551                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1552                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1553                                    stack.append("(");
1554                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1555                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1556                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1557                                            stack.append(":");
1558                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1559                                        }
1560                                    }
1561                                    stack.append(")");
1562                                }
1563                            }
1564
1565                            logBuilder.append("  ");
1566                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1567                            logBuilder.append(' ');
1568                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1569                            logBuilder.append(' ');
1570                            ProcessList.appendRamKb(logBuilder, mi.pss);
1571                            logBuilder.append(" kB: ");
1572                            logBuilder.append(mi.name);
1573                            logBuilder.append(" (");
1574                            logBuilder.append(mi.pid);
1575                            logBuilder.append(") ");
1576                            logBuilder.append(mi.adjType);
1577                            logBuilder.append('\n');
1578                            if (mi.adjReason != null) {
1579                                logBuilder.append("                      ");
1580                                logBuilder.append(mi.adjReason);
1581                                logBuilder.append('\n');
1582                            }
1583                        }
1584
1585                        logBuilder.append("           ");
1586                        ProcessList.appendRamKb(logBuilder, totalPss);
1587                        logBuilder.append(" kB: TOTAL\n");
1588
1589                        long[] infos = new long[Debug.MEMINFO_COUNT];
1590                        Debug.getMemInfo(infos);
1591                        logBuilder.append("  MemInfo: ");
1592                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1593                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1594                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1595                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1596                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1597                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1598                            logBuilder.append("  ZRAM: ");
1599                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1600                            logBuilder.append(" kB RAM, ");
1601                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1602                            logBuilder.append(" kB swap total, ");
1603                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1604                            logBuilder.append(" kB swap free\n");
1605                        }
1606                        Slog.i(TAG, logBuilder.toString());
1607
1608                        StringBuilder dropBuilder = new StringBuilder(1024);
1609                        /*
1610                        StringWriter oomSw = new StringWriter();
1611                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1612                        StringWriter catSw = new StringWriter();
1613                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1614                        String[] emptyArgs = new String[] { };
1615                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1616                        oomPw.flush();
1617                        String oomString = oomSw.toString();
1618                        */
1619                        dropBuilder.append(stack);
1620                        dropBuilder.append('\n');
1621                        dropBuilder.append('\n');
1622                        dropBuilder.append(logBuilder);
1623                        dropBuilder.append('\n');
1624                        /*
1625                        dropBuilder.append(oomString);
1626                        dropBuilder.append('\n');
1627                        */
1628                        StringWriter catSw = new StringWriter();
1629                        synchronized (ActivityManagerService.this) {
1630                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1631                            String[] emptyArgs = new String[] { };
1632                            catPw.println();
1633                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1634                            catPw.println();
1635                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1636                                    false, false, null);
1637                            catPw.println();
1638                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1639                            catPw.flush();
1640                        }
1641                        dropBuilder.append(catSw.toString());
1642                        addErrorToDropBox("lowmem", null, "system_server", null,
1643                                null, tag.toString(), dropBuilder.toString(), null, null);
1644                        //Slog.i(TAG, "Sent to dropbox:");
1645                        //Slog.i(TAG, dropBuilder.toString());
1646                        synchronized (ActivityManagerService.this) {
1647                            long now = SystemClock.uptimeMillis();
1648                            if (mLastMemUsageReportTime < now) {
1649                                mLastMemUsageReportTime = now;
1650                            }
1651                        }
1652                    }
1653                };
1654                thread.start();
1655                break;
1656            }
1657            case REPORT_USER_SWITCH_MSG: {
1658                dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1659                break;
1660            }
1661            case CONTINUE_USER_SWITCH_MSG: {
1662                continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1663                break;
1664            }
1665            case USER_SWITCH_TIMEOUT_MSG: {
1666                timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1667                break;
1668            }
1669            case IMMERSIVE_MODE_LOCK_MSG: {
1670                final boolean nextState = (msg.arg1 != 0);
1671                if (mUpdateLock.isHeld() != nextState) {
1672                    if (DEBUG_IMMERSIVE) {
1673                        final ActivityRecord r = (ActivityRecord) msg.obj;
1674                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1675                    }
1676                    if (nextState) {
1677                        mUpdateLock.acquire();
1678                    } else {
1679                        mUpdateLock.release();
1680                    }
1681                }
1682                break;
1683            }
1684            case PERSIST_URI_GRANTS_MSG: {
1685                writeGrantedUriPermissions();
1686                break;
1687            }
1688            case REQUEST_ALL_PSS_MSG: {
1689                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1690                break;
1691            }
1692            case START_RELATED_USERS_MSG: {
1693                synchronized (ActivityManagerService.this) {
1694                    startRelatedUsersLocked();
1695                }
1696                break;
1697            }
1698            case UPDATE_TIME: {
1699                synchronized (ActivityManagerService.this) {
1700                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1701                        ProcessRecord r = mLruProcesses.get(i);
1702                        if (r.thread != null) {
1703                            try {
1704                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1705                            } catch (RemoteException ex) {
1706                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1707                            }
1708                        }
1709                    }
1710                }
1711                break;
1712            }
1713            }
1714        }
1715    };
1716
1717    static final int COLLECT_PSS_BG_MSG = 1;
1718
1719    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1720        @Override
1721        public void handleMessage(Message msg) {
1722            switch (msg.what) {
1723            case COLLECT_PSS_BG_MSG: {
1724                int i=0, num=0;
1725                long start = SystemClock.uptimeMillis();
1726                long[] tmp = new long[1];
1727                do {
1728                    ProcessRecord proc;
1729                    int procState;
1730                    int pid;
1731                    synchronized (ActivityManagerService.this) {
1732                        if (i >= mPendingPssProcesses.size()) {
1733                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1734                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1735                            mPendingPssProcesses.clear();
1736                            return;
1737                        }
1738                        proc = mPendingPssProcesses.get(i);
1739                        procState = proc.pssProcState;
1740                        if (proc.thread != null && procState == proc.setProcState) {
1741                            pid = proc.pid;
1742                        } else {
1743                            proc = null;
1744                            pid = 0;
1745                        }
1746                        i++;
1747                    }
1748                    if (proc != null) {
1749                        long pss = Debug.getPss(pid, tmp);
1750                        synchronized (ActivityManagerService.this) {
1751                            if (proc.thread != null && proc.setProcState == procState
1752                                    && proc.pid == pid) {
1753                                num++;
1754                                proc.lastPssTime = SystemClock.uptimeMillis();
1755                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1756                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1757                                        + ": " + pss + " lastPss=" + proc.lastPss
1758                                        + " state=" + ProcessList.makeProcStateString(procState));
1759                                if (proc.initialIdlePss == 0) {
1760                                    proc.initialIdlePss = pss;
1761                                }
1762                                proc.lastPss = pss;
1763                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1764                                    proc.lastCachedPss = pss;
1765                                }
1766                            }
1767                        }
1768                    }
1769                } while (true);
1770            }
1771            }
1772        }
1773    };
1774
1775    public void setSystemProcess() {
1776        try {
1777            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1778            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1779            ServiceManager.addService("meminfo", new MemBinder(this));
1780            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1781            ServiceManager.addService("dbinfo", new DbBinder(this));
1782            if (MONITOR_CPU_USAGE) {
1783                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1784            }
1785            ServiceManager.addService("permission", new PermissionController(this));
1786
1787            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1788                    "android", STOCK_PM_FLAGS);
1789            mSystemThread.installSystemApplicationInfo(info);
1790
1791            synchronized (this) {
1792                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
1793                app.persistent = true;
1794                app.pid = MY_PID;
1795                app.maxAdj = ProcessList.SYSTEM_ADJ;
1796                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1797                mProcessNames.put(app.processName, app.uid, app);
1798                synchronized (mPidsSelfLocked) {
1799                    mPidsSelfLocked.put(app.pid, app);
1800                }
1801                updateLruProcessLocked(app, false, null);
1802                updateOomAdjLocked();
1803            }
1804        } catch (PackageManager.NameNotFoundException e) {
1805            throw new RuntimeException(
1806                    "Unable to find android system package", e);
1807        }
1808    }
1809
1810    public void setWindowManager(WindowManagerService wm) {
1811        mWindowManager = wm;
1812        mStackSupervisor.setWindowManager(wm);
1813    }
1814
1815    public void startObservingNativeCrashes() {
1816        final NativeCrashListener ncl = new NativeCrashListener(this);
1817        ncl.start();
1818    }
1819
1820    public IAppOpsService getAppOpsService() {
1821        return mAppOpsService;
1822    }
1823
1824    static class MemBinder extends Binder {
1825        ActivityManagerService mActivityManagerService;
1826        MemBinder(ActivityManagerService activityManagerService) {
1827            mActivityManagerService = activityManagerService;
1828        }
1829
1830        @Override
1831        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1832            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1833                    != PackageManager.PERMISSION_GRANTED) {
1834                pw.println("Permission Denial: can't dump meminfo from from pid="
1835                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1836                        + " without permission " + android.Manifest.permission.DUMP);
1837                return;
1838            }
1839
1840            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1841        }
1842    }
1843
1844    static class GraphicsBinder extends Binder {
1845        ActivityManagerService mActivityManagerService;
1846        GraphicsBinder(ActivityManagerService activityManagerService) {
1847            mActivityManagerService = activityManagerService;
1848        }
1849
1850        @Override
1851        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1852            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1853                    != PackageManager.PERMISSION_GRANTED) {
1854                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1855                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1856                        + " without permission " + android.Manifest.permission.DUMP);
1857                return;
1858            }
1859
1860            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1861        }
1862    }
1863
1864    static class DbBinder extends Binder {
1865        ActivityManagerService mActivityManagerService;
1866        DbBinder(ActivityManagerService activityManagerService) {
1867            mActivityManagerService = activityManagerService;
1868        }
1869
1870        @Override
1871        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1872            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1873                    != PackageManager.PERMISSION_GRANTED) {
1874                pw.println("Permission Denial: can't dump dbinfo from from pid="
1875                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1876                        + " without permission " + android.Manifest.permission.DUMP);
1877                return;
1878            }
1879
1880            mActivityManagerService.dumpDbInfo(fd, pw, args);
1881        }
1882    }
1883
1884    static class CpuBinder extends Binder {
1885        ActivityManagerService mActivityManagerService;
1886        CpuBinder(ActivityManagerService activityManagerService) {
1887            mActivityManagerService = activityManagerService;
1888        }
1889
1890        @Override
1891        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1892            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1893                    != PackageManager.PERMISSION_GRANTED) {
1894                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1895                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1896                        + " without permission " + android.Manifest.permission.DUMP);
1897                return;
1898            }
1899
1900            synchronized (mActivityManagerService.mProcessCpuThread) {
1901                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
1902                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
1903                        SystemClock.uptimeMillis()));
1904            }
1905        }
1906    }
1907
1908    public static final class Lifecycle extends SystemService {
1909        private final ActivityManagerService mService;
1910
1911        public Lifecycle(Context context) {
1912            super(context);
1913            mService = new ActivityManagerService(context);
1914        }
1915
1916        @Override
1917        public void onStart() {
1918            mService.start();
1919        }
1920
1921        public ActivityManagerService getService() {
1922            return mService;
1923        }
1924    }
1925
1926    // Note: This method is invoked on the main thread but may need to attach various
1927    // handlers to other threads.  So take care to be explicit about the looper.
1928    public ActivityManagerService(Context systemContext) {
1929        mContext = systemContext;
1930        mFactoryTest = FactoryTest.getMode();
1931        mSystemThread = ActivityThread.currentActivityThread();
1932
1933        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1934
1935        mHandlerThread = new ServiceThread(TAG,
1936                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
1937        mHandlerThread.start();
1938        mHandler = new MainHandler(mHandlerThread.getLooper());
1939
1940        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
1941                "foreground", BROADCAST_FG_TIMEOUT, false);
1942        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
1943                "background", BROADCAST_BG_TIMEOUT, true);
1944        mBroadcastQueues[0] = mFgBroadcastQueue;
1945        mBroadcastQueues[1] = mBgBroadcastQueue;
1946
1947        mServices = new ActiveServices(this);
1948        mProviderMap = new ProviderMap(this);
1949
1950        // TODO: Move creation of battery stats service outside of activity manager service.
1951        File dataDir = Environment.getDataDirectory();
1952        File systemDir = new File(dataDir, "system");
1953        systemDir.mkdirs();
1954        mBatteryStatsService = new BatteryStatsService(new File(
1955                systemDir, "batterystats.bin").toString(), mHandler);
1956        mBatteryStatsService.getActiveStatistics().readLocked();
1957        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1958        mOnBattery = DEBUG_POWER ? true
1959                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1960        mBatteryStatsService.getActiveStatistics().setCallback(this);
1961
1962        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
1963
1964        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
1965        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
1966
1967        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
1968
1969        // User 0 is the first and only user that runs at boot.
1970        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
1971        mUserLru.add(Integer.valueOf(0));
1972        updateStartedUserArrayLocked();
1973
1974        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1975            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1976
1977        mConfiguration.setToDefaults();
1978        mConfiguration.setLocale(Locale.getDefault());
1979
1980        mConfigurationSeq = mConfiguration.seq = 1;
1981        mProcessCpuTracker.init();
1982
1983        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
1984        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
1985        mStackSupervisor = new ActivityStackSupervisor(this);
1986
1987        mProcessCpuThread = new Thread("CpuTracker") {
1988            @Override
1989            public void run() {
1990                while (true) {
1991                    try {
1992                        try {
1993                            synchronized(this) {
1994                                final long now = SystemClock.uptimeMillis();
1995                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1996                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1997                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1998                                //        + ", write delay=" + nextWriteDelay);
1999                                if (nextWriteDelay < nextCpuDelay) {
2000                                    nextCpuDelay = nextWriteDelay;
2001                                }
2002                                if (nextCpuDelay > 0) {
2003                                    mProcessCpuMutexFree.set(true);
2004                                    this.wait(nextCpuDelay);
2005                                }
2006                            }
2007                        } catch (InterruptedException e) {
2008                        }
2009                        updateCpuStatsNow();
2010                    } catch (Exception e) {
2011                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2012                    }
2013                }
2014            }
2015        };
2016
2017        Watchdog.getInstance().addMonitor(this);
2018        Watchdog.getInstance().addThread(mHandler);
2019    }
2020
2021    private void start() {
2022        mProcessCpuThread.start();
2023
2024        mBatteryStatsService.publish(mContext);
2025        mUsageStatsService.publish(mContext);
2026        mAppOpsService.publish(mContext);
2027        startRunning(null, null, null, null);
2028    }
2029
2030    @Override
2031    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2032            throws RemoteException {
2033        if (code == SYSPROPS_TRANSACTION) {
2034            // We need to tell all apps about the system property change.
2035            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2036            synchronized(this) {
2037                final int NP = mProcessNames.getMap().size();
2038                for (int ip=0; ip<NP; ip++) {
2039                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2040                    final int NA = apps.size();
2041                    for (int ia=0; ia<NA; ia++) {
2042                        ProcessRecord app = apps.valueAt(ia);
2043                        if (app.thread != null) {
2044                            procs.add(app.thread.asBinder());
2045                        }
2046                    }
2047                }
2048            }
2049
2050            int N = procs.size();
2051            for (int i=0; i<N; i++) {
2052                Parcel data2 = Parcel.obtain();
2053                try {
2054                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2055                } catch (RemoteException e) {
2056                }
2057                data2.recycle();
2058            }
2059        }
2060        try {
2061            return super.onTransact(code, data, reply, flags);
2062        } catch (RuntimeException e) {
2063            // The activity manager only throws security exceptions, so let's
2064            // log all others.
2065            if (!(e instanceof SecurityException)) {
2066                Slog.wtf(TAG, "Activity Manager Crash", e);
2067            }
2068            throw e;
2069        }
2070    }
2071
2072    void updateCpuStats() {
2073        final long now = SystemClock.uptimeMillis();
2074        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2075            return;
2076        }
2077        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2078            synchronized (mProcessCpuThread) {
2079                mProcessCpuThread.notify();
2080            }
2081        }
2082    }
2083
2084    void updateCpuStatsNow() {
2085        synchronized (mProcessCpuThread) {
2086            mProcessCpuMutexFree.set(false);
2087            final long now = SystemClock.uptimeMillis();
2088            boolean haveNewCpuStats = false;
2089
2090            if (MONITOR_CPU_USAGE &&
2091                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2092                mLastCpuTime.set(now);
2093                haveNewCpuStats = true;
2094                mProcessCpuTracker.update();
2095                //Slog.i(TAG, mProcessCpu.printCurrentState());
2096                //Slog.i(TAG, "Total CPU usage: "
2097                //        + mProcessCpu.getTotalCpuPercent() + "%");
2098
2099                // Slog the cpu usage if the property is set.
2100                if ("true".equals(SystemProperties.get("events.cpu"))) {
2101                    int user = mProcessCpuTracker.getLastUserTime();
2102                    int system = mProcessCpuTracker.getLastSystemTime();
2103                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2104                    int irq = mProcessCpuTracker.getLastIrqTime();
2105                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2106                    int idle = mProcessCpuTracker.getLastIdleTime();
2107
2108                    int total = user + system + iowait + irq + softIrq + idle;
2109                    if (total == 0) total = 1;
2110
2111                    EventLog.writeEvent(EventLogTags.CPU,
2112                            ((user+system+iowait+irq+softIrq) * 100) / total,
2113                            (user * 100) / total,
2114                            (system * 100) / total,
2115                            (iowait * 100) / total,
2116                            (irq * 100) / total,
2117                            (softIrq * 100) / total);
2118                }
2119            }
2120
2121            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2122            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2123            synchronized(bstats) {
2124                synchronized(mPidsSelfLocked) {
2125                    if (haveNewCpuStats) {
2126                        if (mOnBattery) {
2127                            int perc = bstats.startAddingCpuLocked();
2128                            int totalUTime = 0;
2129                            int totalSTime = 0;
2130                            final int N = mProcessCpuTracker.countStats();
2131                            for (int i=0; i<N; i++) {
2132                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2133                                if (!st.working) {
2134                                    continue;
2135                                }
2136                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2137                                int otherUTime = (st.rel_utime*perc)/100;
2138                                int otherSTime = (st.rel_stime*perc)/100;
2139                                totalUTime += otherUTime;
2140                                totalSTime += otherSTime;
2141                                if (pr != null) {
2142                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2143                                    if (ps == null || !ps.isActive()) {
2144                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2145                                                pr.info.uid, pr.processName);
2146                                    }
2147                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2148                                            st.rel_stime-otherSTime);
2149                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2150                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2151                                } else {
2152                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2153                                    if (ps == null || !ps.isActive()) {
2154                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2155                                                bstats.mapUid(st.uid), st.name);
2156                                    }
2157                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2158                                            st.rel_stime-otherSTime);
2159                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2160                                }
2161                            }
2162                            bstats.finishAddingCpuLocked(perc, totalUTime,
2163                                    totalSTime, cpuSpeedTimes);
2164                        }
2165                    }
2166                }
2167
2168                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2169                    mLastWriteTime = now;
2170                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2171                }
2172            }
2173        }
2174    }
2175
2176    @Override
2177    public void batteryNeedsCpuUpdate() {
2178        updateCpuStatsNow();
2179    }
2180
2181    @Override
2182    public void batteryPowerChanged(boolean onBattery) {
2183        // When plugging in, update the CPU stats first before changing
2184        // the plug state.
2185        updateCpuStatsNow();
2186        synchronized (this) {
2187            synchronized(mPidsSelfLocked) {
2188                mOnBattery = DEBUG_POWER ? true : onBattery;
2189            }
2190        }
2191    }
2192
2193    /**
2194     * Initialize the application bind args. These are passed to each
2195     * process when the bindApplication() IPC is sent to the process. They're
2196     * lazily setup to make sure the services are running when they're asked for.
2197     */
2198    private HashMap<String, IBinder> getCommonServicesLocked() {
2199        if (mAppBindArgs == null) {
2200            mAppBindArgs = new HashMap<String, IBinder>();
2201
2202            // Setup the application init args
2203            mAppBindArgs.put("package", ServiceManager.getService("package"));
2204            mAppBindArgs.put("window", ServiceManager.getService("window"));
2205            mAppBindArgs.put(Context.ALARM_SERVICE,
2206                    ServiceManager.getService(Context.ALARM_SERVICE));
2207        }
2208        return mAppBindArgs;
2209    }
2210
2211    final void setFocusedActivityLocked(ActivityRecord r) {
2212        if (mFocusedActivity != r) {
2213            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2214            mFocusedActivity = r;
2215            mStackSupervisor.setFocusedStack(r);
2216            if (r != null) {
2217                mWindowManager.setFocusedApp(r.appToken, true);
2218            }
2219            applyUpdateLockStateLocked(r);
2220        }
2221    }
2222
2223    @Override
2224    public void setFocusedStack(int stackId) {
2225        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2226        synchronized (ActivityManagerService.this) {
2227            ActivityStack stack = mStackSupervisor.getStack(stackId);
2228            if (stack != null) {
2229                ActivityRecord r = stack.topRunningActivityLocked(null);
2230                if (r != null) {
2231                    setFocusedActivityLocked(r);
2232                }
2233            }
2234        }
2235    }
2236
2237    @Override
2238    public void notifyActivityDrawn(IBinder token) {
2239        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2240        synchronized (this) {
2241            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2242            if (r != null) {
2243                r.task.stack.notifyActivityDrawnLocked(r);
2244            }
2245        }
2246    }
2247
2248    final void applyUpdateLockStateLocked(ActivityRecord r) {
2249        // Modifications to the UpdateLock state are done on our handler, outside
2250        // the activity manager's locks.  The new state is determined based on the
2251        // state *now* of the relevant activity record.  The object is passed to
2252        // the handler solely for logging detail, not to be consulted/modified.
2253        final boolean nextState = r != null && r.immersive;
2254        mHandler.sendMessage(
2255                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2256    }
2257
2258    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2259        Message msg = Message.obtain();
2260        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2261        msg.obj = r.task.askedCompatMode ? null : r;
2262        mHandler.sendMessage(msg);
2263    }
2264
2265    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2266            String what, Object obj, ProcessRecord srcApp) {
2267        app.lastActivityTime = now;
2268
2269        if (app.activities.size() > 0) {
2270            // Don't want to touch dependent processes that are hosting activities.
2271            return index;
2272        }
2273
2274        int lrui = mLruProcesses.lastIndexOf(app);
2275        if (lrui < 0) {
2276            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2277                    + what + " " + obj + " from " + srcApp);
2278            return index;
2279        }
2280
2281        if (lrui >= index) {
2282            // Don't want to cause this to move dependent processes *back* in the
2283            // list as if they were less frequently used.
2284            return index;
2285        }
2286
2287        if (lrui >= mLruProcessActivityStart) {
2288            // Don't want to touch dependent processes that are hosting activities.
2289            return index;
2290        }
2291
2292        mLruProcesses.remove(lrui);
2293        if (index > 0) {
2294            index--;
2295        }
2296        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2297                + " in LRU list: " + app);
2298        mLruProcesses.add(index, app);
2299        return index;
2300    }
2301
2302    final void removeLruProcessLocked(ProcessRecord app) {
2303        int lrui = mLruProcesses.lastIndexOf(app);
2304        if (lrui >= 0) {
2305            if (lrui <= mLruProcessActivityStart) {
2306                mLruProcessActivityStart--;
2307            }
2308            if (lrui <= mLruProcessServiceStart) {
2309                mLruProcessServiceStart--;
2310            }
2311            mLruProcesses.remove(lrui);
2312        }
2313    }
2314
2315    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2316            ProcessRecord client) {
2317        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2318                || app.treatLikeActivity;
2319        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2320        if (!activityChange && hasActivity) {
2321            // The process has activities, so we are only allowing activity-based adjustments
2322            // to move it.  It should be kept in the front of the list with other
2323            // processes that have activities, and we don't want those to change their
2324            // order except due to activity operations.
2325            return;
2326        }
2327
2328        mLruSeq++;
2329        final long now = SystemClock.uptimeMillis();
2330        app.lastActivityTime = now;
2331
2332        // First a quick reject: if the app is already at the position we will
2333        // put it, then there is nothing to do.
2334        if (hasActivity) {
2335            final int N = mLruProcesses.size();
2336            if (N > 0 && mLruProcesses.get(N-1) == app) {
2337                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2338                return;
2339            }
2340        } else {
2341            if (mLruProcessServiceStart > 0
2342                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2343                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2344                return;
2345            }
2346        }
2347
2348        int lrui = mLruProcesses.lastIndexOf(app);
2349
2350        if (app.persistent && lrui >= 0) {
2351            // We don't care about the position of persistent processes, as long as
2352            // they are in the list.
2353            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2354            return;
2355        }
2356
2357        /* In progress: compute new position first, so we can avoid doing work
2358           if the process is not actually going to move.  Not yet working.
2359        int addIndex;
2360        int nextIndex;
2361        boolean inActivity = false, inService = false;
2362        if (hasActivity) {
2363            // Process has activities, put it at the very tipsy-top.
2364            addIndex = mLruProcesses.size();
2365            nextIndex = mLruProcessServiceStart;
2366            inActivity = true;
2367        } else if (hasService) {
2368            // Process has services, put it at the top of the service list.
2369            addIndex = mLruProcessActivityStart;
2370            nextIndex = mLruProcessServiceStart;
2371            inActivity = true;
2372            inService = true;
2373        } else  {
2374            // Process not otherwise of interest, it goes to the top of the non-service area.
2375            addIndex = mLruProcessServiceStart;
2376            if (client != null) {
2377                int clientIndex = mLruProcesses.lastIndexOf(client);
2378                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2379                        + app);
2380                if (clientIndex >= 0 && addIndex > clientIndex) {
2381                    addIndex = clientIndex;
2382                }
2383            }
2384            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2385        }
2386
2387        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2388                + mLruProcessActivityStart + "): " + app);
2389        */
2390
2391        if (lrui >= 0) {
2392            if (lrui < mLruProcessActivityStart) {
2393                mLruProcessActivityStart--;
2394            }
2395            if (lrui < mLruProcessServiceStart) {
2396                mLruProcessServiceStart--;
2397            }
2398            /*
2399            if (addIndex > lrui) {
2400                addIndex--;
2401            }
2402            if (nextIndex > lrui) {
2403                nextIndex--;
2404            }
2405            */
2406            mLruProcesses.remove(lrui);
2407        }
2408
2409        /*
2410        mLruProcesses.add(addIndex, app);
2411        if (inActivity) {
2412            mLruProcessActivityStart++;
2413        }
2414        if (inService) {
2415            mLruProcessActivityStart++;
2416        }
2417        */
2418
2419        int nextIndex;
2420        if (hasActivity) {
2421            final int N = mLruProcesses.size();
2422            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2423                // Process doesn't have activities, but has clients with
2424                // activities...  move it up, but one below the top (the top
2425                // should always have a real activity).
2426                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2427                mLruProcesses.add(N-1, app);
2428                // To keep it from spamming the LRU list (by making a bunch of clients),
2429                // we will push down any other entries owned by the app.
2430                final int uid = app.info.uid;
2431                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2432                    ProcessRecord subProc = mLruProcesses.get(i);
2433                    if (subProc.info.uid == uid) {
2434                        // We want to push this one down the list.  If the process after
2435                        // it is for the same uid, however, don't do so, because we don't
2436                        // want them internally to be re-ordered.
2437                        if (mLruProcesses.get(i-1).info.uid != uid) {
2438                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2439                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2440                            ProcessRecord tmp = mLruProcesses.get(i);
2441                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2442                            mLruProcesses.set(i-1, tmp);
2443                            i--;
2444                        }
2445                    } else {
2446                        // A gap, we can stop here.
2447                        break;
2448                    }
2449                }
2450            } else {
2451                // Process has activities, put it at the very tipsy-top.
2452                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2453                mLruProcesses.add(app);
2454            }
2455            nextIndex = mLruProcessServiceStart;
2456        } else if (hasService) {
2457            // Process has services, put it at the top of the service list.
2458            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2459            mLruProcesses.add(mLruProcessActivityStart, app);
2460            nextIndex = mLruProcessServiceStart;
2461            mLruProcessActivityStart++;
2462        } else  {
2463            // Process not otherwise of interest, it goes to the top of the non-service area.
2464            int index = mLruProcessServiceStart;
2465            if (client != null) {
2466                // If there is a client, don't allow the process to be moved up higher
2467                // in the list than that client.
2468                int clientIndex = mLruProcesses.lastIndexOf(client);
2469                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2470                        + " when updating " + app);
2471                if (clientIndex <= lrui) {
2472                    // Don't allow the client index restriction to push it down farther in the
2473                    // list than it already is.
2474                    clientIndex = lrui;
2475                }
2476                if (clientIndex >= 0 && index > clientIndex) {
2477                    index = clientIndex;
2478                }
2479            }
2480            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2481            mLruProcesses.add(index, app);
2482            nextIndex = index-1;
2483            mLruProcessActivityStart++;
2484            mLruProcessServiceStart++;
2485        }
2486
2487        // If the app is currently using a content provider or service,
2488        // bump those processes as well.
2489        for (int j=app.connections.size()-1; j>=0; j--) {
2490            ConnectionRecord cr = app.connections.valueAt(j);
2491            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2492                    && cr.binding.service.app != null
2493                    && cr.binding.service.app.lruSeq != mLruSeq
2494                    && !cr.binding.service.app.persistent) {
2495                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2496                        "service connection", cr, app);
2497            }
2498        }
2499        for (int j=app.conProviders.size()-1; j>=0; j--) {
2500            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2501            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2502                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2503                        "provider reference", cpr, app);
2504            }
2505        }
2506    }
2507
2508    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2509        if (uid == Process.SYSTEM_UID) {
2510            // The system gets to run in any process.  If there are multiple
2511            // processes with the same uid, just pick the first (this
2512            // should never happen).
2513            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2514            if (procs == null) return null;
2515            final int N = procs.size();
2516            for (int i = 0; i < N; i++) {
2517                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2518            }
2519        }
2520        ProcessRecord proc = mProcessNames.get(processName, uid);
2521        if (false && proc != null && !keepIfLarge
2522                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2523                && proc.lastCachedPss >= 4000) {
2524            // Turn this condition on to cause killing to happen regularly, for testing.
2525            if (proc.baseProcessTracker != null) {
2526                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2527            }
2528            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2529                    + "k from cached");
2530        } else if (proc != null && !keepIfLarge
2531                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2532                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2533            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2534            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2535                if (proc.baseProcessTracker != null) {
2536                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2537                }
2538                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2539                        + "k from cached");
2540            }
2541        }
2542        return proc;
2543    }
2544
2545    void ensurePackageDexOpt(String packageName) {
2546        IPackageManager pm = AppGlobals.getPackageManager();
2547        try {
2548            if (pm.performDexOpt(packageName)) {
2549                mDidDexOpt = true;
2550            }
2551        } catch (RemoteException e) {
2552        }
2553    }
2554
2555    boolean isNextTransitionForward() {
2556        int transit = mWindowManager.getPendingAppTransition();
2557        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2558                || transit == AppTransition.TRANSIT_TASK_OPEN
2559                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2560    }
2561
2562    final ProcessRecord startProcessLocked(String processName,
2563            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2564            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2565            boolean isolated, boolean keepIfLarge) {
2566        ProcessRecord app;
2567        if (!isolated) {
2568            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2569        } else {
2570            // If this is an isolated process, it can't re-use an existing process.
2571            app = null;
2572        }
2573        // We don't have to do anything more if:
2574        // (1) There is an existing application record; and
2575        // (2) The caller doesn't think it is dead, OR there is no thread
2576        //     object attached to it so we know it couldn't have crashed; and
2577        // (3) There is a pid assigned to it, so it is either starting or
2578        //     already running.
2579        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2580                + " app=" + app + " knownToBeDead=" + knownToBeDead
2581                + " thread=" + (app != null ? app.thread : null)
2582                + " pid=" + (app != null ? app.pid : -1));
2583        if (app != null && app.pid > 0) {
2584            if (!knownToBeDead || app.thread == null) {
2585                // We already have the app running, or are waiting for it to
2586                // come up (we have a pid but not yet its thread), so keep it.
2587                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2588                // If this is a new package in the process, add the package to the list
2589                app.addPackage(info.packageName, mProcessStats);
2590                return app;
2591            }
2592
2593            // An application record is attached to a previous process,
2594            // clean it up now.
2595            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2596            handleAppDiedLocked(app, true, true);
2597        }
2598
2599        String hostingNameStr = hostingName != null
2600                ? hostingName.flattenToShortString() : null;
2601
2602        if (!isolated) {
2603            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2604                // If we are in the background, then check to see if this process
2605                // is bad.  If so, we will just silently fail.
2606                if (mBadProcesses.get(info.processName, info.uid) != null) {
2607                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2608                            + "/" + info.processName);
2609                    return null;
2610                }
2611            } else {
2612                // When the user is explicitly starting a process, then clear its
2613                // crash count so that we won't make it bad until they see at
2614                // least one crash dialog again, and make the process good again
2615                // if it had been bad.
2616                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2617                        + "/" + info.processName);
2618                mProcessCrashTimes.remove(info.processName, info.uid);
2619                if (mBadProcesses.get(info.processName, info.uid) != null) {
2620                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2621                            UserHandle.getUserId(info.uid), info.uid,
2622                            info.processName);
2623                    mBadProcesses.remove(info.processName, info.uid);
2624                    if (app != null) {
2625                        app.bad = false;
2626                    }
2627                }
2628            }
2629        }
2630
2631        if (app == null) {
2632            app = newProcessRecordLocked(info, processName, isolated);
2633            if (app == null) {
2634                Slog.w(TAG, "Failed making new process record for "
2635                        + processName + "/" + info.uid + " isolated=" + isolated);
2636                return null;
2637            }
2638            mProcessNames.put(processName, app.uid, app);
2639            if (isolated) {
2640                mIsolatedProcesses.put(app.uid, app);
2641            }
2642        } else {
2643            // If this is a new package in the process, add the package to the list
2644            app.addPackage(info.packageName, mProcessStats);
2645        }
2646
2647        // If the system is not ready yet, then hold off on starting this
2648        // process until it is.
2649        if (!mProcessesReady
2650                && !isAllowedWhileBooting(info)
2651                && !allowWhileBooting) {
2652            if (!mProcessesOnHold.contains(app)) {
2653                mProcessesOnHold.add(app);
2654            }
2655            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2656            return app;
2657        }
2658
2659        startProcessLocked(app, hostingType, hostingNameStr);
2660        return (app.pid != 0) ? app : null;
2661    }
2662
2663    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2664        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2665    }
2666
2667    private final void startProcessLocked(ProcessRecord app,
2668            String hostingType, String hostingNameStr) {
2669        if (app.pid > 0 && app.pid != MY_PID) {
2670            synchronized (mPidsSelfLocked) {
2671                mPidsSelfLocked.remove(app.pid);
2672                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2673            }
2674            app.setPid(0);
2675        }
2676
2677        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2678                "startProcessLocked removing on hold: " + app);
2679        mProcessesOnHold.remove(app);
2680
2681        updateCpuStats();
2682
2683        try {
2684            int uid = app.uid;
2685
2686            int[] gids = null;
2687            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2688            if (!app.isolated) {
2689                int[] permGids = null;
2690                try {
2691                    final PackageManager pm = mContext.getPackageManager();
2692                    permGids = pm.getPackageGids(app.info.packageName);
2693
2694                    if (Environment.isExternalStorageEmulated()) {
2695                        if (pm.checkPermission(
2696                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2697                                app.info.packageName) == PERMISSION_GRANTED) {
2698                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2699                        } else {
2700                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2701                        }
2702                    }
2703                } catch (PackageManager.NameNotFoundException e) {
2704                    Slog.w(TAG, "Unable to retrieve gids", e);
2705                }
2706
2707                /*
2708                 * Add shared application GID so applications can share some
2709                 * resources like shared libraries
2710                 */
2711                if (permGids == null) {
2712                    gids = new int[1];
2713                } else {
2714                    gids = new int[permGids.length + 1];
2715                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2716                }
2717                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2718            }
2719            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2720                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2721                        && mTopComponent != null
2722                        && app.processName.equals(mTopComponent.getPackageName())) {
2723                    uid = 0;
2724                }
2725                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2726                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2727                    uid = 0;
2728                }
2729            }
2730            int debugFlags = 0;
2731            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2732                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2733                // Also turn on CheckJNI for debuggable apps. It's quite
2734                // awkward to turn on otherwise.
2735                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2736            }
2737            // Run the app in safe mode if its manifest requests so or the
2738            // system is booted in safe mode.
2739            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2740                Zygote.systemInSafeMode == true) {
2741                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2742            }
2743            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2744                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2745            }
2746            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2747                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2748            }
2749            if ("1".equals(SystemProperties.get("debug.assert"))) {
2750                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2751            }
2752
2753            // Start the process.  It will either succeed and return a result containing
2754            // the PID of the new process, or else throw a RuntimeException.
2755            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2756                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2757                    app.info.targetSdkVersion, app.info.seinfo, null);
2758
2759            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2760            synchronized (bs) {
2761                if (bs.isOnBattery()) {
2762                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2763                }
2764            }
2765
2766            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2767                    UserHandle.getUserId(uid), startResult.pid, uid,
2768                    app.processName, hostingType,
2769                    hostingNameStr != null ? hostingNameStr : "");
2770
2771            if (app.persistent) {
2772                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2773            }
2774
2775            StringBuilder buf = mStringBuilder;
2776            buf.setLength(0);
2777            buf.append("Start proc ");
2778            buf.append(app.processName);
2779            buf.append(" for ");
2780            buf.append(hostingType);
2781            if (hostingNameStr != null) {
2782                buf.append(" ");
2783                buf.append(hostingNameStr);
2784            }
2785            buf.append(": pid=");
2786            buf.append(startResult.pid);
2787            buf.append(" uid=");
2788            buf.append(uid);
2789            buf.append(" gids={");
2790            if (gids != null) {
2791                for (int gi=0; gi<gids.length; gi++) {
2792                    if (gi != 0) buf.append(", ");
2793                    buf.append(gids[gi]);
2794
2795                }
2796            }
2797            buf.append("}");
2798            Slog.i(TAG, buf.toString());
2799            app.setPid(startResult.pid);
2800            app.usingWrapper = startResult.usingWrapper;
2801            app.removed = false;
2802            synchronized (mPidsSelfLocked) {
2803                this.mPidsSelfLocked.put(startResult.pid, app);
2804                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2805                msg.obj = app;
2806                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2807                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2808            }
2809            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
2810                    app.processName, app.info.uid);
2811            if (app.isolated) {
2812                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2813            }
2814        } catch (RuntimeException e) {
2815            // XXX do better error recovery.
2816            app.setPid(0);
2817            Slog.e(TAG, "Failure starting process " + app.processName, e);
2818        }
2819    }
2820
2821    void updateUsageStats(ActivityRecord component, boolean resumed) {
2822        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
2823        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2824        if (resumed) {
2825            mUsageStatsService.noteResumeComponent(component.realActivity);
2826            synchronized (stats) {
2827                stats.noteActivityResumedLocked(component.app.uid);
2828            }
2829        } else {
2830            mUsageStatsService.notePauseComponent(component.realActivity);
2831            synchronized (stats) {
2832                stats.noteActivityPausedLocked(component.app.uid);
2833            }
2834        }
2835    }
2836
2837    Intent getHomeIntent() {
2838        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
2839        intent.setComponent(mTopComponent);
2840        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
2841            intent.addCategory(Intent.CATEGORY_HOME);
2842        }
2843        return intent;
2844    }
2845
2846    boolean startHomeActivityLocked(int userId) {
2847        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2848                && mTopAction == null) {
2849            // We are running in factory test mode, but unable to find
2850            // the factory test app, so just sit around displaying the
2851            // error message and don't try to start anything.
2852            return false;
2853        }
2854        Intent intent = getHomeIntent();
2855        ActivityInfo aInfo =
2856            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2857        if (aInfo != null) {
2858            intent.setComponent(new ComponentName(
2859                    aInfo.applicationInfo.packageName, aInfo.name));
2860            // Don't do this if the home app is currently being
2861            // instrumented.
2862            aInfo = new ActivityInfo(aInfo);
2863            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2864            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2865                    aInfo.applicationInfo.uid, true);
2866            if (app == null || app.instrumentationClass == null) {
2867                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2868                mStackSupervisor.startHomeActivity(intent, aInfo);
2869            }
2870        }
2871
2872        return true;
2873    }
2874
2875    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2876        ActivityInfo ai = null;
2877        ComponentName comp = intent.getComponent();
2878        try {
2879            if (comp != null) {
2880                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2881            } else {
2882                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2883                        intent,
2884                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2885                            flags, userId);
2886
2887                if (info != null) {
2888                    ai = info.activityInfo;
2889                }
2890            }
2891        } catch (RemoteException e) {
2892            // ignore
2893        }
2894
2895        return ai;
2896    }
2897
2898    /**
2899     * Starts the "new version setup screen" if appropriate.
2900     */
2901    void startSetupActivityLocked() {
2902        // Only do this once per boot.
2903        if (mCheckedForSetup) {
2904            return;
2905        }
2906
2907        // We will show this screen if the current one is a different
2908        // version than the last one shown, and we are not running in
2909        // low-level factory test mode.
2910        final ContentResolver resolver = mContext.getContentResolver();
2911        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
2912                Settings.Global.getInt(resolver,
2913                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
2914            mCheckedForSetup = true;
2915
2916            // See if we should be showing the platform update setup UI.
2917            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2918            List<ResolveInfo> ris = mContext.getPackageManager()
2919                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2920
2921            // We don't allow third party apps to replace this.
2922            ResolveInfo ri = null;
2923            for (int i=0; ris != null && i<ris.size(); i++) {
2924                if ((ris.get(i).activityInfo.applicationInfo.flags
2925                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2926                    ri = ris.get(i);
2927                    break;
2928                }
2929            }
2930
2931            if (ri != null) {
2932                String vers = ri.activityInfo.metaData != null
2933                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2934                        : null;
2935                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2936                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2937                            Intent.METADATA_SETUP_VERSION);
2938                }
2939                String lastVers = Settings.Secure.getString(
2940                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2941                if (vers != null && !vers.equals(lastVers)) {
2942                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2943                    intent.setComponent(new ComponentName(
2944                            ri.activityInfo.packageName, ri.activityInfo.name));
2945                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
2946                            null, null, 0, 0, 0, null, 0, null, false, null, null);
2947                }
2948            }
2949        }
2950    }
2951
2952    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2953        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2954    }
2955
2956    void enforceNotIsolatedCaller(String caller) {
2957        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2958            throw new SecurityException("Isolated process not allowed to call " + caller);
2959        }
2960    }
2961
2962    @Override
2963    public int getFrontActivityScreenCompatMode() {
2964        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2965        synchronized (this) {
2966            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2967        }
2968    }
2969
2970    @Override
2971    public void setFrontActivityScreenCompatMode(int mode) {
2972        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2973                "setFrontActivityScreenCompatMode");
2974        synchronized (this) {
2975            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2976        }
2977    }
2978
2979    @Override
2980    public int getPackageScreenCompatMode(String packageName) {
2981        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2982        synchronized (this) {
2983            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2984        }
2985    }
2986
2987    @Override
2988    public void setPackageScreenCompatMode(String packageName, int mode) {
2989        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2990                "setPackageScreenCompatMode");
2991        synchronized (this) {
2992            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2993        }
2994    }
2995
2996    @Override
2997    public boolean getPackageAskScreenCompat(String packageName) {
2998        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2999        synchronized (this) {
3000            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3001        }
3002    }
3003
3004    @Override
3005    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3006        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3007                "setPackageAskScreenCompat");
3008        synchronized (this) {
3009            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3010        }
3011    }
3012
3013    private void dispatchProcessesChanged() {
3014        int N;
3015        synchronized (this) {
3016            N = mPendingProcessChanges.size();
3017            if (mActiveProcessChanges.length < N) {
3018                mActiveProcessChanges = new ProcessChangeItem[N];
3019            }
3020            mPendingProcessChanges.toArray(mActiveProcessChanges);
3021            mAvailProcessChanges.addAll(mPendingProcessChanges);
3022            mPendingProcessChanges.clear();
3023            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3024        }
3025
3026        int i = mProcessObservers.beginBroadcast();
3027        while (i > 0) {
3028            i--;
3029            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3030            if (observer != null) {
3031                try {
3032                    for (int j=0; j<N; j++) {
3033                        ProcessChangeItem item = mActiveProcessChanges[j];
3034                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3035                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3036                                    + item.pid + " uid=" + item.uid + ": "
3037                                    + item.foregroundActivities);
3038                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3039                                    item.foregroundActivities);
3040                        }
3041                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
3042                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
3043                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
3044                            observer.onImportanceChanged(item.pid, item.uid,
3045                                    item.importance);
3046                        }
3047                    }
3048                } catch (RemoteException e) {
3049                }
3050            }
3051        }
3052        mProcessObservers.finishBroadcast();
3053    }
3054
3055    private void dispatchProcessDied(int pid, int uid) {
3056        int i = mProcessObservers.beginBroadcast();
3057        while (i > 0) {
3058            i--;
3059            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3060            if (observer != null) {
3061                try {
3062                    observer.onProcessDied(pid, uid);
3063                } catch (RemoteException e) {
3064                }
3065            }
3066        }
3067        mProcessObservers.finishBroadcast();
3068    }
3069
3070    final void doPendingActivityLaunchesLocked(boolean doResume) {
3071        final int N = mPendingActivityLaunches.size();
3072        if (N <= 0) {
3073            return;
3074        }
3075        for (int i=0; i<N; i++) {
3076            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3077            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags,
3078                    doResume && i == (N-1), null);
3079        }
3080        mPendingActivityLaunches.clear();
3081    }
3082
3083    @Override
3084    public final int startActivity(IApplicationThread caller, String callingPackage,
3085            Intent intent, String resolvedType, IBinder resultTo,
3086            String resultWho, int requestCode, int startFlags,
3087            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3088        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3089                resultWho, requestCode,
3090                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3091    }
3092
3093    @Override
3094    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3095            Intent intent, String resolvedType, IBinder resultTo,
3096            String resultWho, int requestCode, int startFlags,
3097            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3098        enforceNotIsolatedCaller("startActivity");
3099        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3100                false, true, "startActivity", null);
3101        // TODO: Switch to user app stacks here.
3102        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3103                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3104                null, null, options, userId, null);
3105    }
3106
3107    @Override
3108    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3109            Intent intent, String resolvedType, IBinder resultTo,
3110            String resultWho, int requestCode, int startFlags, String profileFile,
3111            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3112        enforceNotIsolatedCaller("startActivityAndWait");
3113        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3114                false, true, "startActivityAndWait", null);
3115        WaitResult res = new WaitResult();
3116        // TODO: Switch to user app stacks here.
3117        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3118                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3119                res, null, options, UserHandle.getCallingUserId(), null);
3120        return res;
3121    }
3122
3123    @Override
3124    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3125            Intent intent, String resolvedType, IBinder resultTo,
3126            String resultWho, int requestCode, int startFlags, Configuration config,
3127            Bundle options, int userId) {
3128        enforceNotIsolatedCaller("startActivityWithConfig");
3129        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3130                false, true, "startActivityWithConfig", null);
3131        // TODO: Switch to user app stacks here.
3132        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3133                resolvedType, resultTo, resultWho, requestCode, startFlags,
3134                null, null, null, config, options, userId, null);
3135        return ret;
3136    }
3137
3138    @Override
3139    public int startActivityIntentSender(IApplicationThread caller,
3140            IntentSender intent, Intent fillInIntent, String resolvedType,
3141            IBinder resultTo, String resultWho, int requestCode,
3142            int flagsMask, int flagsValues, Bundle options) {
3143        enforceNotIsolatedCaller("startActivityIntentSender");
3144        // Refuse possible leaked file descriptors
3145        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3146            throw new IllegalArgumentException("File descriptors passed in Intent");
3147        }
3148
3149        IIntentSender sender = intent.getTarget();
3150        if (!(sender instanceof PendingIntentRecord)) {
3151            throw new IllegalArgumentException("Bad PendingIntent object");
3152        }
3153
3154        PendingIntentRecord pir = (PendingIntentRecord)sender;
3155
3156        synchronized (this) {
3157            // If this is coming from the currently resumed activity, it is
3158            // effectively saying that app switches are allowed at this point.
3159            final ActivityStack stack = getFocusedStack();
3160            if (stack.mResumedActivity != null &&
3161                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3162                mAppSwitchesAllowedTime = 0;
3163            }
3164        }
3165        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3166                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3167        return ret;
3168    }
3169
3170    @Override
3171    public boolean startNextMatchingActivity(IBinder callingActivity,
3172            Intent intent, Bundle options) {
3173        // Refuse possible leaked file descriptors
3174        if (intent != null && intent.hasFileDescriptors() == true) {
3175            throw new IllegalArgumentException("File descriptors passed in Intent");
3176        }
3177
3178        synchronized (this) {
3179            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3180            if (r == null) {
3181                ActivityOptions.abort(options);
3182                return false;
3183            }
3184            if (r.app == null || r.app.thread == null) {
3185                // The caller is not running...  d'oh!
3186                ActivityOptions.abort(options);
3187                return false;
3188            }
3189            intent = new Intent(intent);
3190            // The caller is not allowed to change the data.
3191            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3192            // And we are resetting to find the next component...
3193            intent.setComponent(null);
3194
3195            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3196
3197            ActivityInfo aInfo = null;
3198            try {
3199                List<ResolveInfo> resolves =
3200                    AppGlobals.getPackageManager().queryIntentActivities(
3201                            intent, r.resolvedType,
3202                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3203                            UserHandle.getCallingUserId());
3204
3205                // Look for the original activity in the list...
3206                final int N = resolves != null ? resolves.size() : 0;
3207                for (int i=0; i<N; i++) {
3208                    ResolveInfo rInfo = resolves.get(i);
3209                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3210                            && rInfo.activityInfo.name.equals(r.info.name)) {
3211                        // We found the current one...  the next matching is
3212                        // after it.
3213                        i++;
3214                        if (i<N) {
3215                            aInfo = resolves.get(i).activityInfo;
3216                        }
3217                        if (debug) {
3218                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3219                                    + "/" + r.info.name);
3220                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3221                                    + "/" + aInfo.name);
3222                        }
3223                        break;
3224                    }
3225                }
3226            } catch (RemoteException e) {
3227            }
3228
3229            if (aInfo == null) {
3230                // Nobody who is next!
3231                ActivityOptions.abort(options);
3232                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3233                return false;
3234            }
3235
3236            intent.setComponent(new ComponentName(
3237                    aInfo.applicationInfo.packageName, aInfo.name));
3238            intent.setFlags(intent.getFlags()&~(
3239                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3240                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3241                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3242                    Intent.FLAG_ACTIVITY_NEW_TASK));
3243
3244            // Okay now we need to start the new activity, replacing the
3245            // currently running activity.  This is a little tricky because
3246            // we want to start the new one as if the current one is finished,
3247            // but not finish the current one first so that there is no flicker.
3248            // And thus...
3249            final boolean wasFinishing = r.finishing;
3250            r.finishing = true;
3251
3252            // Propagate reply information over to the new activity.
3253            final ActivityRecord resultTo = r.resultTo;
3254            final String resultWho = r.resultWho;
3255            final int requestCode = r.requestCode;
3256            r.resultTo = null;
3257            if (resultTo != null) {
3258                resultTo.removeResultsLocked(r, resultWho, requestCode);
3259            }
3260
3261            final long origId = Binder.clearCallingIdentity();
3262            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3263                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
3264                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3265                    options, false, null, null);
3266            Binder.restoreCallingIdentity(origId);
3267
3268            r.finishing = wasFinishing;
3269            if (res != ActivityManager.START_SUCCESS) {
3270                return false;
3271            }
3272            return true;
3273        }
3274    }
3275
3276    final int startActivityInPackage(int uid, String callingPackage,
3277            Intent intent, String resolvedType, IBinder resultTo,
3278            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3279                    IActivityContainer container) {
3280
3281        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3282                false, true, "startActivityInPackage", null);
3283
3284        // TODO: Switch to user app stacks here.
3285        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3286                resultTo, resultWho, requestCode, startFlags,
3287                null, null, null, null, options, userId, container);
3288        return ret;
3289    }
3290
3291    @Override
3292    public final int startActivities(IApplicationThread caller, String callingPackage,
3293            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3294            int userId) {
3295        enforceNotIsolatedCaller("startActivities");
3296        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3297                false, true, "startActivity", null);
3298        // TODO: Switch to user app stacks here.
3299        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3300                resolvedTypes, resultTo, options, userId);
3301        return ret;
3302    }
3303
3304    final int startActivitiesInPackage(int uid, String callingPackage,
3305            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3306            Bundle options, int userId) {
3307
3308        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3309                false, true, "startActivityInPackage", null);
3310        // TODO: Switch to user app stacks here.
3311        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3312                resultTo, options, userId);
3313        return ret;
3314    }
3315
3316    final void addRecentTaskLocked(TaskRecord task) {
3317        int N = mRecentTasks.size();
3318        // Quick case: check if the top-most recent task is the same.
3319        if (N > 0 && mRecentTasks.get(0) == task) {
3320            return;
3321        }
3322        // Remove any existing entries that are the same kind of task.
3323        final Intent intent = task.intent;
3324        final boolean document = intent != null && intent.isDocument();
3325        for (int i=0; i<N; i++) {
3326            TaskRecord tr = mRecentTasks.get(i);
3327            if (task != tr) {
3328                if (task.userId != tr.userId) {
3329                    continue;
3330                }
3331                final Intent trIntent = tr.intent;
3332                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3333                    (intent == null || !intent.filterEquals(trIntent))) {
3334                    continue;
3335                }
3336                if (document || trIntent != null && trIntent.isDocument()) {
3337                    // Document tasks do not match other tasks.
3338                    continue;
3339                }
3340            }
3341
3342            // Either task and tr are the same or, their affinities match or their intents match
3343            // and neither of them is a document.
3344            tr.disposeThumbnail();
3345            mRecentTasks.remove(i);
3346            i--;
3347            N--;
3348            if (task.intent == null) {
3349                // If the new recent task we are adding is not fully
3350                // specified, then replace it with the existing recent task.
3351                task = tr;
3352            }
3353        }
3354        if (N >= MAX_RECENT_TASKS) {
3355            mRecentTasks.remove(N-1).disposeThumbnail();
3356        }
3357        mRecentTasks.add(0, task);
3358    }
3359
3360    @Override
3361    public void reportActivityFullyDrawn(IBinder token) {
3362        synchronized (this) {
3363            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3364            if (r == null) {
3365                return;
3366            }
3367            r.reportFullyDrawnLocked();
3368        }
3369    }
3370
3371    @Override
3372    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3373        synchronized (this) {
3374            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3375            if (r == null) {
3376                return;
3377            }
3378            final long origId = Binder.clearCallingIdentity();
3379            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3380            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3381                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3382            if (config != null) {
3383                r.frozenBeforeDestroy = true;
3384                if (!updateConfigurationLocked(config, r, false, false)) {
3385                    mStackSupervisor.resumeTopActivitiesLocked();
3386                }
3387            }
3388            Binder.restoreCallingIdentity(origId);
3389        }
3390    }
3391
3392    @Override
3393    public int getRequestedOrientation(IBinder token) {
3394        synchronized (this) {
3395            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3396            if (r == null) {
3397                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3398            }
3399            return mWindowManager.getAppOrientation(r.appToken);
3400        }
3401    }
3402
3403    /**
3404     * This is the internal entry point for handling Activity.finish().
3405     *
3406     * @param token The Binder token referencing the Activity we want to finish.
3407     * @param resultCode Result code, if any, from this Activity.
3408     * @param resultData Result data (Intent), if any, from this Activity.
3409     *
3410     * @return Returns true if the activity successfully finished, or false if it is still running.
3411     */
3412    @Override
3413    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
3414        // Refuse possible leaked file descriptors
3415        if (resultData != null && resultData.hasFileDescriptors() == true) {
3416            throw new IllegalArgumentException("File descriptors passed in Intent");
3417        }
3418
3419        synchronized(this) {
3420            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3421            if (r == null) {
3422                return true;
3423            }
3424            if (mController != null) {
3425                // Find the first activity that is not finishing.
3426                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3427                if (next != null) {
3428                    // ask watcher if this is allowed
3429                    boolean resumeOK = true;
3430                    try {
3431                        resumeOK = mController.activityResuming(next.packageName);
3432                    } catch (RemoteException e) {
3433                        mController = null;
3434                        Watchdog.getInstance().setActivityController(null);
3435                    }
3436
3437                    if (!resumeOK) {
3438                        return false;
3439                    }
3440                }
3441            }
3442            final long origId = Binder.clearCallingIdentity();
3443            boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode,
3444                    resultData, "app-request", true);
3445            Binder.restoreCallingIdentity(origId);
3446            return res;
3447        }
3448    }
3449
3450    @Override
3451    public final void finishHeavyWeightApp() {
3452        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3453                != PackageManager.PERMISSION_GRANTED) {
3454            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3455                    + Binder.getCallingPid()
3456                    + ", uid=" + Binder.getCallingUid()
3457                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3458            Slog.w(TAG, msg);
3459            throw new SecurityException(msg);
3460        }
3461
3462        synchronized(this) {
3463            if (mHeavyWeightProcess == null) {
3464                return;
3465            }
3466
3467            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3468                    mHeavyWeightProcess.activities);
3469            for (int i=0; i<activities.size(); i++) {
3470                ActivityRecord r = activities.get(i);
3471                if (!r.finishing) {
3472                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3473                            null, "finish-heavy", true);
3474                }
3475            }
3476
3477            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3478                    mHeavyWeightProcess.userId, 0));
3479            mHeavyWeightProcess = null;
3480        }
3481    }
3482
3483    @Override
3484    public void crashApplication(int uid, int initialPid, String packageName,
3485            String message) {
3486        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3487                != PackageManager.PERMISSION_GRANTED) {
3488            String msg = "Permission Denial: crashApplication() from pid="
3489                    + Binder.getCallingPid()
3490                    + ", uid=" + Binder.getCallingUid()
3491                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3492            Slog.w(TAG, msg);
3493            throw new SecurityException(msg);
3494        }
3495
3496        synchronized(this) {
3497            ProcessRecord proc = null;
3498
3499            // Figure out which process to kill.  We don't trust that initialPid
3500            // still has any relation to current pids, so must scan through the
3501            // list.
3502            synchronized (mPidsSelfLocked) {
3503                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3504                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3505                    if (p.uid != uid) {
3506                        continue;
3507                    }
3508                    if (p.pid == initialPid) {
3509                        proc = p;
3510                        break;
3511                    }
3512                    if (p.pkgList.containsKey(packageName)) {
3513                        proc = p;
3514                    }
3515                }
3516            }
3517
3518            if (proc == null) {
3519                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3520                        + " initialPid=" + initialPid
3521                        + " packageName=" + packageName);
3522                return;
3523            }
3524
3525            if (proc.thread != null) {
3526                if (proc.pid == Process.myPid()) {
3527                    Log.w(TAG, "crashApplication: trying to crash self!");
3528                    return;
3529                }
3530                long ident = Binder.clearCallingIdentity();
3531                try {
3532                    proc.thread.scheduleCrash(message);
3533                } catch (RemoteException e) {
3534                }
3535                Binder.restoreCallingIdentity(ident);
3536            }
3537        }
3538    }
3539
3540    @Override
3541    public final void finishSubActivity(IBinder token, String resultWho,
3542            int requestCode) {
3543        synchronized(this) {
3544            final long origId = Binder.clearCallingIdentity();
3545            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3546            if (r != null) {
3547                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3548            }
3549            Binder.restoreCallingIdentity(origId);
3550        }
3551    }
3552
3553    @Override
3554    public boolean finishActivityAffinity(IBinder token) {
3555        synchronized(this) {
3556            final long origId = Binder.clearCallingIdentity();
3557            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3558            boolean res = false;
3559            if (r != null) {
3560                res = r.task.stack.finishActivityAffinityLocked(r);
3561            }
3562            Binder.restoreCallingIdentity(origId);
3563            return res;
3564        }
3565    }
3566
3567    @Override
3568    public boolean willActivityBeVisible(IBinder token) {
3569        synchronized(this) {
3570            ActivityStack stack = ActivityRecord.getStackLocked(token);
3571            if (stack != null) {
3572                return stack.willActivityBeVisibleLocked(token);
3573            }
3574            return false;
3575        }
3576    }
3577
3578    @Override
3579    public void overridePendingTransition(IBinder token, String packageName,
3580            int enterAnim, int exitAnim) {
3581        synchronized(this) {
3582            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3583            if (self == null) {
3584                return;
3585            }
3586
3587            final long origId = Binder.clearCallingIdentity();
3588
3589            if (self.state == ActivityState.RESUMED
3590                    || self.state == ActivityState.PAUSING) {
3591                mWindowManager.overridePendingAppTransition(packageName,
3592                        enterAnim, exitAnim, null);
3593            }
3594
3595            Binder.restoreCallingIdentity(origId);
3596        }
3597    }
3598
3599    /**
3600     * Main function for removing an existing process from the activity manager
3601     * as a result of that process going away.  Clears out all connections
3602     * to the process.
3603     */
3604    private final void handleAppDiedLocked(ProcessRecord app,
3605            boolean restarting, boolean allowRestart) {
3606        int pid = app.pid;
3607        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3608        if (!restarting) {
3609            removeLruProcessLocked(app);
3610            if (pid > 0) {
3611                ProcessList.remove(pid);
3612            }
3613        }
3614
3615        if (mProfileProc == app) {
3616            clearProfilerLocked();
3617        }
3618
3619        // Remove this application's activities from active lists.
3620        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3621
3622        app.activities.clear();
3623
3624        if (app.instrumentationClass != null) {
3625            Slog.w(TAG, "Crash of app " + app.processName
3626                  + " running instrumentation " + app.instrumentationClass);
3627            Bundle info = new Bundle();
3628            info.putString("shortMsg", "Process crashed.");
3629            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3630        }
3631
3632        if (!restarting) {
3633            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3634                // If there was nothing to resume, and we are not already
3635                // restarting this process, but there is a visible activity that
3636                // is hosted by the process...  then make sure all visible
3637                // activities are running, taking care of restarting this
3638                // process.
3639                if (hasVisibleActivities) {
3640                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3641                }
3642            }
3643        }
3644    }
3645
3646    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3647        IBinder threadBinder = thread.asBinder();
3648        // Find the application record.
3649        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3650            ProcessRecord rec = mLruProcesses.get(i);
3651            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3652                return i;
3653            }
3654        }
3655        return -1;
3656    }
3657
3658    final ProcessRecord getRecordForAppLocked(
3659            IApplicationThread thread) {
3660        if (thread == null) {
3661            return null;
3662        }
3663
3664        int appIndex = getLRURecordIndexForAppLocked(thread);
3665        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3666    }
3667
3668    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3669        // If there are no longer any background processes running,
3670        // and the app that died was not running instrumentation,
3671        // then tell everyone we are now low on memory.
3672        boolean haveBg = false;
3673        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3674            ProcessRecord rec = mLruProcesses.get(i);
3675            if (rec.thread != null
3676                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3677                haveBg = true;
3678                break;
3679            }
3680        }
3681
3682        if (!haveBg) {
3683            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3684            if (doReport) {
3685                long now = SystemClock.uptimeMillis();
3686                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3687                    doReport = false;
3688                } else {
3689                    mLastMemUsageReportTime = now;
3690                }
3691            }
3692            final ArrayList<ProcessMemInfo> memInfos
3693                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3694            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3695            long now = SystemClock.uptimeMillis();
3696            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3697                ProcessRecord rec = mLruProcesses.get(i);
3698                if (rec == dyingProc || rec.thread == null) {
3699                    continue;
3700                }
3701                if (doReport) {
3702                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3703                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3704                }
3705                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3706                    // The low memory report is overriding any current
3707                    // state for a GC request.  Make sure to do
3708                    // heavy/important/visible/foreground processes first.
3709                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3710                        rec.lastRequestedGc = 0;
3711                    } else {
3712                        rec.lastRequestedGc = rec.lastLowMemory;
3713                    }
3714                    rec.reportLowMemory = true;
3715                    rec.lastLowMemory = now;
3716                    mProcessesToGc.remove(rec);
3717                    addProcessToGcListLocked(rec);
3718                }
3719            }
3720            if (doReport) {
3721                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3722                mHandler.sendMessage(msg);
3723            }
3724            scheduleAppGcsLocked();
3725        }
3726    }
3727
3728    final void appDiedLocked(ProcessRecord app, int pid,
3729            IApplicationThread thread) {
3730
3731        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3732        synchronized (stats) {
3733            stats.noteProcessDiedLocked(app.info.uid, pid);
3734        }
3735
3736        // Clean up already done if the process has been re-started.
3737        if (app.pid == pid && app.thread != null &&
3738                app.thread.asBinder() == thread.asBinder()) {
3739            boolean doLowMem = app.instrumentationClass == null;
3740            boolean doOomAdj = doLowMem;
3741            if (!app.killedByAm) {
3742                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3743                        + ") has died.");
3744                mAllowLowerMemLevel = true;
3745            } else {
3746                // Note that we always want to do oom adj to update our state with the
3747                // new number of procs.
3748                mAllowLowerMemLevel = false;
3749                doLowMem = false;
3750            }
3751            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3752            if (DEBUG_CLEANUP) Slog.v(
3753                TAG, "Dying app: " + app + ", pid: " + pid
3754                + ", thread: " + thread.asBinder());
3755            handleAppDiedLocked(app, false, true);
3756
3757            if (doOomAdj) {
3758                updateOomAdjLocked();
3759            }
3760            if (doLowMem) {
3761                doLowMemReportIfNeededLocked(app);
3762            }
3763        } else if (app.pid != pid) {
3764            // A new process has already been started.
3765            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3766                    + ") has died and restarted (pid " + app.pid + ").");
3767            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3768        } else if (DEBUG_PROCESSES) {
3769            Slog.d(TAG, "Received spurious death notification for thread "
3770                    + thread.asBinder());
3771        }
3772    }
3773
3774    /**
3775     * If a stack trace dump file is configured, dump process stack traces.
3776     * @param clearTraces causes the dump file to be erased prior to the new
3777     *    traces being written, if true; when false, the new traces will be
3778     *    appended to any existing file content.
3779     * @param firstPids of dalvik VM processes to dump stack traces for first
3780     * @param lastPids of dalvik VM processes to dump stack traces for last
3781     * @param nativeProcs optional list of native process names to dump stack crawls
3782     * @return file containing stack traces, or null if no dump file is configured
3783     */
3784    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3785            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3786        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3787        if (tracesPath == null || tracesPath.length() == 0) {
3788            return null;
3789        }
3790
3791        File tracesFile = new File(tracesPath);
3792        try {
3793            File tracesDir = tracesFile.getParentFile();
3794            if (!tracesDir.exists()) {
3795                tracesFile.mkdirs();
3796                if (!SELinux.restorecon(tracesDir)) {
3797                    return null;
3798                }
3799            }
3800            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3801
3802            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3803            tracesFile.createNewFile();
3804            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3805        } catch (IOException e) {
3806            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3807            return null;
3808        }
3809
3810        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
3811        return tracesFile;
3812    }
3813
3814    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3815            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3816        // Use a FileObserver to detect when traces finish writing.
3817        // The order of traces is considered important to maintain for legibility.
3818        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3819            @Override
3820            public synchronized void onEvent(int event, String path) { notify(); }
3821        };
3822
3823        try {
3824            observer.startWatching();
3825
3826            // First collect all of the stacks of the most important pids.
3827            if (firstPids != null) {
3828                try {
3829                    int num = firstPids.size();
3830                    for (int i = 0; i < num; i++) {
3831                        synchronized (observer) {
3832                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3833                            observer.wait(200);  // Wait for write-close, give up after 200msec
3834                        }
3835                    }
3836                } catch (InterruptedException e) {
3837                    Log.wtf(TAG, e);
3838                }
3839            }
3840
3841            // Next collect the stacks of the native pids
3842            if (nativeProcs != null) {
3843                int[] pids = Process.getPidsForCommands(nativeProcs);
3844                if (pids != null) {
3845                    for (int pid : pids) {
3846                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3847                    }
3848                }
3849            }
3850
3851            // Lastly, measure CPU usage.
3852            if (processCpuTracker != null) {
3853                processCpuTracker.init();
3854                System.gc();
3855                processCpuTracker.update();
3856                try {
3857                    synchronized (processCpuTracker) {
3858                        processCpuTracker.wait(500); // measure over 1/2 second.
3859                    }
3860                } catch (InterruptedException e) {
3861                }
3862                processCpuTracker.update();
3863
3864                // We'll take the stack crawls of just the top apps using CPU.
3865                final int N = processCpuTracker.countWorkingStats();
3866                int numProcs = 0;
3867                for (int i=0; i<N && numProcs<5; i++) {
3868                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
3869                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3870                        numProcs++;
3871                        try {
3872                            synchronized (observer) {
3873                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3874                                observer.wait(200);  // Wait for write-close, give up after 200msec
3875                            }
3876                        } catch (InterruptedException e) {
3877                            Log.wtf(TAG, e);
3878                        }
3879
3880                    }
3881                }
3882            }
3883        } finally {
3884            observer.stopWatching();
3885        }
3886    }
3887
3888    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3889        if (true || IS_USER_BUILD) {
3890            return;
3891        }
3892        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3893        if (tracesPath == null || tracesPath.length() == 0) {
3894            return;
3895        }
3896
3897        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3898        StrictMode.allowThreadDiskWrites();
3899        try {
3900            final File tracesFile = new File(tracesPath);
3901            final File tracesDir = tracesFile.getParentFile();
3902            final File tracesTmp = new File(tracesDir, "__tmp__");
3903            try {
3904                if (!tracesDir.exists()) {
3905                    tracesFile.mkdirs();
3906                    if (!SELinux.restorecon(tracesDir.getPath())) {
3907                        return;
3908                    }
3909                }
3910                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3911
3912                if (tracesFile.exists()) {
3913                    tracesTmp.delete();
3914                    tracesFile.renameTo(tracesTmp);
3915                }
3916                StringBuilder sb = new StringBuilder();
3917                Time tobj = new Time();
3918                tobj.set(System.currentTimeMillis());
3919                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3920                sb.append(": ");
3921                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3922                sb.append(" since ");
3923                sb.append(msg);
3924                FileOutputStream fos = new FileOutputStream(tracesFile);
3925                fos.write(sb.toString().getBytes());
3926                if (app == null) {
3927                    fos.write("\n*** No application process!".getBytes());
3928                }
3929                fos.close();
3930                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3931            } catch (IOException e) {
3932                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3933                return;
3934            }
3935
3936            if (app != null) {
3937                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3938                firstPids.add(app.pid);
3939                dumpStackTraces(tracesPath, firstPids, null, null, null);
3940            }
3941
3942            File lastTracesFile = null;
3943            File curTracesFile = null;
3944            for (int i=9; i>=0; i--) {
3945                String name = String.format(Locale.US, "slow%02d.txt", i);
3946                curTracesFile = new File(tracesDir, name);
3947                if (curTracesFile.exists()) {
3948                    if (lastTracesFile != null) {
3949                        curTracesFile.renameTo(lastTracesFile);
3950                    } else {
3951                        curTracesFile.delete();
3952                    }
3953                }
3954                lastTracesFile = curTracesFile;
3955            }
3956            tracesFile.renameTo(curTracesFile);
3957            if (tracesTmp.exists()) {
3958                tracesTmp.renameTo(tracesFile);
3959            }
3960        } finally {
3961            StrictMode.setThreadPolicy(oldPolicy);
3962        }
3963    }
3964
3965    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3966            ActivityRecord parent, boolean aboveSystem, final String annotation) {
3967        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3968        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3969
3970        if (mController != null) {
3971            try {
3972                // 0 == continue, -1 = kill process immediately
3973                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3974                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3975            } catch (RemoteException e) {
3976                mController = null;
3977                Watchdog.getInstance().setActivityController(null);
3978            }
3979        }
3980
3981        long anrTime = SystemClock.uptimeMillis();
3982        if (MONITOR_CPU_USAGE) {
3983            updateCpuStatsNow();
3984        }
3985
3986        synchronized (this) {
3987            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3988            if (mShuttingDown) {
3989                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3990                return;
3991            } else if (app.notResponding) {
3992                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3993                return;
3994            } else if (app.crashing) {
3995                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3996                return;
3997            }
3998
3999            // In case we come through here for the same app before completing
4000            // this one, mark as anring now so we will bail out.
4001            app.notResponding = true;
4002
4003            // Log the ANR to the event log.
4004            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4005                    app.processName, app.info.flags, annotation);
4006
4007            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4008            firstPids.add(app.pid);
4009
4010            int parentPid = app.pid;
4011            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4012            if (parentPid != app.pid) firstPids.add(parentPid);
4013
4014            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4015
4016            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4017                ProcessRecord r = mLruProcesses.get(i);
4018                if (r != null && r.thread != null) {
4019                    int pid = r.pid;
4020                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4021                        if (r.persistent) {
4022                            firstPids.add(pid);
4023                        } else {
4024                            lastPids.put(pid, Boolean.TRUE);
4025                        }
4026                    }
4027                }
4028            }
4029        }
4030
4031        // Log the ANR to the main log.
4032        StringBuilder info = new StringBuilder();
4033        info.setLength(0);
4034        info.append("ANR in ").append(app.processName);
4035        if (activity != null && activity.shortComponentName != null) {
4036            info.append(" (").append(activity.shortComponentName).append(")");
4037        }
4038        info.append("\n");
4039        info.append("PID: ").append(app.pid).append("\n");
4040        if (annotation != null) {
4041            info.append("Reason: ").append(annotation).append("\n");
4042        }
4043        if (parent != null && parent != activity) {
4044            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4045        }
4046
4047        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4048
4049        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4050                NATIVE_STACKS_OF_INTEREST);
4051
4052        String cpuInfo = null;
4053        if (MONITOR_CPU_USAGE) {
4054            updateCpuStatsNow();
4055            synchronized (mProcessCpuThread) {
4056                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4057            }
4058            info.append(processCpuTracker.printCurrentLoad());
4059            info.append(cpuInfo);
4060        }
4061
4062        info.append(processCpuTracker.printCurrentState(anrTime));
4063
4064        Slog.e(TAG, info.toString());
4065        if (tracesFile == null) {
4066            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4067            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4068        }
4069
4070        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4071                cpuInfo, tracesFile, null);
4072
4073        if (mController != null) {
4074            try {
4075                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4076                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4077                if (res != 0) {
4078                    if (res < 0 && app.pid != MY_PID) {
4079                        Process.killProcess(app.pid);
4080                    } else {
4081                        synchronized (this) {
4082                            mServices.scheduleServiceTimeoutLocked(app);
4083                        }
4084                    }
4085                    return;
4086                }
4087            } catch (RemoteException e) {
4088                mController = null;
4089                Watchdog.getInstance().setActivityController(null);
4090            }
4091        }
4092
4093        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4094        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4095                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4096
4097        synchronized (this) {
4098            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4099                killUnneededProcessLocked(app, "background ANR");
4100                return;
4101            }
4102
4103            // Set the app's notResponding state, and look up the errorReportReceiver
4104            makeAppNotRespondingLocked(app,
4105                    activity != null ? activity.shortComponentName : null,
4106                    annotation != null ? "ANR " + annotation : "ANR",
4107                    info.toString());
4108
4109            // Bring up the infamous App Not Responding dialog
4110            Message msg = Message.obtain();
4111            HashMap<String, Object> map = new HashMap<String, Object>();
4112            msg.what = SHOW_NOT_RESPONDING_MSG;
4113            msg.obj = map;
4114            msg.arg1 = aboveSystem ? 1 : 0;
4115            map.put("app", app);
4116            if (activity != null) {
4117                map.put("activity", activity);
4118            }
4119
4120            mHandler.sendMessage(msg);
4121        }
4122    }
4123
4124    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4125        if (!mLaunchWarningShown) {
4126            mLaunchWarningShown = true;
4127            mHandler.post(new Runnable() {
4128                @Override
4129                public void run() {
4130                    synchronized (ActivityManagerService.this) {
4131                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4132                        d.show();
4133                        mHandler.postDelayed(new Runnable() {
4134                            @Override
4135                            public void run() {
4136                                synchronized (ActivityManagerService.this) {
4137                                    d.dismiss();
4138                                    mLaunchWarningShown = false;
4139                                }
4140                            }
4141                        }, 4000);
4142                    }
4143                }
4144            });
4145        }
4146    }
4147
4148    @Override
4149    public boolean clearApplicationUserData(final String packageName,
4150            final IPackageDataObserver observer, int userId) {
4151        enforceNotIsolatedCaller("clearApplicationUserData");
4152        int uid = Binder.getCallingUid();
4153        int pid = Binder.getCallingPid();
4154        userId = handleIncomingUser(pid, uid,
4155                userId, false, true, "clearApplicationUserData", null);
4156        long callingId = Binder.clearCallingIdentity();
4157        try {
4158            IPackageManager pm = AppGlobals.getPackageManager();
4159            int pkgUid = -1;
4160            synchronized(this) {
4161                try {
4162                    pkgUid = pm.getPackageUid(packageName, userId);
4163                } catch (RemoteException e) {
4164                }
4165                if (pkgUid == -1) {
4166                    Slog.w(TAG, "Invalid packageName: " + packageName);
4167                    if (observer != null) {
4168                        try {
4169                            observer.onRemoveCompleted(packageName, false);
4170                        } catch (RemoteException e) {
4171                            Slog.i(TAG, "Observer no longer exists.");
4172                        }
4173                    }
4174                    return false;
4175                }
4176                if (uid == pkgUid || checkComponentPermission(
4177                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4178                        pid, uid, -1, true)
4179                        == PackageManager.PERMISSION_GRANTED) {
4180                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4181                } else {
4182                    throw new SecurityException("PID " + pid + " does not have permission "
4183                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4184                                    + " of package " + packageName);
4185                }
4186            }
4187
4188            try {
4189                // Clear application user data
4190                pm.clearApplicationUserData(packageName, observer, userId);
4191
4192                // Remove all permissions granted from/to this package
4193                removeUriPermissionsForPackageLocked(packageName, userId, true);
4194
4195                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4196                        Uri.fromParts("package", packageName, null));
4197                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4198                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4199                        null, null, 0, null, null, null, false, false, userId);
4200            } catch (RemoteException e) {
4201            }
4202        } finally {
4203            Binder.restoreCallingIdentity(callingId);
4204        }
4205        return true;
4206    }
4207
4208    @Override
4209    public void killBackgroundProcesses(final String packageName, int userId) {
4210        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4211                != PackageManager.PERMISSION_GRANTED &&
4212                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4213                        != PackageManager.PERMISSION_GRANTED) {
4214            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4215                    + Binder.getCallingPid()
4216                    + ", uid=" + Binder.getCallingUid()
4217                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4218            Slog.w(TAG, msg);
4219            throw new SecurityException(msg);
4220        }
4221
4222        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4223                userId, true, true, "killBackgroundProcesses", null);
4224        long callingId = Binder.clearCallingIdentity();
4225        try {
4226            IPackageManager pm = AppGlobals.getPackageManager();
4227            synchronized(this) {
4228                int appId = -1;
4229                try {
4230                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4231                } catch (RemoteException e) {
4232                }
4233                if (appId == -1) {
4234                    Slog.w(TAG, "Invalid packageName: " + packageName);
4235                    return;
4236                }
4237                killPackageProcessesLocked(packageName, appId, userId,
4238                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4239            }
4240        } finally {
4241            Binder.restoreCallingIdentity(callingId);
4242        }
4243    }
4244
4245    @Override
4246    public void killAllBackgroundProcesses() {
4247        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4248                != PackageManager.PERMISSION_GRANTED) {
4249            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4250                    + Binder.getCallingPid()
4251                    + ", uid=" + Binder.getCallingUid()
4252                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4253            Slog.w(TAG, msg);
4254            throw new SecurityException(msg);
4255        }
4256
4257        long callingId = Binder.clearCallingIdentity();
4258        try {
4259            synchronized(this) {
4260                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4261                final int NP = mProcessNames.getMap().size();
4262                for (int ip=0; ip<NP; ip++) {
4263                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4264                    final int NA = apps.size();
4265                    for (int ia=0; ia<NA; ia++) {
4266                        ProcessRecord app = apps.valueAt(ia);
4267                        if (app.persistent) {
4268                            // we don't kill persistent processes
4269                            continue;
4270                        }
4271                        if (app.removed) {
4272                            procs.add(app);
4273                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4274                            app.removed = true;
4275                            procs.add(app);
4276                        }
4277                    }
4278                }
4279
4280                int N = procs.size();
4281                for (int i=0; i<N; i++) {
4282                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4283                }
4284                mAllowLowerMemLevel = true;
4285                updateOomAdjLocked();
4286                doLowMemReportIfNeededLocked(null);
4287            }
4288        } finally {
4289            Binder.restoreCallingIdentity(callingId);
4290        }
4291    }
4292
4293    @Override
4294    public void forceStopPackage(final String packageName, int userId) {
4295        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4296                != PackageManager.PERMISSION_GRANTED) {
4297            String msg = "Permission Denial: forceStopPackage() from pid="
4298                    + Binder.getCallingPid()
4299                    + ", uid=" + Binder.getCallingUid()
4300                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4301            Slog.w(TAG, msg);
4302            throw new SecurityException(msg);
4303        }
4304        final int callingPid = Binder.getCallingPid();
4305        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4306                userId, true, true, "forceStopPackage", null);
4307        long callingId = Binder.clearCallingIdentity();
4308        try {
4309            IPackageManager pm = AppGlobals.getPackageManager();
4310            synchronized(this) {
4311                int[] users = userId == UserHandle.USER_ALL
4312                        ? getUsersLocked() : new int[] { userId };
4313                for (int user : users) {
4314                    int pkgUid = -1;
4315                    try {
4316                        pkgUid = pm.getPackageUid(packageName, user);
4317                    } catch (RemoteException e) {
4318                    }
4319                    if (pkgUid == -1) {
4320                        Slog.w(TAG, "Invalid packageName: " + packageName);
4321                        continue;
4322                    }
4323                    try {
4324                        pm.setPackageStoppedState(packageName, true, user);
4325                    } catch (RemoteException e) {
4326                    } catch (IllegalArgumentException e) {
4327                        Slog.w(TAG, "Failed trying to unstop package "
4328                                + packageName + ": " + e);
4329                    }
4330                    if (isUserRunningLocked(user, false)) {
4331                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4332                    }
4333                }
4334            }
4335        } finally {
4336            Binder.restoreCallingIdentity(callingId);
4337        }
4338    }
4339
4340    /*
4341     * The pkg name and app id have to be specified.
4342     */
4343    @Override
4344    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4345        if (pkg == null) {
4346            return;
4347        }
4348        // Make sure the uid is valid.
4349        if (appid < 0) {
4350            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4351            return;
4352        }
4353        int callerUid = Binder.getCallingUid();
4354        // Only the system server can kill an application
4355        if (callerUid == Process.SYSTEM_UID) {
4356            // Post an aysnc message to kill the application
4357            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4358            msg.arg1 = appid;
4359            msg.arg2 = 0;
4360            Bundle bundle = new Bundle();
4361            bundle.putString("pkg", pkg);
4362            bundle.putString("reason", reason);
4363            msg.obj = bundle;
4364            mHandler.sendMessage(msg);
4365        } else {
4366            throw new SecurityException(callerUid + " cannot kill pkg: " +
4367                    pkg);
4368        }
4369    }
4370
4371    @Override
4372    public void closeSystemDialogs(String reason) {
4373        enforceNotIsolatedCaller("closeSystemDialogs");
4374
4375        final int pid = Binder.getCallingPid();
4376        final int uid = Binder.getCallingUid();
4377        final long origId = Binder.clearCallingIdentity();
4378        try {
4379            synchronized (this) {
4380                // Only allow this from foreground processes, so that background
4381                // applications can't abuse it to prevent system UI from being shown.
4382                if (uid >= Process.FIRST_APPLICATION_UID) {
4383                    ProcessRecord proc;
4384                    synchronized (mPidsSelfLocked) {
4385                        proc = mPidsSelfLocked.get(pid);
4386                    }
4387                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4388                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4389                                + " from background process " + proc);
4390                        return;
4391                    }
4392                }
4393                closeSystemDialogsLocked(reason);
4394            }
4395        } finally {
4396            Binder.restoreCallingIdentity(origId);
4397        }
4398    }
4399
4400    void closeSystemDialogsLocked(String reason) {
4401        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4402        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4403                | Intent.FLAG_RECEIVER_FOREGROUND);
4404        if (reason != null) {
4405            intent.putExtra("reason", reason);
4406        }
4407        mWindowManager.closeSystemDialogs(reason);
4408
4409        mStackSupervisor.closeSystemDialogsLocked();
4410
4411        broadcastIntentLocked(null, null, intent, null,
4412                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4413                Process.SYSTEM_UID, UserHandle.USER_ALL);
4414    }
4415
4416    @Override
4417    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4418        enforceNotIsolatedCaller("getProcessMemoryInfo");
4419        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4420        for (int i=pids.length-1; i>=0; i--) {
4421            ProcessRecord proc;
4422            int oomAdj;
4423            synchronized (this) {
4424                synchronized (mPidsSelfLocked) {
4425                    proc = mPidsSelfLocked.get(pids[i]);
4426                    oomAdj = proc != null ? proc.setAdj : 0;
4427                }
4428            }
4429            infos[i] = new Debug.MemoryInfo();
4430            Debug.getMemoryInfo(pids[i], infos[i]);
4431            if (proc != null) {
4432                synchronized (this) {
4433                    if (proc.thread != null && proc.setAdj == oomAdj) {
4434                        // Record this for posterity if the process has been stable.
4435                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4436                                infos[i].getTotalUss(), false, proc.pkgList);
4437                    }
4438                }
4439            }
4440        }
4441        return infos;
4442    }
4443
4444    @Override
4445    public long[] getProcessPss(int[] pids) {
4446        enforceNotIsolatedCaller("getProcessPss");
4447        long[] pss = new long[pids.length];
4448        for (int i=pids.length-1; i>=0; i--) {
4449            ProcessRecord proc;
4450            int oomAdj;
4451            synchronized (this) {
4452                synchronized (mPidsSelfLocked) {
4453                    proc = mPidsSelfLocked.get(pids[i]);
4454                    oomAdj = proc != null ? proc.setAdj : 0;
4455                }
4456            }
4457            long[] tmpUss = new long[1];
4458            pss[i] = Debug.getPss(pids[i], tmpUss);
4459            if (proc != null) {
4460                synchronized (this) {
4461                    if (proc.thread != null && proc.setAdj == oomAdj) {
4462                        // Record this for posterity if the process has been stable.
4463                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4464                    }
4465                }
4466            }
4467        }
4468        return pss;
4469    }
4470
4471    @Override
4472    public void killApplicationProcess(String processName, int uid) {
4473        if (processName == null) {
4474            return;
4475        }
4476
4477        int callerUid = Binder.getCallingUid();
4478        // Only the system server can kill an application
4479        if (callerUid == Process.SYSTEM_UID) {
4480            synchronized (this) {
4481                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4482                if (app != null && app.thread != null) {
4483                    try {
4484                        app.thread.scheduleSuicide();
4485                    } catch (RemoteException e) {
4486                        // If the other end already died, then our work here is done.
4487                    }
4488                } else {
4489                    Slog.w(TAG, "Process/uid not found attempting kill of "
4490                            + processName + " / " + uid);
4491                }
4492            }
4493        } else {
4494            throw new SecurityException(callerUid + " cannot kill app process: " +
4495                    processName);
4496        }
4497    }
4498
4499    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4500        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4501                false, true, false, false, UserHandle.getUserId(uid), reason);
4502        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4503                Uri.fromParts("package", packageName, null));
4504        if (!mProcessesReady) {
4505            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4506                    | Intent.FLAG_RECEIVER_FOREGROUND);
4507        }
4508        intent.putExtra(Intent.EXTRA_UID, uid);
4509        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4510        broadcastIntentLocked(null, null, intent,
4511                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4512                false, false,
4513                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4514    }
4515
4516    private void forceStopUserLocked(int userId, String reason) {
4517        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4518        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4519        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4520                | Intent.FLAG_RECEIVER_FOREGROUND);
4521        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4522        broadcastIntentLocked(null, null, intent,
4523                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4524                false, false,
4525                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4526    }
4527
4528    private final boolean killPackageProcessesLocked(String packageName, int appId,
4529            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4530            boolean doit, boolean evenPersistent, String reason) {
4531        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4532
4533        // Remove all processes this package may have touched: all with the
4534        // same UID (except for the system or root user), and all whose name
4535        // matches the package name.
4536        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4537        final int NP = mProcessNames.getMap().size();
4538        for (int ip=0; ip<NP; ip++) {
4539            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4540            final int NA = apps.size();
4541            for (int ia=0; ia<NA; ia++) {
4542                ProcessRecord app = apps.valueAt(ia);
4543                if (app.persistent && !evenPersistent) {
4544                    // we don't kill persistent processes
4545                    continue;
4546                }
4547                if (app.removed) {
4548                    if (doit) {
4549                        procs.add(app);
4550                    }
4551                    continue;
4552                }
4553
4554                // Skip process if it doesn't meet our oom adj requirement.
4555                if (app.setAdj < minOomAdj) {
4556                    continue;
4557                }
4558
4559                // If no package is specified, we call all processes under the
4560                // give user id.
4561                if (packageName == null) {
4562                    if (app.userId != userId) {
4563                        continue;
4564                    }
4565                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4566                        continue;
4567                    }
4568                // Package has been specified, we want to hit all processes
4569                // that match it.  We need to qualify this by the processes
4570                // that are running under the specified app and user ID.
4571                } else {
4572                    if (UserHandle.getAppId(app.uid) != appId) {
4573                        continue;
4574                    }
4575                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4576                        continue;
4577                    }
4578                    if (!app.pkgList.containsKey(packageName)) {
4579                        continue;
4580                    }
4581                }
4582
4583                // Process has passed all conditions, kill it!
4584                if (!doit) {
4585                    return true;
4586                }
4587                app.removed = true;
4588                procs.add(app);
4589            }
4590        }
4591
4592        int N = procs.size();
4593        for (int i=0; i<N; i++) {
4594            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4595        }
4596        updateOomAdjLocked();
4597        return N > 0;
4598    }
4599
4600    private final boolean forceStopPackageLocked(String name, int appId,
4601            boolean callerWillRestart, boolean purgeCache, boolean doit,
4602            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4603        int i;
4604        int N;
4605
4606        if (userId == UserHandle.USER_ALL && name == null) {
4607            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4608        }
4609
4610        if (appId < 0 && name != null) {
4611            try {
4612                appId = UserHandle.getAppId(
4613                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4614            } catch (RemoteException e) {
4615            }
4616        }
4617
4618        if (doit) {
4619            if (name != null) {
4620                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4621                        + " user=" + userId + ": " + reason);
4622            } else {
4623                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4624            }
4625
4626            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4627            for (int ip=pmap.size()-1; ip>=0; ip--) {
4628                SparseArray<Long> ba = pmap.valueAt(ip);
4629                for (i=ba.size()-1; i>=0; i--) {
4630                    boolean remove = false;
4631                    final int entUid = ba.keyAt(i);
4632                    if (name != null) {
4633                        if (userId == UserHandle.USER_ALL) {
4634                            if (UserHandle.getAppId(entUid) == appId) {
4635                                remove = true;
4636                            }
4637                        } else {
4638                            if (entUid == UserHandle.getUid(userId, appId)) {
4639                                remove = true;
4640                            }
4641                        }
4642                    } else if (UserHandle.getUserId(entUid) == userId) {
4643                        remove = true;
4644                    }
4645                    if (remove) {
4646                        ba.removeAt(i);
4647                    }
4648                }
4649                if (ba.size() == 0) {
4650                    pmap.removeAt(ip);
4651                }
4652            }
4653        }
4654
4655        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4656                -100, callerWillRestart, true, doit, evenPersistent,
4657                name == null ? ("stop user " + userId) : ("stop " + name));
4658
4659        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4660            if (!doit) {
4661                return true;
4662            }
4663            didSomething = true;
4664        }
4665
4666        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4667            if (!doit) {
4668                return true;
4669            }
4670            didSomething = true;
4671        }
4672
4673        if (name == null) {
4674            // Remove all sticky broadcasts from this user.
4675            mStickyBroadcasts.remove(userId);
4676        }
4677
4678        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4679        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4680                userId, providers)) {
4681            if (!doit) {
4682                return true;
4683            }
4684            didSomething = true;
4685        }
4686        N = providers.size();
4687        for (i=0; i<N; i++) {
4688            removeDyingProviderLocked(null, providers.get(i), true);
4689        }
4690
4691        // Remove transient permissions granted from/to this package/user
4692        removeUriPermissionsForPackageLocked(name, userId, false);
4693
4694        if (name == null || uninstalling) {
4695            // Remove pending intents.  For now we only do this when force
4696            // stopping users, because we have some problems when doing this
4697            // for packages -- app widgets are not currently cleaned up for
4698            // such packages, so they can be left with bad pending intents.
4699            if (mIntentSenderRecords.size() > 0) {
4700                Iterator<WeakReference<PendingIntentRecord>> it
4701                        = mIntentSenderRecords.values().iterator();
4702                while (it.hasNext()) {
4703                    WeakReference<PendingIntentRecord> wpir = it.next();
4704                    if (wpir == null) {
4705                        it.remove();
4706                        continue;
4707                    }
4708                    PendingIntentRecord pir = wpir.get();
4709                    if (pir == null) {
4710                        it.remove();
4711                        continue;
4712                    }
4713                    if (name == null) {
4714                        // Stopping user, remove all objects for the user.
4715                        if (pir.key.userId != userId) {
4716                            // Not the same user, skip it.
4717                            continue;
4718                        }
4719                    } else {
4720                        if (UserHandle.getAppId(pir.uid) != appId) {
4721                            // Different app id, skip it.
4722                            continue;
4723                        }
4724                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4725                            // Different user, skip it.
4726                            continue;
4727                        }
4728                        if (!pir.key.packageName.equals(name)) {
4729                            // Different package, skip it.
4730                            continue;
4731                        }
4732                    }
4733                    if (!doit) {
4734                        return true;
4735                    }
4736                    didSomething = true;
4737                    it.remove();
4738                    pir.canceled = true;
4739                    if (pir.key.activity != null) {
4740                        pir.key.activity.pendingResults.remove(pir.ref);
4741                    }
4742                }
4743            }
4744        }
4745
4746        if (doit) {
4747            if (purgeCache && name != null) {
4748                AttributeCache ac = AttributeCache.instance();
4749                if (ac != null) {
4750                    ac.removePackage(name);
4751                }
4752            }
4753            if (mBooted) {
4754                mStackSupervisor.resumeTopActivitiesLocked();
4755                mStackSupervisor.scheduleIdleLocked();
4756            }
4757        }
4758
4759        return didSomething;
4760    }
4761
4762    private final boolean removeProcessLocked(ProcessRecord app,
4763            boolean callerWillRestart, boolean allowRestart, String reason) {
4764        final String name = app.processName;
4765        final int uid = app.uid;
4766        if (DEBUG_PROCESSES) Slog.d(
4767            TAG, "Force removing proc " + app.toShortString() + " (" + name
4768            + "/" + uid + ")");
4769
4770        mProcessNames.remove(name, uid);
4771        mIsolatedProcesses.remove(app.uid);
4772        if (mHeavyWeightProcess == app) {
4773            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4774                    mHeavyWeightProcess.userId, 0));
4775            mHeavyWeightProcess = null;
4776        }
4777        boolean needRestart = false;
4778        if (app.pid > 0 && app.pid != MY_PID) {
4779            int pid = app.pid;
4780            synchronized (mPidsSelfLocked) {
4781                mPidsSelfLocked.remove(pid);
4782                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4783            }
4784            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
4785                    app.processName, app.info.uid);
4786            if (app.isolated) {
4787                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
4788            }
4789            killUnneededProcessLocked(app, reason);
4790            handleAppDiedLocked(app, true, allowRestart);
4791            removeLruProcessLocked(app);
4792
4793            if (app.persistent && !app.isolated) {
4794                if (!callerWillRestart) {
4795                    addAppLocked(app.info, false);
4796                } else {
4797                    needRestart = true;
4798                }
4799            }
4800        } else {
4801            mRemovedProcesses.add(app);
4802        }
4803
4804        return needRestart;
4805    }
4806
4807    private final void processStartTimedOutLocked(ProcessRecord app) {
4808        final int pid = app.pid;
4809        boolean gone = false;
4810        synchronized (mPidsSelfLocked) {
4811            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4812            if (knownApp != null && knownApp.thread == null) {
4813                mPidsSelfLocked.remove(pid);
4814                gone = true;
4815            }
4816        }
4817
4818        if (gone) {
4819            Slog.w(TAG, "Process " + app + " failed to attach");
4820            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
4821                    pid, app.uid, app.processName);
4822            mProcessNames.remove(app.processName, app.uid);
4823            mIsolatedProcesses.remove(app.uid);
4824            if (mHeavyWeightProcess == app) {
4825                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4826                        mHeavyWeightProcess.userId, 0));
4827                mHeavyWeightProcess = null;
4828            }
4829            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
4830                    app.processName, app.info.uid);
4831            if (app.isolated) {
4832                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
4833            }
4834            // Take care of any launching providers waiting for this process.
4835            checkAppInLaunchingProvidersLocked(app, true);
4836            // Take care of any services that are waiting for the process.
4837            mServices.processStartTimedOutLocked(app);
4838            killUnneededProcessLocked(app, "start timeout");
4839            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4840                Slog.w(TAG, "Unattached app died before backup, skipping");
4841                try {
4842                    IBackupManager bm = IBackupManager.Stub.asInterface(
4843                            ServiceManager.getService(Context.BACKUP_SERVICE));
4844                    bm.agentDisconnected(app.info.packageName);
4845                } catch (RemoteException e) {
4846                    // Can't happen; the backup manager is local
4847                }
4848            }
4849            if (isPendingBroadcastProcessLocked(pid)) {
4850                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4851                skipPendingBroadcastLocked(pid);
4852            }
4853        } else {
4854            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4855        }
4856    }
4857
4858    private final boolean attachApplicationLocked(IApplicationThread thread,
4859            int pid) {
4860
4861        // Find the application record that is being attached...  either via
4862        // the pid if we are running in multiple processes, or just pull the
4863        // next app record if we are emulating process with anonymous threads.
4864        ProcessRecord app;
4865        if (pid != MY_PID && pid >= 0) {
4866            synchronized (mPidsSelfLocked) {
4867                app = mPidsSelfLocked.get(pid);
4868            }
4869        } else {
4870            app = null;
4871        }
4872
4873        if (app == null) {
4874            Slog.w(TAG, "No pending application record for pid " + pid
4875                    + " (IApplicationThread " + thread + "); dropping process");
4876            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4877            if (pid > 0 && pid != MY_PID) {
4878                Process.killProcessQuiet(pid);
4879            } else {
4880                try {
4881                    thread.scheduleExit();
4882                } catch (Exception e) {
4883                    // Ignore exceptions.
4884                }
4885            }
4886            return false;
4887        }
4888
4889        // If this application record is still attached to a previous
4890        // process, clean it up now.
4891        if (app.thread != null) {
4892            handleAppDiedLocked(app, true, true);
4893        }
4894
4895        // Tell the process all about itself.
4896
4897        if (localLOGV) Slog.v(
4898                TAG, "Binding process pid " + pid + " to record " + app);
4899
4900        final String processName = app.processName;
4901        try {
4902            AppDeathRecipient adr = new AppDeathRecipient(
4903                    app, pid, thread);
4904            thread.asBinder().linkToDeath(adr, 0);
4905            app.deathRecipient = adr;
4906        } catch (RemoteException e) {
4907            app.resetPackageList(mProcessStats);
4908            startProcessLocked(app, "link fail", processName);
4909            return false;
4910        }
4911
4912        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
4913
4914        app.makeActive(thread, mProcessStats);
4915        app.curAdj = app.setAdj = -100;
4916        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
4917        app.forcingToForeground = null;
4918        updateProcessForegroundLocked(app, false, false);
4919        app.hasShownUi = false;
4920        app.debugging = false;
4921        app.cached = false;
4922
4923        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4924
4925        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4926        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4927
4928        if (!normalMode) {
4929            Slog.i(TAG, "Launching preboot mode app: " + app);
4930        }
4931
4932        if (localLOGV) Slog.v(
4933            TAG, "New app record " + app
4934            + " thread=" + thread.asBinder() + " pid=" + pid);
4935        try {
4936            int testMode = IApplicationThread.DEBUG_OFF;
4937            if (mDebugApp != null && mDebugApp.equals(processName)) {
4938                testMode = mWaitForDebugger
4939                    ? IApplicationThread.DEBUG_WAIT
4940                    : IApplicationThread.DEBUG_ON;
4941                app.debugging = true;
4942                if (mDebugTransient) {
4943                    mDebugApp = mOrigDebugApp;
4944                    mWaitForDebugger = mOrigWaitForDebugger;
4945                }
4946            }
4947            String profileFile = app.instrumentationProfileFile;
4948            ParcelFileDescriptor profileFd = null;
4949            boolean profileAutoStop = false;
4950            if (mProfileApp != null && mProfileApp.equals(processName)) {
4951                mProfileProc = app;
4952                profileFile = mProfileFile;
4953                profileFd = mProfileFd;
4954                profileAutoStop = mAutoStopProfiler;
4955            }
4956            boolean enableOpenGlTrace = false;
4957            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4958                enableOpenGlTrace = true;
4959                mOpenGlTraceApp = null;
4960            }
4961
4962            // If the app is being launched for restore or full backup, set it up specially
4963            boolean isRestrictedBackupMode = false;
4964            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4965                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4966                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4967                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4968            }
4969
4970            ensurePackageDexOpt(app.instrumentationInfo != null
4971                    ? app.instrumentationInfo.packageName
4972                    : app.info.packageName);
4973            if (app.instrumentationClass != null) {
4974                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4975            }
4976            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4977                    + processName + " with config " + mConfiguration);
4978            ApplicationInfo appInfo = app.instrumentationInfo != null
4979                    ? app.instrumentationInfo : app.info;
4980            app.compat = compatibilityInfoForPackageLocked(appInfo);
4981            if (profileFd != null) {
4982                profileFd = profileFd.dup();
4983            }
4984            thread.bindApplication(processName, appInfo, providers,
4985                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4986                    app.instrumentationArguments, app.instrumentationWatcher,
4987                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
4988                    isRestrictedBackupMode || !normalMode, app.persistent,
4989                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4990                    mCoreSettingsObserver.getCoreSettingsLocked());
4991            updateLruProcessLocked(app, false, null);
4992            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4993        } catch (Exception e) {
4994            // todo: Yikes!  What should we do?  For now we will try to
4995            // start another process, but that could easily get us in
4996            // an infinite loop of restarting processes...
4997            Slog.w(TAG, "Exception thrown during bind!", e);
4998
4999            app.resetPackageList(mProcessStats);
5000            app.unlinkDeathRecipient();
5001            startProcessLocked(app, "bind fail", processName);
5002            return false;
5003        }
5004
5005        // Remove this record from the list of starting applications.
5006        mPersistentStartingProcesses.remove(app);
5007        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5008                "Attach application locked removing on hold: " + app);
5009        mProcessesOnHold.remove(app);
5010
5011        boolean badApp = false;
5012        boolean didSomething = false;
5013
5014        // See if the top visible activity is waiting to run in this process...
5015        if (normalMode) {
5016            try {
5017                if (mStackSupervisor.attachApplicationLocked(app)) {
5018                    didSomething = true;
5019                }
5020            } catch (Exception e) {
5021                badApp = true;
5022            }
5023        }
5024
5025        // Find any services that should be running in this process...
5026        if (!badApp) {
5027            try {
5028                didSomething |= mServices.attachApplicationLocked(app, processName);
5029            } catch (Exception e) {
5030                badApp = true;
5031            }
5032        }
5033
5034        // Check if a next-broadcast receiver is in this process...
5035        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5036            try {
5037                didSomething |= sendPendingBroadcastsLocked(app);
5038            } catch (Exception e) {
5039                // If the app died trying to launch the receiver we declare it 'bad'
5040                badApp = true;
5041            }
5042        }
5043
5044        // Check whether the next backup agent is in this process...
5045        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5046            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5047            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5048            try {
5049                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5050                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5051                        mBackupTarget.backupMode);
5052            } catch (Exception e) {
5053                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5054                e.printStackTrace();
5055            }
5056        }
5057
5058        if (badApp) {
5059            // todo: Also need to kill application to deal with all
5060            // kinds of exceptions.
5061            handleAppDiedLocked(app, false, true);
5062            return false;
5063        }
5064
5065        if (!didSomething) {
5066            updateOomAdjLocked();
5067        }
5068
5069        return true;
5070    }
5071
5072    @Override
5073    public final void attachApplication(IApplicationThread thread) {
5074        synchronized (this) {
5075            int callingPid = Binder.getCallingPid();
5076            final long origId = Binder.clearCallingIdentity();
5077            attachApplicationLocked(thread, callingPid);
5078            Binder.restoreCallingIdentity(origId);
5079        }
5080    }
5081
5082    @Override
5083    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5084        final long origId = Binder.clearCallingIdentity();
5085        synchronized (this) {
5086            ActivityStack stack = ActivityRecord.getStackLocked(token);
5087            if (stack != null) {
5088                ActivityRecord r =
5089                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5090                if (stopProfiling) {
5091                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5092                        try {
5093                            mProfileFd.close();
5094                        } catch (IOException e) {
5095                        }
5096                        clearProfilerLocked();
5097                    }
5098                }
5099            }
5100        }
5101        Binder.restoreCallingIdentity(origId);
5102    }
5103
5104    void enableScreenAfterBoot() {
5105        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5106                SystemClock.uptimeMillis());
5107        mWindowManager.enableScreenAfterBoot();
5108
5109        synchronized (this) {
5110            updateEventDispatchingLocked();
5111        }
5112    }
5113
5114    @Override
5115    public void showBootMessage(final CharSequence msg, final boolean always) {
5116        enforceNotIsolatedCaller("showBootMessage");
5117        mWindowManager.showBootMessage(msg, always);
5118    }
5119
5120    @Override
5121    public void dismissKeyguardOnNextActivity() {
5122        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5123        final long token = Binder.clearCallingIdentity();
5124        try {
5125            synchronized (this) {
5126                if (DEBUG_LOCKSCREEN) logLockScreen("");
5127                if (mLockScreenShown) {
5128                    mLockScreenShown = false;
5129                    comeOutOfSleepIfNeededLocked();
5130                }
5131                mStackSupervisor.setDismissKeyguard(true);
5132            }
5133        } finally {
5134            Binder.restoreCallingIdentity(token);
5135        }
5136    }
5137
5138    final void finishBooting() {
5139        IntentFilter pkgFilter = new IntentFilter();
5140        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
5141        pkgFilter.addDataScheme("package");
5142        mContext.registerReceiver(new BroadcastReceiver() {
5143            @Override
5144            public void onReceive(Context context, Intent intent) {
5145                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
5146                if (pkgs != null) {
5147                    for (String pkg : pkgs) {
5148                        synchronized (ActivityManagerService.this) {
5149                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
5150                                    "finished booting")) {
5151                                setResultCode(Activity.RESULT_OK);
5152                                return;
5153                            }
5154                        }
5155                    }
5156                }
5157            }
5158        }, pkgFilter);
5159
5160        synchronized (this) {
5161            // Ensure that any processes we had put on hold are now started
5162            // up.
5163            final int NP = mProcessesOnHold.size();
5164            if (NP > 0) {
5165                ArrayList<ProcessRecord> procs =
5166                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5167                for (int ip=0; ip<NP; ip++) {
5168                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5169                            + procs.get(ip));
5170                    startProcessLocked(procs.get(ip), "on-hold", null);
5171                }
5172            }
5173
5174            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5175                // Start looking for apps that are abusing wake locks.
5176                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5177                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5178                // Tell anyone interested that we are done booting!
5179                SystemProperties.set("sys.boot_completed", "1");
5180                SystemProperties.set("dev.bootcomplete", "1");
5181                for (int i=0; i<mStartedUsers.size(); i++) {
5182                    UserStartedState uss = mStartedUsers.valueAt(i);
5183                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5184                        uss.mState = UserStartedState.STATE_RUNNING;
5185                        final int userId = mStartedUsers.keyAt(i);
5186                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5187                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5188                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5189                        broadcastIntentLocked(null, null, intent, null,
5190                                new IIntentReceiver.Stub() {
5191                                    @Override
5192                                    public void performReceive(Intent intent, int resultCode,
5193                                            String data, Bundle extras, boolean ordered,
5194                                            boolean sticky, int sendingUser) {
5195                                        synchronized (ActivityManagerService.this) {
5196                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5197                                                    true, false);
5198                                        }
5199                                    }
5200                                },
5201                                0, null, null,
5202                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5203                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5204                                userId);
5205                    }
5206                }
5207                scheduleStartRelatedUsersLocked();
5208            }
5209        }
5210    }
5211
5212    final void ensureBootCompleted() {
5213        boolean booting;
5214        boolean enableScreen;
5215        synchronized (this) {
5216            booting = mBooting;
5217            mBooting = false;
5218            enableScreen = !mBooted;
5219            mBooted = true;
5220        }
5221
5222        if (booting) {
5223            finishBooting();
5224        }
5225
5226        if (enableScreen) {
5227            enableScreenAfterBoot();
5228        }
5229    }
5230
5231    @Override
5232    public final void activityResumed(IBinder token) {
5233        final long origId = Binder.clearCallingIdentity();
5234        synchronized(this) {
5235            ActivityStack stack = ActivityRecord.getStackLocked(token);
5236            if (stack != null) {
5237                ActivityRecord.activityResumedLocked(token);
5238            }
5239        }
5240        Binder.restoreCallingIdentity(origId);
5241    }
5242
5243    @Override
5244    public final void activityPaused(IBinder token) {
5245        final long origId = Binder.clearCallingIdentity();
5246        synchronized(this) {
5247            ActivityStack stack = ActivityRecord.getStackLocked(token);
5248            if (stack != null) {
5249                stack.activityPausedLocked(token, false);
5250            }
5251        }
5252        Binder.restoreCallingIdentity(origId);
5253    }
5254
5255    @Override
5256    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
5257            CharSequence description) {
5258        if (localLOGV) Slog.v(
5259            TAG, "Activity stopped: token=" + token);
5260
5261        // Refuse possible leaked file descriptors
5262        if (icicle != null && icicle.hasFileDescriptors()) {
5263            throw new IllegalArgumentException("File descriptors passed in Bundle");
5264        }
5265
5266        ActivityRecord r = null;
5267
5268        final long origId = Binder.clearCallingIdentity();
5269
5270        synchronized (this) {
5271            r = ActivityRecord.isInStackLocked(token);
5272            if (r != null) {
5273                r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description);
5274            }
5275        }
5276
5277        if (r != null) {
5278            sendPendingThumbnail(r, null, null, null, false);
5279        }
5280
5281        trimApplications();
5282
5283        Binder.restoreCallingIdentity(origId);
5284    }
5285
5286    @Override
5287    public final void activityDestroyed(IBinder token) {
5288        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5289        synchronized (this) {
5290            ActivityStack stack = ActivityRecord.getStackLocked(token);
5291            if (stack != null) {
5292                stack.activityDestroyedLocked(token);
5293            }
5294        }
5295    }
5296
5297    @Override
5298    public String getCallingPackage(IBinder token) {
5299        synchronized (this) {
5300            ActivityRecord r = getCallingRecordLocked(token);
5301            return r != null ? r.info.packageName : null;
5302        }
5303    }
5304
5305    @Override
5306    public ComponentName getCallingActivity(IBinder token) {
5307        synchronized (this) {
5308            ActivityRecord r = getCallingRecordLocked(token);
5309            return r != null ? r.intent.getComponent() : null;
5310        }
5311    }
5312
5313    private ActivityRecord getCallingRecordLocked(IBinder token) {
5314        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5315        if (r == null) {
5316            return null;
5317        }
5318        return r.resultTo;
5319    }
5320
5321    @Override
5322    public ComponentName getActivityClassForToken(IBinder token) {
5323        synchronized(this) {
5324            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5325            if (r == null) {
5326                return null;
5327            }
5328            return r.intent.getComponent();
5329        }
5330    }
5331
5332    @Override
5333    public String getPackageForToken(IBinder token) {
5334        synchronized(this) {
5335            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5336            if (r == null) {
5337                return null;
5338            }
5339            return r.packageName;
5340        }
5341    }
5342
5343    @Override
5344    public IIntentSender getIntentSender(int type,
5345            String packageName, IBinder token, String resultWho,
5346            int requestCode, Intent[] intents, String[] resolvedTypes,
5347            int flags, Bundle options, int userId) {
5348        enforceNotIsolatedCaller("getIntentSender");
5349        // Refuse possible leaked file descriptors
5350        if (intents != null) {
5351            if (intents.length < 1) {
5352                throw new IllegalArgumentException("Intents array length must be >= 1");
5353            }
5354            for (int i=0; i<intents.length; i++) {
5355                Intent intent = intents[i];
5356                if (intent != null) {
5357                    if (intent.hasFileDescriptors()) {
5358                        throw new IllegalArgumentException("File descriptors passed in Intent");
5359                    }
5360                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5361                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5362                        throw new IllegalArgumentException(
5363                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5364                    }
5365                    intents[i] = new Intent(intent);
5366                }
5367            }
5368            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5369                throw new IllegalArgumentException(
5370                        "Intent array length does not match resolvedTypes length");
5371            }
5372        }
5373        if (options != null) {
5374            if (options.hasFileDescriptors()) {
5375                throw new IllegalArgumentException("File descriptors passed in options");
5376            }
5377        }
5378
5379        synchronized(this) {
5380            int callingUid = Binder.getCallingUid();
5381            int origUserId = userId;
5382            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5383                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5384                    "getIntentSender", null);
5385            if (origUserId == UserHandle.USER_CURRENT) {
5386                // We don't want to evaluate this until the pending intent is
5387                // actually executed.  However, we do want to always do the
5388                // security checking for it above.
5389                userId = UserHandle.USER_CURRENT;
5390            }
5391            try {
5392                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5393                    int uid = AppGlobals.getPackageManager()
5394                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5395                    if (!UserHandle.isSameApp(callingUid, uid)) {
5396                        String msg = "Permission Denial: getIntentSender() from pid="
5397                            + Binder.getCallingPid()
5398                            + ", uid=" + Binder.getCallingUid()
5399                            + ", (need uid=" + uid + ")"
5400                            + " is not allowed to send as package " + packageName;
5401                        Slog.w(TAG, msg);
5402                        throw new SecurityException(msg);
5403                    }
5404                }
5405
5406                return getIntentSenderLocked(type, packageName, callingUid, userId,
5407                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5408
5409            } catch (RemoteException e) {
5410                throw new SecurityException(e);
5411            }
5412        }
5413    }
5414
5415    IIntentSender getIntentSenderLocked(int type, String packageName,
5416            int callingUid, int userId, IBinder token, String resultWho,
5417            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5418            Bundle options) {
5419        if (DEBUG_MU)
5420            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5421        ActivityRecord activity = null;
5422        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5423            activity = ActivityRecord.isInStackLocked(token);
5424            if (activity == null) {
5425                return null;
5426            }
5427            if (activity.finishing) {
5428                return null;
5429            }
5430        }
5431
5432        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5433        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5434        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5435        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5436                |PendingIntent.FLAG_UPDATE_CURRENT);
5437
5438        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5439                type, packageName, activity, resultWho,
5440                requestCode, intents, resolvedTypes, flags, options, userId);
5441        WeakReference<PendingIntentRecord> ref;
5442        ref = mIntentSenderRecords.get(key);
5443        PendingIntentRecord rec = ref != null ? ref.get() : null;
5444        if (rec != null) {
5445            if (!cancelCurrent) {
5446                if (updateCurrent) {
5447                    if (rec.key.requestIntent != null) {
5448                        rec.key.requestIntent.replaceExtras(intents != null ?
5449                                intents[intents.length - 1] : null);
5450                    }
5451                    if (intents != null) {
5452                        intents[intents.length-1] = rec.key.requestIntent;
5453                        rec.key.allIntents = intents;
5454                        rec.key.allResolvedTypes = resolvedTypes;
5455                    } else {
5456                        rec.key.allIntents = null;
5457                        rec.key.allResolvedTypes = null;
5458                    }
5459                }
5460                return rec;
5461            }
5462            rec.canceled = true;
5463            mIntentSenderRecords.remove(key);
5464        }
5465        if (noCreate) {
5466            return rec;
5467        }
5468        rec = new PendingIntentRecord(this, key, callingUid);
5469        mIntentSenderRecords.put(key, rec.ref);
5470        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5471            if (activity.pendingResults == null) {
5472                activity.pendingResults
5473                        = new HashSet<WeakReference<PendingIntentRecord>>();
5474            }
5475            activity.pendingResults.add(rec.ref);
5476        }
5477        return rec;
5478    }
5479
5480    @Override
5481    public void cancelIntentSender(IIntentSender sender) {
5482        if (!(sender instanceof PendingIntentRecord)) {
5483            return;
5484        }
5485        synchronized(this) {
5486            PendingIntentRecord rec = (PendingIntentRecord)sender;
5487            try {
5488                int uid = AppGlobals.getPackageManager()
5489                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5490                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5491                    String msg = "Permission Denial: cancelIntentSender() from pid="
5492                        + Binder.getCallingPid()
5493                        + ", uid=" + Binder.getCallingUid()
5494                        + " is not allowed to cancel packges "
5495                        + rec.key.packageName;
5496                    Slog.w(TAG, msg);
5497                    throw new SecurityException(msg);
5498                }
5499            } catch (RemoteException e) {
5500                throw new SecurityException(e);
5501            }
5502            cancelIntentSenderLocked(rec, true);
5503        }
5504    }
5505
5506    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5507        rec.canceled = true;
5508        mIntentSenderRecords.remove(rec.key);
5509        if (cleanActivity && rec.key.activity != null) {
5510            rec.key.activity.pendingResults.remove(rec.ref);
5511        }
5512    }
5513
5514    @Override
5515    public String getPackageForIntentSender(IIntentSender pendingResult) {
5516        if (!(pendingResult instanceof PendingIntentRecord)) {
5517            return null;
5518        }
5519        try {
5520            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5521            return res.key.packageName;
5522        } catch (ClassCastException e) {
5523        }
5524        return null;
5525    }
5526
5527    @Override
5528    public int getUidForIntentSender(IIntentSender sender) {
5529        if (sender instanceof PendingIntentRecord) {
5530            try {
5531                PendingIntentRecord res = (PendingIntentRecord)sender;
5532                return res.uid;
5533            } catch (ClassCastException e) {
5534            }
5535        }
5536        return -1;
5537    }
5538
5539    @Override
5540    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5541        if (!(pendingResult instanceof PendingIntentRecord)) {
5542            return false;
5543        }
5544        try {
5545            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5546            if (res.key.allIntents == null) {
5547                return false;
5548            }
5549            for (int i=0; i<res.key.allIntents.length; i++) {
5550                Intent intent = res.key.allIntents[i];
5551                if (intent.getPackage() != null && intent.getComponent() != null) {
5552                    return false;
5553                }
5554            }
5555            return true;
5556        } catch (ClassCastException e) {
5557        }
5558        return false;
5559    }
5560
5561    @Override
5562    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5563        if (!(pendingResult instanceof PendingIntentRecord)) {
5564            return false;
5565        }
5566        try {
5567            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5568            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5569                return true;
5570            }
5571            return false;
5572        } catch (ClassCastException e) {
5573        }
5574        return false;
5575    }
5576
5577    @Override
5578    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5579        if (!(pendingResult instanceof PendingIntentRecord)) {
5580            return null;
5581        }
5582        try {
5583            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5584            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5585        } catch (ClassCastException e) {
5586        }
5587        return null;
5588    }
5589
5590    @Override
5591    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5592        if (!(pendingResult instanceof PendingIntentRecord)) {
5593            return null;
5594        }
5595        try {
5596            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5597            Intent intent = res.key.requestIntent;
5598            if (intent != null) {
5599                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5600                        || res.lastTagPrefix.equals(prefix))) {
5601                    return res.lastTag;
5602                }
5603                res.lastTagPrefix = prefix;
5604                StringBuilder sb = new StringBuilder(128);
5605                if (prefix != null) {
5606                    sb.append(prefix);
5607                }
5608                if (intent.getAction() != null) {
5609                    sb.append(intent.getAction());
5610                } else if (intent.getComponent() != null) {
5611                    intent.getComponent().appendShortString(sb);
5612                } else {
5613                    sb.append("?");
5614                }
5615                return res.lastTag = sb.toString();
5616            }
5617        } catch (ClassCastException e) {
5618        }
5619        return null;
5620    }
5621
5622    @Override
5623    public void setProcessLimit(int max) {
5624        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5625                "setProcessLimit()");
5626        synchronized (this) {
5627            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5628            mProcessLimitOverride = max;
5629        }
5630        trimApplications();
5631    }
5632
5633    @Override
5634    public int getProcessLimit() {
5635        synchronized (this) {
5636            return mProcessLimitOverride;
5637        }
5638    }
5639
5640    void foregroundTokenDied(ForegroundToken token) {
5641        synchronized (ActivityManagerService.this) {
5642            synchronized (mPidsSelfLocked) {
5643                ForegroundToken cur
5644                    = mForegroundProcesses.get(token.pid);
5645                if (cur != token) {
5646                    return;
5647                }
5648                mForegroundProcesses.remove(token.pid);
5649                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5650                if (pr == null) {
5651                    return;
5652                }
5653                pr.forcingToForeground = null;
5654                updateProcessForegroundLocked(pr, false, false);
5655            }
5656            updateOomAdjLocked();
5657        }
5658    }
5659
5660    @Override
5661    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5662        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5663                "setProcessForeground()");
5664        synchronized(this) {
5665            boolean changed = false;
5666
5667            synchronized (mPidsSelfLocked) {
5668                ProcessRecord pr = mPidsSelfLocked.get(pid);
5669                if (pr == null && isForeground) {
5670                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5671                    return;
5672                }
5673                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5674                if (oldToken != null) {
5675                    oldToken.token.unlinkToDeath(oldToken, 0);
5676                    mForegroundProcesses.remove(pid);
5677                    if (pr != null) {
5678                        pr.forcingToForeground = null;
5679                    }
5680                    changed = true;
5681                }
5682                if (isForeground && token != null) {
5683                    ForegroundToken newToken = new ForegroundToken() {
5684                        @Override
5685                        public void binderDied() {
5686                            foregroundTokenDied(this);
5687                        }
5688                    };
5689                    newToken.pid = pid;
5690                    newToken.token = token;
5691                    try {
5692                        token.linkToDeath(newToken, 0);
5693                        mForegroundProcesses.put(pid, newToken);
5694                        pr.forcingToForeground = token;
5695                        changed = true;
5696                    } catch (RemoteException e) {
5697                        // If the process died while doing this, we will later
5698                        // do the cleanup with the process death link.
5699                    }
5700                }
5701            }
5702
5703            if (changed) {
5704                updateOomAdjLocked();
5705            }
5706        }
5707    }
5708
5709    // =========================================================
5710    // PERMISSIONS
5711    // =========================================================
5712
5713    static class PermissionController extends IPermissionController.Stub {
5714        ActivityManagerService mActivityManagerService;
5715        PermissionController(ActivityManagerService activityManagerService) {
5716            mActivityManagerService = activityManagerService;
5717        }
5718
5719        @Override
5720        public boolean checkPermission(String permission, int pid, int uid) {
5721            return mActivityManagerService.checkPermission(permission, pid,
5722                    uid) == PackageManager.PERMISSION_GRANTED;
5723        }
5724    }
5725
5726    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5727        @Override
5728        public int checkComponentPermission(String permission, int pid, int uid,
5729                int owningUid, boolean exported) {
5730            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5731                    owningUid, exported);
5732        }
5733
5734        @Override
5735        public Object getAMSLock() {
5736            return ActivityManagerService.this;
5737        }
5738    }
5739
5740    /**
5741     * This can be called with or without the global lock held.
5742     */
5743    int checkComponentPermission(String permission, int pid, int uid,
5744            int owningUid, boolean exported) {
5745        // We might be performing an operation on behalf of an indirect binder
5746        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5747        // client identity accordingly before proceeding.
5748        Identity tlsIdentity = sCallerIdentity.get();
5749        if (tlsIdentity != null) {
5750            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5751                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5752            uid = tlsIdentity.uid;
5753            pid = tlsIdentity.pid;
5754        }
5755
5756        if (pid == MY_PID) {
5757            return PackageManager.PERMISSION_GRANTED;
5758        }
5759
5760        return ActivityManager.checkComponentPermission(permission, uid,
5761                owningUid, exported);
5762    }
5763
5764    /**
5765     * As the only public entry point for permissions checking, this method
5766     * can enforce the semantic that requesting a check on a null global
5767     * permission is automatically denied.  (Internally a null permission
5768     * string is used when calling {@link #checkComponentPermission} in cases
5769     * when only uid-based security is needed.)
5770     *
5771     * This can be called with or without the global lock held.
5772     */
5773    @Override
5774    public int checkPermission(String permission, int pid, int uid) {
5775        if (permission == null) {
5776            return PackageManager.PERMISSION_DENIED;
5777        }
5778        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5779    }
5780
5781    /**
5782     * Binder IPC calls go through the public entry point.
5783     * This can be called with or without the global lock held.
5784     */
5785    int checkCallingPermission(String permission) {
5786        return checkPermission(permission,
5787                Binder.getCallingPid(),
5788                UserHandle.getAppId(Binder.getCallingUid()));
5789    }
5790
5791    /**
5792     * This can be called with or without the global lock held.
5793     */
5794    void enforceCallingPermission(String permission, String func) {
5795        if (checkCallingPermission(permission)
5796                == PackageManager.PERMISSION_GRANTED) {
5797            return;
5798        }
5799
5800        String msg = "Permission Denial: " + func + " from pid="
5801                + Binder.getCallingPid()
5802                + ", uid=" + Binder.getCallingUid()
5803                + " requires " + permission;
5804        Slog.w(TAG, msg);
5805        throw new SecurityException(msg);
5806    }
5807
5808    /**
5809     * Determine if UID is holding permissions required to access {@link Uri} in
5810     * the given {@link ProviderInfo}. Final permission checking is always done
5811     * in {@link ContentProvider}.
5812     */
5813    private final boolean checkHoldingPermissionsLocked(
5814            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
5815        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5816                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
5817
5818        if (pi.applicationInfo.uid == uid) {
5819            return true;
5820        } else if (!pi.exported) {
5821            return false;
5822        }
5823
5824        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
5825        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
5826        try {
5827            // check if target holds top-level <provider> permissions
5828            if (!readMet && pi.readPermission != null
5829                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
5830                readMet = true;
5831            }
5832            if (!writeMet && pi.writePermission != null
5833                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
5834                writeMet = true;
5835            }
5836
5837            // track if unprotected read/write is allowed; any denied
5838            // <path-permission> below removes this ability
5839            boolean allowDefaultRead = pi.readPermission == null;
5840            boolean allowDefaultWrite = pi.writePermission == null;
5841
5842            // check if target holds any <path-permission> that match uri
5843            final PathPermission[] pps = pi.pathPermissions;
5844            if (pps != null) {
5845                final String path = uri.getPath();
5846                int i = pps.length;
5847                while (i > 0 && (!readMet || !writeMet)) {
5848                    i--;
5849                    PathPermission pp = pps[i];
5850                    if (pp.match(path)) {
5851                        if (!readMet) {
5852                            final String pprperm = pp.getReadPermission();
5853                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
5854                                    + pprperm + " for " + pp.getPath()
5855                                    + ": match=" + pp.match(path)
5856                                    + " check=" + pm.checkUidPermission(pprperm, uid));
5857                            if (pprperm != null) {
5858                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
5859                                    readMet = true;
5860                                } else {
5861                                    allowDefaultRead = false;
5862                                }
5863                            }
5864                        }
5865                        if (!writeMet) {
5866                            final String ppwperm = pp.getWritePermission();
5867                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
5868                                    + ppwperm + " for " + pp.getPath()
5869                                    + ": match=" + pp.match(path)
5870                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
5871                            if (ppwperm != null) {
5872                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
5873                                    writeMet = true;
5874                                } else {
5875                                    allowDefaultWrite = false;
5876                                }
5877                            }
5878                        }
5879                    }
5880                }
5881            }
5882
5883            // grant unprotected <provider> read/write, if not blocked by
5884            // <path-permission> above
5885            if (allowDefaultRead) readMet = true;
5886            if (allowDefaultWrite) writeMet = true;
5887
5888        } catch (RemoteException e) {
5889            return false;
5890        }
5891
5892        return readMet && writeMet;
5893    }
5894
5895    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
5896        ProviderInfo pi = null;
5897        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
5898        if (cpr != null) {
5899            pi = cpr.info;
5900        } else {
5901            try {
5902                pi = AppGlobals.getPackageManager().resolveContentProvider(
5903                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
5904            } catch (RemoteException ex) {
5905            }
5906        }
5907        return pi;
5908    }
5909
5910    private UriPermission findUriPermissionLocked(int targetUid, Uri uri) {
5911        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5912        if (targetUris != null) {
5913            return targetUris.get(uri);
5914        } else {
5915            return null;
5916        }
5917    }
5918
5919    private UriPermission findOrCreateUriPermissionLocked(
5920            String sourcePkg, String targetPkg, int targetUid, Uri uri) {
5921        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5922        if (targetUris == null) {
5923            targetUris = Maps.newArrayMap();
5924            mGrantedUriPermissions.put(targetUid, targetUris);
5925        }
5926
5927        UriPermission perm = targetUris.get(uri);
5928        if (perm == null) {
5929            perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri);
5930            targetUris.put(uri, perm);
5931        }
5932
5933        return perm;
5934    }
5935
5936    private final boolean checkUriPermissionLocked(
5937            Uri uri, int uid, int modeFlags, int minStrength) {
5938        // Root gets to do everything.
5939        if (uid == 0) {
5940            return true;
5941        }
5942        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5943        if (perms == null) return false;
5944        UriPermission perm = perms.get(uri);
5945        if (perm == null) return false;
5946        return perm.getStrength(modeFlags) >= minStrength;
5947    }
5948
5949    @Override
5950    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
5951        enforceNotIsolatedCaller("checkUriPermission");
5952
5953        // Another redirected-binder-call permissions check as in
5954        // {@link checkComponentPermission}.
5955        Identity tlsIdentity = sCallerIdentity.get();
5956        if (tlsIdentity != null) {
5957            uid = tlsIdentity.uid;
5958            pid = tlsIdentity.pid;
5959        }
5960
5961        // Our own process gets to do everything.
5962        if (pid == MY_PID) {
5963            return PackageManager.PERMISSION_GRANTED;
5964        }
5965        synchronized(this) {
5966            return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED)
5967                    ? PackageManager.PERMISSION_GRANTED
5968                    : PackageManager.PERMISSION_DENIED;
5969        }
5970    }
5971
5972    /**
5973     * Check if the targetPkg can be granted permission to access uri by
5974     * the callingUid using the given modeFlags.  Throws a security exception
5975     * if callingUid is not allowed to do this.  Returns the uid of the target
5976     * if the URI permission grant should be performed; returns -1 if it is not
5977     * needed (for example targetPkg already has permission to access the URI).
5978     * If you already know the uid of the target, you can supply it in
5979     * lastTargetUid else set that to -1.
5980     */
5981    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5982            Uri uri, int modeFlags, int lastTargetUid) {
5983        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
5984        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5985                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5986        if (modeFlags == 0) {
5987            return -1;
5988        }
5989
5990        if (targetPkg != null) {
5991            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5992                    "Checking grant " + targetPkg + " permission to " + uri);
5993        }
5994
5995        final IPackageManager pm = AppGlobals.getPackageManager();
5996
5997        // If this is not a content: uri, we can't do anything with it.
5998        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
5999            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6000                    "Can't grant URI permission for non-content URI: " + uri);
6001            return -1;
6002        }
6003
6004        final String authority = uri.getAuthority();
6005        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6006        if (pi == null) {
6007            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
6008            return -1;
6009        }
6010
6011        int targetUid = lastTargetUid;
6012        if (targetUid < 0 && targetPkg != null) {
6013            try {
6014                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6015                if (targetUid < 0) {
6016                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6017                            "Can't grant URI permission no uid for: " + targetPkg);
6018                    return -1;
6019                }
6020            } catch (RemoteException ex) {
6021                return -1;
6022            }
6023        }
6024
6025        if (targetUid >= 0) {
6026            // First...  does the target actually need this permission?
6027            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
6028                // No need to grant the target this permission.
6029                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6030                        "Target " + targetPkg + " already has full permission to " + uri);
6031                return -1;
6032            }
6033        } else {
6034            // First...  there is no target package, so can anyone access it?
6035            boolean allowed = pi.exported;
6036            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6037                if (pi.readPermission != null) {
6038                    allowed = false;
6039                }
6040            }
6041            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6042                if (pi.writePermission != null) {
6043                    allowed = false;
6044                }
6045            }
6046            if (allowed) {
6047                return -1;
6048            }
6049        }
6050
6051        // Second...  is the provider allowing granting of URI permissions?
6052        if (!pi.grantUriPermissions) {
6053            throw new SecurityException("Provider " + pi.packageName
6054                    + "/" + pi.name
6055                    + " does not allow granting of Uri permissions (uri "
6056                    + uri + ")");
6057        }
6058        if (pi.uriPermissionPatterns != null) {
6059            final int N = pi.uriPermissionPatterns.length;
6060            boolean allowed = false;
6061            for (int i=0; i<N; i++) {
6062                if (pi.uriPermissionPatterns[i] != null
6063                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
6064                    allowed = true;
6065                    break;
6066                }
6067            }
6068            if (!allowed) {
6069                throw new SecurityException("Provider " + pi.packageName
6070                        + "/" + pi.name
6071                        + " does not allow granting of permission to path of Uri "
6072                        + uri);
6073            }
6074        }
6075
6076        // Third...  does the caller itself have permission to access
6077        // this uri?
6078        if (callingUid != Process.myUid()) {
6079            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6080                // Require they hold a strong enough Uri permission
6081                final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6082                        : UriPermission.STRENGTH_OWNED;
6083                if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) {
6084                    throw new SecurityException("Uid " + callingUid
6085                            + " does not have permission to uri " + uri);
6086                }
6087            }
6088        }
6089
6090        return targetUid;
6091    }
6092
6093    @Override
6094    public int checkGrantUriPermission(int callingUid, String targetPkg,
6095            Uri uri, int modeFlags) {
6096        enforceNotIsolatedCaller("checkGrantUriPermission");
6097        synchronized(this) {
6098            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6099        }
6100    }
6101
6102    void grantUriPermissionUncheckedLocked(
6103            int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
6104        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6105        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6106                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6107        if (modeFlags == 0) {
6108            return;
6109        }
6110
6111        // So here we are: the caller has the assumed permission
6112        // to the uri, and the target doesn't.  Let's now give this to
6113        // the target.
6114
6115        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6116                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
6117
6118        final String authority = uri.getAuthority();
6119        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid));
6120        if (pi == null) {
6121            Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString());
6122            return;
6123        }
6124
6125        final UriPermission perm = findOrCreateUriPermissionLocked(
6126                pi.packageName, targetPkg, targetUid, uri);
6127        perm.grantModes(modeFlags, persistable, owner);
6128    }
6129
6130    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
6131            int modeFlags, UriPermissionOwner owner) {
6132        if (targetPkg == null) {
6133            throw new NullPointerException("targetPkg");
6134        }
6135
6136        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6137        if (targetUid < 0) {
6138            return;
6139        }
6140
6141        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
6142    }
6143
6144    static class NeededUriGrants extends ArrayList<Uri> {
6145        final String targetPkg;
6146        final int targetUid;
6147        final int flags;
6148
6149        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6150            this.targetPkg = targetPkg;
6151            this.targetUid = targetUid;
6152            this.flags = flags;
6153        }
6154    }
6155
6156    /**
6157     * Like checkGrantUriPermissionLocked, but takes an Intent.
6158     */
6159    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6160            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6161        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6162                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6163                + " clip=" + (intent != null ? intent.getClipData() : null)
6164                + " from " + intent + "; flags=0x"
6165                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6166
6167        if (targetPkg == null) {
6168            throw new NullPointerException("targetPkg");
6169        }
6170
6171        if (intent == null) {
6172            return null;
6173        }
6174        Uri data = intent.getData();
6175        ClipData clip = intent.getClipData();
6176        if (data == null && clip == null) {
6177            return null;
6178        }
6179
6180        if (data != null) {
6181            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
6182                mode, needed != null ? needed.targetUid : -1);
6183            if (targetUid > 0) {
6184                if (needed == null) {
6185                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6186                }
6187                needed.add(data);
6188            }
6189        }
6190        if (clip != null) {
6191            for (int i=0; i<clip.getItemCount(); i++) {
6192                Uri uri = clip.getItemAt(i).getUri();
6193                if (uri != null) {
6194                    int targetUid = -1;
6195                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
6196                            mode, needed != null ? needed.targetUid : -1);
6197                    if (targetUid > 0) {
6198                        if (needed == null) {
6199                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6200                        }
6201                        needed.add(uri);
6202                    }
6203                } else {
6204                    Intent clipIntent = clip.getItemAt(i).getIntent();
6205                    if (clipIntent != null) {
6206                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6207                                callingUid, targetPkg, clipIntent, mode, needed);
6208                        if (newNeeded != null) {
6209                            needed = newNeeded;
6210                        }
6211                    }
6212                }
6213            }
6214        }
6215
6216        return needed;
6217    }
6218
6219    /**
6220     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6221     */
6222    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6223            UriPermissionOwner owner) {
6224        if (needed != null) {
6225            for (int i=0; i<needed.size(); i++) {
6226                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6227                        needed.get(i), needed.flags, owner);
6228            }
6229        }
6230    }
6231
6232    void grantUriPermissionFromIntentLocked(int callingUid,
6233            String targetPkg, Intent intent, UriPermissionOwner owner) {
6234        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6235                intent, intent != null ? intent.getFlags() : 0, null);
6236        if (needed == null) {
6237            return;
6238        }
6239
6240        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6241    }
6242
6243    @Override
6244    public void grantUriPermission(IApplicationThread caller, String targetPkg,
6245            Uri uri, int modeFlags) {
6246        enforceNotIsolatedCaller("grantUriPermission");
6247        synchronized(this) {
6248            final ProcessRecord r = getRecordForAppLocked(caller);
6249            if (r == null) {
6250                throw new SecurityException("Unable to find app for caller "
6251                        + caller
6252                        + " when granting permission to uri " + uri);
6253            }
6254            if (targetPkg == null) {
6255                throw new IllegalArgumentException("null target");
6256            }
6257            if (uri == null) {
6258                throw new IllegalArgumentException("null uri");
6259            }
6260
6261            // Persistable only supported through Intents
6262            Preconditions.checkFlagsArgument(modeFlags,
6263                    Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6264
6265            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
6266                    null);
6267        }
6268    }
6269
6270    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6271        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
6272                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
6273            ArrayMap<Uri, UriPermission> perms
6274                    = mGrantedUriPermissions.get(perm.targetUid);
6275            if (perms != null) {
6276                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6277                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6278                perms.remove(perm.uri);
6279                if (perms.size() == 0) {
6280                    mGrantedUriPermissions.remove(perm.targetUid);
6281                }
6282            }
6283        }
6284    }
6285
6286    private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) {
6287        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri);
6288
6289        final IPackageManager pm = AppGlobals.getPackageManager();
6290        final String authority = uri.getAuthority();
6291        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6292        if (pi == null) {
6293            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
6294            return;
6295        }
6296
6297        // Does the caller have this permission on the URI?
6298        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6299            // Right now, if you are not the original owner of the permission,
6300            // you are not allowed to revoke it.
6301            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6302                throw new SecurityException("Uid " + callingUid
6303                        + " does not have permission to uri " + uri);
6304            //}
6305        }
6306
6307        boolean persistChanged = false;
6308
6309        // Go through all of the permissions and remove any that match.
6310        final List<String> SEGMENTS = uri.getPathSegments();
6311        if (SEGMENTS != null) {
6312            final int NS = SEGMENTS.size();
6313            int N = mGrantedUriPermissions.size();
6314            for (int i=0; i<N; i++) {
6315                ArrayMap<Uri, UriPermission> perms
6316                        = mGrantedUriPermissions.valueAt(i);
6317                Iterator<UriPermission> it = perms.values().iterator();
6318            toploop:
6319                while (it.hasNext()) {
6320                    UriPermission perm = it.next();
6321                    Uri targetUri = perm.uri;
6322                    if (!authority.equals(targetUri.getAuthority())) {
6323                        continue;
6324                    }
6325                    List<String> targetSegments = targetUri.getPathSegments();
6326                    if (targetSegments == null) {
6327                        continue;
6328                    }
6329                    if (targetSegments.size() < NS) {
6330                        continue;
6331                    }
6332                    for (int j=0; j<NS; j++) {
6333                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
6334                            continue toploop;
6335                        }
6336                    }
6337                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6338                            "Revoking " + perm.targetUid + " permission to " + perm.uri);
6339                    persistChanged |= perm.clearModes(modeFlags, true);
6340                    if (perm.modeFlags == 0) {
6341                        it.remove();
6342                    }
6343                }
6344                if (perms.size() == 0) {
6345                    mGrantedUriPermissions.remove(
6346                            mGrantedUriPermissions.keyAt(i));
6347                    N--;
6348                    i--;
6349                }
6350            }
6351        }
6352
6353        if (persistChanged) {
6354            schedulePersistUriGrants();
6355        }
6356    }
6357
6358    @Override
6359    public void revokeUriPermission(IApplicationThread caller, Uri uri,
6360            int modeFlags) {
6361        enforceNotIsolatedCaller("revokeUriPermission");
6362        synchronized(this) {
6363            final ProcessRecord r = getRecordForAppLocked(caller);
6364            if (r == null) {
6365                throw new SecurityException("Unable to find app for caller "
6366                        + caller
6367                        + " when revoking permission to uri " + uri);
6368            }
6369            if (uri == null) {
6370                Slog.w(TAG, "revokeUriPermission: null uri");
6371                return;
6372            }
6373
6374            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6375                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6376            if (modeFlags == 0) {
6377                return;
6378            }
6379
6380            final IPackageManager pm = AppGlobals.getPackageManager();
6381            final String authority = uri.getAuthority();
6382            final ProviderInfo pi = getProviderInfoLocked(authority, r.userId);
6383            if (pi == null) {
6384                Slog.w(TAG, "No content provider found for permission revoke: "
6385                        + uri.toSafeString());
6386                return;
6387            }
6388
6389            revokeUriPermissionLocked(r.uid, uri, modeFlags);
6390        }
6391    }
6392
6393    /**
6394     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6395     * given package.
6396     *
6397     * @param packageName Package name to match, or {@code null} to apply to all
6398     *            packages.
6399     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6400     *            to all users.
6401     * @param persistable If persistable grants should be removed.
6402     */
6403    private void removeUriPermissionsForPackageLocked(
6404            String packageName, int userHandle, boolean persistable) {
6405        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6406            throw new IllegalArgumentException("Must narrow by either package or user");
6407        }
6408
6409        boolean persistChanged = false;
6410
6411        final int size = mGrantedUriPermissions.size();
6412        for (int i = 0; i < size; i++) {
6413            // Only inspect grants matching user
6414            if (userHandle == UserHandle.USER_ALL
6415                    || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) {
6416                final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i)
6417                        .values().iterator();
6418                while (it.hasNext()) {
6419                    final UriPermission perm = it.next();
6420
6421                    // Only inspect grants matching package
6422                    if (packageName == null || perm.sourcePkg.equals(packageName)
6423                            || perm.targetPkg.equals(packageName)) {
6424                        persistChanged |= perm.clearModes(~0, persistable);
6425
6426                        // Only remove when no modes remain; any persisted grants
6427                        // will keep this alive.
6428                        if (perm.modeFlags == 0) {
6429                            it.remove();
6430                        }
6431                    }
6432                }
6433            }
6434        }
6435
6436        if (persistChanged) {
6437            schedulePersistUriGrants();
6438        }
6439    }
6440
6441    @Override
6442    public IBinder newUriPermissionOwner(String name) {
6443        enforceNotIsolatedCaller("newUriPermissionOwner");
6444        synchronized(this) {
6445            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6446            return owner.getExternalTokenLocked();
6447        }
6448    }
6449
6450    @Override
6451    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
6452            Uri uri, int modeFlags) {
6453        synchronized(this) {
6454            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6455            if (owner == null) {
6456                throw new IllegalArgumentException("Unknown owner: " + token);
6457            }
6458            if (fromUid != Binder.getCallingUid()) {
6459                if (Binder.getCallingUid() != Process.myUid()) {
6460                    // Only system code can grant URI permissions on behalf
6461                    // of other users.
6462                    throw new SecurityException("nice try");
6463                }
6464            }
6465            if (targetPkg == null) {
6466                throw new IllegalArgumentException("null target");
6467            }
6468            if (uri == null) {
6469                throw new IllegalArgumentException("null uri");
6470            }
6471
6472            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
6473        }
6474    }
6475
6476    @Override
6477    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
6478        synchronized(this) {
6479            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6480            if (owner == null) {
6481                throw new IllegalArgumentException("Unknown owner: " + token);
6482            }
6483
6484            if (uri == null) {
6485                owner.removeUriPermissionsLocked(mode);
6486            } else {
6487                owner.removeUriPermissionLocked(uri, mode);
6488            }
6489        }
6490    }
6491
6492    private void schedulePersistUriGrants() {
6493        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6494            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6495                    10 * DateUtils.SECOND_IN_MILLIS);
6496        }
6497    }
6498
6499    private void writeGrantedUriPermissions() {
6500        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6501
6502        // Snapshot permissions so we can persist without lock
6503        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6504        synchronized (this) {
6505            final int size = mGrantedUriPermissions.size();
6506            for (int i = 0 ; i < size; i++) {
6507                for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) {
6508                    if (perm.persistedModeFlags != 0) {
6509                        persist.add(perm.snapshot());
6510                    }
6511                }
6512            }
6513        }
6514
6515        FileOutputStream fos = null;
6516        try {
6517            fos = mGrantFile.startWrite();
6518
6519            XmlSerializer out = new FastXmlSerializer();
6520            out.setOutput(fos, "utf-8");
6521            out.startDocument(null, true);
6522            out.startTag(null, TAG_URI_GRANTS);
6523            for (UriPermission.Snapshot perm : persist) {
6524                out.startTag(null, TAG_URI_GRANT);
6525                writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle);
6526                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6527                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6528                out.attribute(null, ATTR_URI, String.valueOf(perm.uri));
6529                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6530                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6531                out.endTag(null, TAG_URI_GRANT);
6532            }
6533            out.endTag(null, TAG_URI_GRANTS);
6534            out.endDocument();
6535
6536            mGrantFile.finishWrite(fos);
6537        } catch (IOException e) {
6538            if (fos != null) {
6539                mGrantFile.failWrite(fos);
6540            }
6541        }
6542    }
6543
6544    private void readGrantedUriPermissionsLocked() {
6545        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6546
6547        final long now = System.currentTimeMillis();
6548
6549        FileInputStream fis = null;
6550        try {
6551            fis = mGrantFile.openRead();
6552            final XmlPullParser in = Xml.newPullParser();
6553            in.setInput(fis, null);
6554
6555            int type;
6556            while ((type = in.next()) != END_DOCUMENT) {
6557                final String tag = in.getName();
6558                if (type == START_TAG) {
6559                    if (TAG_URI_GRANT.equals(tag)) {
6560                        final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE);
6561                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6562                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6563                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6564                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6565                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6566
6567                        // Sanity check that provider still belongs to source package
6568                        final ProviderInfo pi = getProviderInfoLocked(
6569                                uri.getAuthority(), userHandle);
6570                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6571                            int targetUid = -1;
6572                            try {
6573                                targetUid = AppGlobals.getPackageManager()
6574                                        .getPackageUid(targetPkg, userHandle);
6575                            } catch (RemoteException e) {
6576                            }
6577                            if (targetUid != -1) {
6578                                final UriPermission perm = findOrCreateUriPermissionLocked(
6579                                        sourcePkg, targetPkg, targetUid, uri);
6580                                perm.initPersistedModes(modeFlags, createdTime);
6581                            }
6582                        } else {
6583                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6584                                    + " but instead found " + pi);
6585                        }
6586                    }
6587                }
6588            }
6589        } catch (FileNotFoundException e) {
6590            // Missing grants is okay
6591        } catch (IOException e) {
6592            Log.wtf(TAG, "Failed reading Uri grants", e);
6593        } catch (XmlPullParserException e) {
6594            Log.wtf(TAG, "Failed reading Uri grants", e);
6595        } finally {
6596            IoUtils.closeQuietly(fis);
6597        }
6598    }
6599
6600    @Override
6601    public void takePersistableUriPermission(Uri uri, int modeFlags) {
6602        enforceNotIsolatedCaller("takePersistableUriPermission");
6603
6604        Preconditions.checkFlagsArgument(modeFlags,
6605                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6606
6607        synchronized (this) {
6608            final int callingUid = Binder.getCallingUid();
6609            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6610            if (perm == null) {
6611                throw new SecurityException("No permission grant found for UID " + callingUid
6612                        + " and Uri " + uri.toSafeString());
6613            }
6614
6615            boolean persistChanged = perm.takePersistableModes(modeFlags);
6616            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6617
6618            if (persistChanged) {
6619                schedulePersistUriGrants();
6620            }
6621        }
6622    }
6623
6624    @Override
6625    public void releasePersistableUriPermission(Uri uri, int modeFlags) {
6626        enforceNotIsolatedCaller("releasePersistableUriPermission");
6627
6628        Preconditions.checkFlagsArgument(modeFlags,
6629                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6630
6631        synchronized (this) {
6632            final int callingUid = Binder.getCallingUid();
6633
6634            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6635            if (perm == null) {
6636                Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri "
6637                        + uri.toSafeString());
6638                return;
6639            }
6640
6641            final boolean persistChanged = perm.releasePersistableModes(modeFlags);
6642            removeUriPermissionIfNeededLocked(perm);
6643            if (persistChanged) {
6644                schedulePersistUriGrants();
6645            }
6646        }
6647    }
6648
6649    /**
6650     * Prune any older {@link UriPermission} for the given UID until outstanding
6651     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6652     *
6653     * @return if any mutations occured that require persisting.
6654     */
6655    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6656        final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6657        if (perms == null) return false;
6658        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6659
6660        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6661        for (UriPermission perm : perms.values()) {
6662            if (perm.persistedModeFlags != 0) {
6663                persisted.add(perm);
6664            }
6665        }
6666
6667        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6668        if (trimCount <= 0) return false;
6669
6670        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6671        for (int i = 0; i < trimCount; i++) {
6672            final UriPermission perm = persisted.get(i);
6673
6674            if (DEBUG_URI_PERMISSION) {
6675                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6676            }
6677
6678            perm.releasePersistableModes(~0);
6679            removeUriPermissionIfNeededLocked(perm);
6680        }
6681
6682        return true;
6683    }
6684
6685    @Override
6686    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6687            String packageName, boolean incoming) {
6688        enforceNotIsolatedCaller("getPersistedUriPermissions");
6689        Preconditions.checkNotNull(packageName, "packageName");
6690
6691        final int callingUid = Binder.getCallingUid();
6692        final IPackageManager pm = AppGlobals.getPackageManager();
6693        try {
6694            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6695            if (packageUid != callingUid) {
6696                throw new SecurityException(
6697                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6698            }
6699        } catch (RemoteException e) {
6700            throw new SecurityException("Failed to verify package name ownership");
6701        }
6702
6703        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6704        synchronized (this) {
6705            if (incoming) {
6706                final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6707                if (perms == null) {
6708                    Slog.w(TAG, "No permission grants found for " + packageName);
6709                } else {
6710                    final int size = perms.size();
6711                    for (int i = 0; i < size; i++) {
6712                        final UriPermission perm = perms.valueAt(i);
6713                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6714                            result.add(perm.buildPersistedPublicApiObject());
6715                        }
6716                    }
6717                }
6718            } else {
6719                final int size = mGrantedUriPermissions.size();
6720                for (int i = 0; i < size; i++) {
6721                    final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6722                    final int permsSize = perms.size();
6723                    for (int j = 0; j < permsSize; j++) {
6724                        final UriPermission perm = perms.valueAt(j);
6725                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6726                            result.add(perm.buildPersistedPublicApiObject());
6727                        }
6728                    }
6729                }
6730            }
6731        }
6732        return new ParceledListSlice<android.content.UriPermission>(result);
6733    }
6734
6735    @Override
6736    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6737        synchronized (this) {
6738            ProcessRecord app =
6739                who != null ? getRecordForAppLocked(who) : null;
6740            if (app == null) return;
6741
6742            Message msg = Message.obtain();
6743            msg.what = WAIT_FOR_DEBUGGER_MSG;
6744            msg.obj = app;
6745            msg.arg1 = waiting ? 1 : 0;
6746            mHandler.sendMessage(msg);
6747        }
6748    }
6749
6750    @Override
6751    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
6752        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
6753        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
6754        outInfo.availMem = Process.getFreeMemory();
6755        outInfo.totalMem = Process.getTotalMemory();
6756        outInfo.threshold = homeAppMem;
6757        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
6758        outInfo.hiddenAppThreshold = cachedAppMem;
6759        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
6760                ProcessList.SERVICE_ADJ);
6761        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
6762                ProcessList.VISIBLE_APP_ADJ);
6763        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
6764                ProcessList.FOREGROUND_APP_ADJ);
6765    }
6766
6767    // =========================================================
6768    // TASK MANAGEMENT
6769    // =========================================================
6770
6771    @Override
6772    public List<RunningTaskInfo> getTasks(int maxNum, int flags,
6773                         IThumbnailReceiver receiver) {
6774        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
6775
6776        PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver);
6777        ActivityRecord topRecord = null;
6778
6779        synchronized(this) {
6780            if (localLOGV) Slog.v(
6781                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
6782                + ", receiver=" + receiver);
6783
6784            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
6785                    != PackageManager.PERMISSION_GRANTED) {
6786                if (receiver != null) {
6787                    // If the caller wants to wait for pending thumbnails,
6788                    // it ain't gonna get them.
6789                    try {
6790                        receiver.finished();
6791                    } catch (RemoteException ex) {
6792                    }
6793                }
6794                String msg = "Permission Denial: getTasks() from pid="
6795                        + Binder.getCallingPid()
6796                        + ", uid=" + Binder.getCallingUid()
6797                        + " requires " + android.Manifest.permission.GET_TASKS;
6798                Slog.w(TAG, msg);
6799                throw new SecurityException(msg);
6800            }
6801
6802            // TODO: Improve with MRU list from all ActivityStacks.
6803            topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list);
6804
6805            if (!pending.pendingRecords.isEmpty()) {
6806                mPendingThumbnails.add(pending);
6807            }
6808        }
6809
6810        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
6811
6812        if (topRecord != null) {
6813            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
6814            try {
6815                IApplicationThread topThumbnail = topRecord.app.thread;
6816                topThumbnail.requestThumbnail(topRecord.appToken);
6817            } catch (Exception e) {
6818                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
6819                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
6820            }
6821        }
6822
6823        if (pending.pendingRecords.isEmpty() && receiver != null) {
6824            // In this case all thumbnails were available and the client
6825            // is being asked to be told when the remaining ones come in...
6826            // which is unusually, since the top-most currently running
6827            // activity should never have a canned thumbnail!  Oh well.
6828            try {
6829                receiver.finished();
6830            } catch (RemoteException ex) {
6831            }
6832        }
6833
6834        return list;
6835    }
6836
6837    TaskRecord getMostRecentTask() {
6838        return mRecentTasks.get(0);
6839    }
6840
6841    @Override
6842    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
6843            int flags, int userId) {
6844        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6845                false, true, "getRecentTasks", null);
6846
6847        synchronized (this) {
6848            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
6849                    "getRecentTasks()");
6850            final boolean detailed = checkCallingPermission(
6851                    android.Manifest.permission.GET_DETAILED_TASKS)
6852                    == PackageManager.PERMISSION_GRANTED;
6853
6854            IPackageManager pm = AppGlobals.getPackageManager();
6855
6856            final int N = mRecentTasks.size();
6857            ArrayList<ActivityManager.RecentTaskInfo> res
6858                    = new ArrayList<ActivityManager.RecentTaskInfo>(
6859                            maxNum < N ? maxNum : N);
6860
6861            final Set<Integer> includedUsers;
6862            if ((flags & ActivityManager.RECENT_INCLUDE_RELATED) != 0) {
6863                includedUsers = getRelatedUsersLocked(userId);
6864            } else {
6865                includedUsers = new HashSet<Integer>();
6866            }
6867            includedUsers.add(Integer.valueOf(userId));
6868            for (int i=0; i<N && maxNum > 0; i++) {
6869                TaskRecord tr = mRecentTasks.get(i);
6870                // Only add calling user or related users recent tasks
6871                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
6872
6873                // Return the entry if desired by the caller.  We always return
6874                // the first entry, because callers always expect this to be the
6875                // foreground app.  We may filter others if the caller has
6876                // not supplied RECENT_WITH_EXCLUDED and there is some reason
6877                // we should exclude the entry.
6878
6879                if (i == 0
6880                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
6881                        || (tr.intent == null)
6882                        || ((tr.intent.getFlags()
6883                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
6884                    ActivityManager.RecentTaskInfo rti
6885                            = new ActivityManager.RecentTaskInfo();
6886                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
6887                    rti.persistentId = tr.taskId;
6888                    rti.baseIntent = new Intent(
6889                            tr.intent != null ? tr.intent : tr.affinityIntent);
6890                    if (!detailed) {
6891                        rti.baseIntent.replaceExtras((Bundle)null);
6892                    }
6893                    rti.origActivity = tr.origActivity;
6894                    rti.description = tr.lastDescription;
6895                    rti.stackId = tr.stack.mStackId;
6896                    rti.userId = tr.userId;
6897
6898                    final ArrayList<ActivityRecord> activities = tr.mActivities;
6899                    int numSet = 0;
6900                    for (int activityNdx = activities.size() - 1; activityNdx >= 0 && numSet < 2;
6901                            --activityNdx) {
6902                        final ActivityRecord r = activities.get(activityNdx);
6903                        if (rti.activityLabel == null && r.recentsLabel != null) {
6904                            rti.activityLabel = r.recentsLabel;
6905                            ++numSet;
6906                        }
6907                        if (rti.activityIcon == null && r.recentsIcon != null) {
6908                            rti.activityIcon = r.recentsIcon;
6909                            ++numSet;
6910                        }
6911                    }
6912
6913                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
6914                        // Check whether this activity is currently available.
6915                        try {
6916                            if (rti.origActivity != null) {
6917                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
6918                                        == null) {
6919                                    continue;
6920                                }
6921                            } else if (rti.baseIntent != null) {
6922                                if (pm.queryIntentActivities(rti.baseIntent,
6923                                        null, 0, userId) == null) {
6924                                    continue;
6925                                }
6926                            }
6927                        } catch (RemoteException e) {
6928                            // Will never happen.
6929                        }
6930                    }
6931
6932                    res.add(rti);
6933                    maxNum--;
6934                }
6935            }
6936            return res;
6937        }
6938    }
6939
6940    private TaskRecord recentTaskForIdLocked(int id) {
6941        final int N = mRecentTasks.size();
6942            for (int i=0; i<N; i++) {
6943                TaskRecord tr = mRecentTasks.get(i);
6944                if (tr.taskId == id) {
6945                    return tr;
6946                }
6947            }
6948            return null;
6949    }
6950
6951    @Override
6952    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
6953        synchronized (this) {
6954            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6955                    "getTaskThumbnails()");
6956            TaskRecord tr = recentTaskForIdLocked(id);
6957            if (tr != null) {
6958                return tr.getTaskThumbnailsLocked();
6959            }
6960        }
6961        return null;
6962    }
6963
6964    @Override
6965    public Bitmap getTaskTopThumbnail(int id) {
6966        synchronized (this) {
6967            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6968                    "getTaskTopThumbnail()");
6969            TaskRecord tr = recentTaskForIdLocked(id);
6970            if (tr != null) {
6971                return tr.getTaskTopThumbnailLocked();
6972            }
6973        }
6974        return null;
6975    }
6976
6977    @Override
6978    public void setRecentsLabel(IBinder token, CharSequence recentsLabel) {
6979        synchronized (this) {
6980            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6981            if (r != null) {
6982                r.recentsLabel = recentsLabel.toString();
6983            }
6984        }
6985    }
6986
6987    @Override
6988    public void setRecentsIcon(IBinder token, Bitmap recentsIcon) {
6989        synchronized (this) {
6990            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6991            if (r != null) {
6992                r.recentsIcon = recentsIcon;
6993            }
6994        }
6995    }
6996
6997    @Override
6998    public boolean removeSubTask(int taskId, int subTaskIndex) {
6999        synchronized (this) {
7000            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7001                    "removeSubTask()");
7002            long ident = Binder.clearCallingIdentity();
7003            try {
7004                TaskRecord tr = recentTaskForIdLocked(taskId);
7005                if (tr != null) {
7006                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
7007                }
7008                return false;
7009            } finally {
7010                Binder.restoreCallingIdentity(ident);
7011            }
7012        }
7013    }
7014
7015    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7016        if (!pr.killedByAm) {
7017            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7018            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7019                    pr.processName, pr.setAdj, reason);
7020            pr.killedByAm = true;
7021            Process.killProcessQuiet(pr.pid);
7022        }
7023    }
7024
7025    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7026        tr.disposeThumbnail();
7027        mRecentTasks.remove(tr);
7028        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7029        Intent baseIntent = new Intent(
7030                tr.intent != null ? tr.intent : tr.affinityIntent);
7031        ComponentName component = baseIntent.getComponent();
7032        if (component == null) {
7033            Slog.w(TAG, "Now component for base intent of task: " + tr);
7034            return;
7035        }
7036
7037        // Find any running services associated with this app.
7038        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7039
7040        if (killProcesses) {
7041            // Find any running processes associated with this app.
7042            final String pkg = component.getPackageName();
7043            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7044            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7045            for (int i=0; i<pmap.size(); i++) {
7046                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7047                for (int j=0; j<uids.size(); j++) {
7048                    ProcessRecord proc = uids.valueAt(j);
7049                    if (proc.userId != tr.userId) {
7050                        continue;
7051                    }
7052                    if (!proc.pkgList.containsKey(pkg)) {
7053                        continue;
7054                    }
7055                    procs.add(proc);
7056                }
7057            }
7058
7059            // Kill the running processes.
7060            for (int i=0; i<procs.size(); i++) {
7061                ProcessRecord pr = procs.get(i);
7062                if (pr == mHomeProcess) {
7063                    // Don't kill the home process along with tasks from the same package.
7064                    continue;
7065                }
7066                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7067                    killUnneededProcessLocked(pr, "remove task");
7068                } else {
7069                    pr.waitingToKill = "remove task";
7070                }
7071            }
7072        }
7073    }
7074
7075    @Override
7076    public boolean removeTask(int taskId, int flags) {
7077        synchronized (this) {
7078            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7079                    "removeTask()");
7080            long ident = Binder.clearCallingIdentity();
7081            try {
7082                TaskRecord tr = recentTaskForIdLocked(taskId);
7083                if (tr != null) {
7084                    ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false);
7085                    if (r != null) {
7086                        cleanUpRemovedTaskLocked(tr, flags);
7087                        return true;
7088                    }
7089                    if (tr.mActivities.size() == 0) {
7090                        // Caller is just removing a recent task that is
7091                        // not actively running.  That is easy!
7092                        cleanUpRemovedTaskLocked(tr, flags);
7093                        return true;
7094                    }
7095                    Slog.w(TAG, "removeTask: task " + taskId
7096                            + " does not have activities to remove, "
7097                            + " but numActivities=" + tr.numActivities
7098                            + ": " + tr);
7099                }
7100            } finally {
7101                Binder.restoreCallingIdentity(ident);
7102            }
7103        }
7104        return false;
7105    }
7106
7107    /**
7108     * TODO: Add mController hook
7109     */
7110    @Override
7111    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7112        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7113                "moveTaskToFront()");
7114
7115        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7116        synchronized(this) {
7117            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7118                    Binder.getCallingUid(), "Task to front")) {
7119                ActivityOptions.abort(options);
7120                return;
7121            }
7122            final long origId = Binder.clearCallingIdentity();
7123            try {
7124                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7125                if (task == null) {
7126                    return;
7127                }
7128                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7129                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7130                    return;
7131                }
7132                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7133            } finally {
7134                Binder.restoreCallingIdentity(origId);
7135            }
7136            ActivityOptions.abort(options);
7137        }
7138    }
7139
7140    @Override
7141    public void moveTaskToBack(int taskId) {
7142        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7143                "moveTaskToBack()");
7144
7145        synchronized(this) {
7146            TaskRecord tr = recentTaskForIdLocked(taskId);
7147            if (tr != null) {
7148                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7149                ActivityStack stack = tr.stack;
7150                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7151                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7152                            Binder.getCallingUid(), "Task to back")) {
7153                        return;
7154                    }
7155                }
7156                final long origId = Binder.clearCallingIdentity();
7157                try {
7158                    stack.moveTaskToBackLocked(taskId, null);
7159                } finally {
7160                    Binder.restoreCallingIdentity(origId);
7161                }
7162            }
7163        }
7164    }
7165
7166    /**
7167     * Moves an activity, and all of the other activities within the same task, to the bottom
7168     * of the history stack.  The activity's order within the task is unchanged.
7169     *
7170     * @param token A reference to the activity we wish to move
7171     * @param nonRoot If false then this only works if the activity is the root
7172     *                of a task; if true it will work for any activity in a task.
7173     * @return Returns true if the move completed, false if not.
7174     */
7175    @Override
7176    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7177        enforceNotIsolatedCaller("moveActivityTaskToBack");
7178        synchronized(this) {
7179            final long origId = Binder.clearCallingIdentity();
7180            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7181            if (taskId >= 0) {
7182                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7183            }
7184            Binder.restoreCallingIdentity(origId);
7185        }
7186        return false;
7187    }
7188
7189    @Override
7190    public void moveTaskBackwards(int task) {
7191        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7192                "moveTaskBackwards()");
7193
7194        synchronized(this) {
7195            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7196                    Binder.getCallingUid(), "Task backwards")) {
7197                return;
7198            }
7199            final long origId = Binder.clearCallingIdentity();
7200            moveTaskBackwardsLocked(task);
7201            Binder.restoreCallingIdentity(origId);
7202        }
7203    }
7204
7205    private final void moveTaskBackwardsLocked(int task) {
7206        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7207    }
7208
7209    @Override
7210    public IBinder getHomeActivityToken() throws RemoteException {
7211        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7212                "getHomeActivityToken()");
7213        synchronized (this) {
7214            return mStackSupervisor.getHomeActivityToken();
7215        }
7216    }
7217
7218    @Override
7219    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7220            IActivityContainerCallback callback) throws RemoteException {
7221        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7222                "createActivityContainer()");
7223        synchronized (this) {
7224            if (parentActivityToken == null) {
7225                throw new IllegalArgumentException("parent token must not be null");
7226            }
7227            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7228            if (r == null) {
7229                return null;
7230            }
7231            return mStackSupervisor.createActivityContainer(r, callback);
7232        }
7233    }
7234
7235    @Override
7236    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7237        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7238                "deleteActivityContainer()");
7239        synchronized (this) {
7240            mStackSupervisor.deleteActivityContainer(container);
7241        }
7242    }
7243
7244    @Override
7245    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7246            throws RemoteException {
7247        synchronized (this) {
7248            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7249            if (stack != null) {
7250                return stack.mActivityContainer;
7251            }
7252            return null;
7253        }
7254    }
7255
7256    @Override
7257    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7258        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7259                "moveTaskToStack()");
7260        if (stackId == HOME_STACK_ID) {
7261            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7262                    new RuntimeException("here").fillInStackTrace());
7263        }
7264        synchronized (this) {
7265            long ident = Binder.clearCallingIdentity();
7266            try {
7267                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7268                        + stackId + " toTop=" + toTop);
7269                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7270            } finally {
7271                Binder.restoreCallingIdentity(ident);
7272            }
7273        }
7274    }
7275
7276    @Override
7277    public void resizeStack(int stackBoxId, Rect bounds) {
7278        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7279                "resizeStackBox()");
7280        long ident = Binder.clearCallingIdentity();
7281        try {
7282            mWindowManager.resizeStack(stackBoxId, bounds);
7283        } finally {
7284            Binder.restoreCallingIdentity(ident);
7285        }
7286    }
7287
7288    @Override
7289    public List<StackInfo> getAllStackInfos() {
7290        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7291                "getAllStackInfos()");
7292        long ident = Binder.clearCallingIdentity();
7293        try {
7294            synchronized (this) {
7295                return mStackSupervisor.getAllStackInfosLocked();
7296            }
7297        } finally {
7298            Binder.restoreCallingIdentity(ident);
7299        }
7300    }
7301
7302    @Override
7303    public StackInfo getStackInfo(int stackId) {
7304        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7305                "getStackInfo()");
7306        long ident = Binder.clearCallingIdentity();
7307        try {
7308            synchronized (this) {
7309                return mStackSupervisor.getStackInfoLocked(stackId);
7310            }
7311        } finally {
7312            Binder.restoreCallingIdentity(ident);
7313        }
7314    }
7315
7316    @Override
7317    public boolean isInHomeStack(int taskId) {
7318        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7319                "getStackInfo()");
7320        long ident = Binder.clearCallingIdentity();
7321        try {
7322            synchronized (this) {
7323                TaskRecord tr = recentTaskForIdLocked(taskId);
7324                if (tr != null) {
7325                    return tr.stack.isHomeStack();
7326                }
7327            }
7328        } finally {
7329            Binder.restoreCallingIdentity(ident);
7330        }
7331        return false;
7332    }
7333
7334    @Override
7335    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7336        synchronized(this) {
7337            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7338        }
7339    }
7340
7341    private boolean isLockTaskAuthorized(ComponentName name) {
7342//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7343//                "startLockTaskMode()");
7344//        DevicePolicyManager dpm = (DevicePolicyManager)
7345//                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7346//        return dpm != null && dpm.isLockTaskPermitted(name);
7347        return true;
7348    }
7349
7350    private void startLockTaskMode(TaskRecord task) {
7351        if (!isLockTaskAuthorized(task.intent.getComponent())) {
7352            return;
7353        }
7354        long ident = Binder.clearCallingIdentity();
7355        try {
7356            synchronized (this) {
7357                // Since we lost lock on task, make sure it is still there.
7358                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7359                if (task != null) {
7360                    mStackSupervisor.setLockTaskModeLocked(task);
7361                }
7362            }
7363        } finally {
7364            Binder.restoreCallingIdentity(ident);
7365        }
7366    }
7367
7368    @Override
7369    public void startLockTaskMode(int taskId) {
7370        long ident = Binder.clearCallingIdentity();
7371        try {
7372            final TaskRecord task;
7373            synchronized (this) {
7374                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7375            }
7376            if (task != null) {
7377                startLockTaskMode(task);
7378            }
7379        } finally {
7380            Binder.restoreCallingIdentity(ident);
7381        }
7382    }
7383
7384    @Override
7385    public void startLockTaskMode(IBinder token) {
7386        long ident = Binder.clearCallingIdentity();
7387        try {
7388            final TaskRecord task;
7389            synchronized (this) {
7390                final ActivityRecord r = ActivityRecord.forToken(token);
7391                if (r == null) {
7392                    return;
7393                }
7394                task = r.task;
7395            }
7396            if (task != null) {
7397                startLockTaskMode(task);
7398            }
7399        } finally {
7400            Binder.restoreCallingIdentity(ident);
7401        }
7402    }
7403
7404    @Override
7405    public void stopLockTaskMode() {
7406//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7407//                "stopLockTaskMode()");
7408        synchronized (this) {
7409            mStackSupervisor.setLockTaskModeLocked(null);
7410        }
7411    }
7412
7413    @Override
7414    public boolean isInLockTaskMode() {
7415        synchronized (this) {
7416            return mStackSupervisor.isInLockTaskMode();
7417        }
7418    }
7419
7420    // =========================================================
7421    // THUMBNAILS
7422    // =========================================================
7423
7424    public void reportThumbnail(IBinder token,
7425            Bitmap thumbnail, CharSequence description) {
7426        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
7427        final long origId = Binder.clearCallingIdentity();
7428        sendPendingThumbnail(null, token, thumbnail, description, true);
7429        Binder.restoreCallingIdentity(origId);
7430    }
7431
7432    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
7433            Bitmap thumbnail, CharSequence description, boolean always) {
7434        TaskRecord task;
7435        ArrayList<PendingThumbnailsRecord> receivers = null;
7436
7437        //System.out.println("Send pending thumbnail: " + r);
7438
7439        synchronized(this) {
7440            if (r == null) {
7441                r = ActivityRecord.isInStackLocked(token);
7442                if (r == null) {
7443                    return;
7444                }
7445            }
7446            if (thumbnail == null && r.thumbHolder != null) {
7447                thumbnail = r.thumbHolder.lastThumbnail;
7448                description = r.thumbHolder.lastDescription;
7449            }
7450            if (thumbnail == null && !always) {
7451                // If there is no thumbnail, and this entry is not actually
7452                // going away, then abort for now and pick up the next
7453                // thumbnail we get.
7454                return;
7455            }
7456            task = r.task;
7457
7458            int N = mPendingThumbnails.size();
7459            int i=0;
7460            while (i<N) {
7461                PendingThumbnailsRecord pr = mPendingThumbnails.get(i);
7462                //System.out.println("Looking in " + pr.pendingRecords);
7463                if (pr.pendingRecords.remove(r)) {
7464                    if (receivers == null) {
7465                        receivers = new ArrayList<PendingThumbnailsRecord>();
7466                    }
7467                    receivers.add(pr);
7468                    if (pr.pendingRecords.size() == 0) {
7469                        pr.finished = true;
7470                        mPendingThumbnails.remove(i);
7471                        N--;
7472                        continue;
7473                    }
7474                }
7475                i++;
7476            }
7477        }
7478
7479        if (receivers != null) {
7480            final int N = receivers.size();
7481            for (int i=0; i<N; i++) {
7482                try {
7483                    PendingThumbnailsRecord pr = receivers.get(i);
7484                    pr.receiver.newThumbnail(
7485                        task != null ? task.taskId : -1, thumbnail, description);
7486                    if (pr.finished) {
7487                        pr.receiver.finished();
7488                    }
7489                } catch (Exception e) {
7490                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
7491                }
7492            }
7493        }
7494    }
7495
7496    // =========================================================
7497    // CONTENT PROVIDERS
7498    // =========================================================
7499
7500    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7501        List<ProviderInfo> providers = null;
7502        try {
7503            providers = AppGlobals.getPackageManager().
7504                queryContentProviders(app.processName, app.uid,
7505                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7506        } catch (RemoteException ex) {
7507        }
7508        if (DEBUG_MU)
7509            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7510        int userId = app.userId;
7511        if (providers != null) {
7512            int N = providers.size();
7513            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7514            for (int i=0; i<N; i++) {
7515                ProviderInfo cpi =
7516                    (ProviderInfo)providers.get(i);
7517                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7518                        cpi.name, cpi.flags);
7519                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7520                    // This is a singleton provider, but a user besides the
7521                    // default user is asking to initialize a process it runs
7522                    // in...  well, no, it doesn't actually run in this process,
7523                    // it runs in the process of the default user.  Get rid of it.
7524                    providers.remove(i);
7525                    N--;
7526                    i--;
7527                    continue;
7528                }
7529
7530                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7531                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7532                if (cpr == null) {
7533                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7534                    mProviderMap.putProviderByClass(comp, cpr);
7535                }
7536                if (DEBUG_MU)
7537                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7538                app.pubProviders.put(cpi.name, cpr);
7539                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7540                    // Don't add this if it is a platform component that is marked
7541                    // to run in multiple processes, because this is actually
7542                    // part of the framework so doesn't make sense to track as a
7543                    // separate apk in the process.
7544                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7545                }
7546                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7547            }
7548        }
7549        return providers;
7550    }
7551
7552    /**
7553     * Check if {@link ProcessRecord} has a possible chance at accessing the
7554     * given {@link ProviderInfo}. Final permission checking is always done
7555     * in {@link ContentProvider}.
7556     */
7557    private final String checkContentProviderPermissionLocked(
7558            ProviderInfo cpi, ProcessRecord r) {
7559        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7560        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7561        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7562                cpi.applicationInfo.uid, cpi.exported)
7563                == PackageManager.PERMISSION_GRANTED) {
7564            return null;
7565        }
7566        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7567                cpi.applicationInfo.uid, cpi.exported)
7568                == PackageManager.PERMISSION_GRANTED) {
7569            return null;
7570        }
7571
7572        PathPermission[] pps = cpi.pathPermissions;
7573        if (pps != null) {
7574            int i = pps.length;
7575            while (i > 0) {
7576                i--;
7577                PathPermission pp = pps[i];
7578                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7579                        cpi.applicationInfo.uid, cpi.exported)
7580                        == PackageManager.PERMISSION_GRANTED) {
7581                    return null;
7582                }
7583                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7584                        cpi.applicationInfo.uid, cpi.exported)
7585                        == PackageManager.PERMISSION_GRANTED) {
7586                    return null;
7587                }
7588            }
7589        }
7590
7591        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7592        if (perms != null) {
7593            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
7594                if (uri.getKey().getAuthority().equals(cpi.authority)) {
7595                    return null;
7596                }
7597            }
7598        }
7599
7600        String msg;
7601        if (!cpi.exported) {
7602            msg = "Permission Denial: opening provider " + cpi.name
7603                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7604                    + ", uid=" + callingUid + ") that is not exported from uid "
7605                    + cpi.applicationInfo.uid;
7606        } else {
7607            msg = "Permission Denial: opening provider " + cpi.name
7608                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7609                    + ", uid=" + callingUid + ") requires "
7610                    + cpi.readPermission + " or " + cpi.writePermission;
7611        }
7612        Slog.w(TAG, msg);
7613        return msg;
7614    }
7615
7616    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7617            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7618        if (r != null) {
7619            for (int i=0; i<r.conProviders.size(); i++) {
7620                ContentProviderConnection conn = r.conProviders.get(i);
7621                if (conn.provider == cpr) {
7622                    if (DEBUG_PROVIDER) Slog.v(TAG,
7623                            "Adding provider requested by "
7624                            + r.processName + " from process "
7625                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7626                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7627                    if (stable) {
7628                        conn.stableCount++;
7629                        conn.numStableIncs++;
7630                    } else {
7631                        conn.unstableCount++;
7632                        conn.numUnstableIncs++;
7633                    }
7634                    return conn;
7635                }
7636            }
7637            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7638            if (stable) {
7639                conn.stableCount = 1;
7640                conn.numStableIncs = 1;
7641            } else {
7642                conn.unstableCount = 1;
7643                conn.numUnstableIncs = 1;
7644            }
7645            cpr.connections.add(conn);
7646            r.conProviders.add(conn);
7647            return conn;
7648        }
7649        cpr.addExternalProcessHandleLocked(externalProcessToken);
7650        return null;
7651    }
7652
7653    boolean decProviderCountLocked(ContentProviderConnection conn,
7654            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7655        if (conn != null) {
7656            cpr = conn.provider;
7657            if (DEBUG_PROVIDER) Slog.v(TAG,
7658                    "Removing provider requested by "
7659                    + conn.client.processName + " from process "
7660                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7661                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7662            if (stable) {
7663                conn.stableCount--;
7664            } else {
7665                conn.unstableCount--;
7666            }
7667            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7668                cpr.connections.remove(conn);
7669                conn.client.conProviders.remove(conn);
7670                return true;
7671            }
7672            return false;
7673        }
7674        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7675        return false;
7676    }
7677
7678    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7679            String name, IBinder token, boolean stable, int userId) {
7680        ContentProviderRecord cpr;
7681        ContentProviderConnection conn = null;
7682        ProviderInfo cpi = null;
7683
7684        synchronized(this) {
7685            ProcessRecord r = null;
7686            if (caller != null) {
7687                r = getRecordForAppLocked(caller);
7688                if (r == null) {
7689                    throw new SecurityException(
7690                            "Unable to find app for caller " + caller
7691                          + " (pid=" + Binder.getCallingPid()
7692                          + ") when getting content provider " + name);
7693                }
7694            }
7695
7696            // First check if this content provider has been published...
7697            cpr = mProviderMap.getProviderByName(name, userId);
7698            boolean providerRunning = cpr != null;
7699            if (providerRunning) {
7700                cpi = cpr.info;
7701                String msg;
7702                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7703                    throw new SecurityException(msg);
7704                }
7705
7706                if (r != null && cpr.canRunHere(r)) {
7707                    // This provider has been published or is in the process
7708                    // of being published...  but it is also allowed to run
7709                    // in the caller's process, so don't make a connection
7710                    // and just let the caller instantiate its own instance.
7711                    ContentProviderHolder holder = cpr.newHolder(null);
7712                    // don't give caller the provider object, it needs
7713                    // to make its own.
7714                    holder.provider = null;
7715                    return holder;
7716                }
7717
7718                final long origId = Binder.clearCallingIdentity();
7719
7720                // In this case the provider instance already exists, so we can
7721                // return it right away.
7722                conn = incProviderCountLocked(r, cpr, token, stable);
7723                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7724                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7725                        // If this is a perceptible app accessing the provider,
7726                        // make sure to count it as being accessed and thus
7727                        // back up on the LRU list.  This is good because
7728                        // content providers are often expensive to start.
7729                        updateLruProcessLocked(cpr.proc, false, null);
7730                    }
7731                }
7732
7733                if (cpr.proc != null) {
7734                    if (false) {
7735                        if (cpr.name.flattenToShortString().equals(
7736                                "com.android.providers.calendar/.CalendarProvider2")) {
7737                            Slog.v(TAG, "****************** KILLING "
7738                                + cpr.name.flattenToShortString());
7739                            Process.killProcess(cpr.proc.pid);
7740                        }
7741                    }
7742                    boolean success = updateOomAdjLocked(cpr.proc);
7743                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7744                    // NOTE: there is still a race here where a signal could be
7745                    // pending on the process even though we managed to update its
7746                    // adj level.  Not sure what to do about this, but at least
7747                    // the race is now smaller.
7748                    if (!success) {
7749                        // Uh oh...  it looks like the provider's process
7750                        // has been killed on us.  We need to wait for a new
7751                        // process to be started, and make sure its death
7752                        // doesn't kill our process.
7753                        Slog.i(TAG,
7754                                "Existing provider " + cpr.name.flattenToShortString()
7755                                + " is crashing; detaching " + r);
7756                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7757                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7758                        if (!lastRef) {
7759                            // This wasn't the last ref our process had on
7760                            // the provider...  we have now been killed, bail.
7761                            return null;
7762                        }
7763                        providerRunning = false;
7764                        conn = null;
7765                    }
7766                }
7767
7768                Binder.restoreCallingIdentity(origId);
7769            }
7770
7771            boolean singleton;
7772            if (!providerRunning) {
7773                try {
7774                    cpi = AppGlobals.getPackageManager().
7775                        resolveContentProvider(name,
7776                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7777                } catch (RemoteException ex) {
7778                }
7779                if (cpi == null) {
7780                    return null;
7781                }
7782                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7783                        cpi.name, cpi.flags);
7784                if (singleton) {
7785                    userId = 0;
7786                }
7787                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7788
7789                String msg;
7790                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7791                    throw new SecurityException(msg);
7792                }
7793
7794                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
7795                        && !cpi.processName.equals("system")) {
7796                    // If this content provider does not run in the system
7797                    // process, and the system is not yet ready to run other
7798                    // processes, then fail fast instead of hanging.
7799                    throw new IllegalArgumentException(
7800                            "Attempt to launch content provider before system ready");
7801                }
7802
7803                // Make sure that the user who owns this provider is started.  If not,
7804                // we don't want to allow it to run.
7805                if (mStartedUsers.get(userId) == null) {
7806                    Slog.w(TAG, "Unable to launch app "
7807                            + cpi.applicationInfo.packageName + "/"
7808                            + cpi.applicationInfo.uid + " for provider "
7809                            + name + ": user " + userId + " is stopped");
7810                    return null;
7811                }
7812
7813                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7814                cpr = mProviderMap.getProviderByClass(comp, userId);
7815                final boolean firstClass = cpr == null;
7816                if (firstClass) {
7817                    try {
7818                        ApplicationInfo ai =
7819                            AppGlobals.getPackageManager().
7820                                getApplicationInfo(
7821                                        cpi.applicationInfo.packageName,
7822                                        STOCK_PM_FLAGS, userId);
7823                        if (ai == null) {
7824                            Slog.w(TAG, "No package info for content provider "
7825                                    + cpi.name);
7826                            return null;
7827                        }
7828                        ai = getAppInfoForUser(ai, userId);
7829                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
7830                    } catch (RemoteException ex) {
7831                        // pm is in same process, this will never happen.
7832                    }
7833                }
7834
7835                if (r != null && cpr.canRunHere(r)) {
7836                    // If this is a multiprocess provider, then just return its
7837                    // info and allow the caller to instantiate it.  Only do
7838                    // this if the provider is the same user as the caller's
7839                    // process, or can run as root (so can be in any process).
7840                    return cpr.newHolder(null);
7841                }
7842
7843                if (DEBUG_PROVIDER) {
7844                    RuntimeException e = new RuntimeException("here");
7845                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
7846                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
7847                }
7848
7849                // This is single process, and our app is now connecting to it.
7850                // See if we are already in the process of launching this
7851                // provider.
7852                final int N = mLaunchingProviders.size();
7853                int i;
7854                for (i=0; i<N; i++) {
7855                    if (mLaunchingProviders.get(i) == cpr) {
7856                        break;
7857                    }
7858                }
7859
7860                // If the provider is not already being launched, then get it
7861                // started.
7862                if (i >= N) {
7863                    final long origId = Binder.clearCallingIdentity();
7864
7865                    try {
7866                        // Content provider is now in use, its package can't be stopped.
7867                        try {
7868                            AppGlobals.getPackageManager().setPackageStoppedState(
7869                                    cpr.appInfo.packageName, false, userId);
7870                        } catch (RemoteException e) {
7871                        } catch (IllegalArgumentException e) {
7872                            Slog.w(TAG, "Failed trying to unstop package "
7873                                    + cpr.appInfo.packageName + ": " + e);
7874                        }
7875
7876                        // Use existing process if already started
7877                        ProcessRecord proc = getProcessRecordLocked(
7878                                cpi.processName, cpr.appInfo.uid, false);
7879                        if (proc != null && proc.thread != null) {
7880                            if (DEBUG_PROVIDER) {
7881                                Slog.d(TAG, "Installing in existing process " + proc);
7882                            }
7883                            proc.pubProviders.put(cpi.name, cpr);
7884                            try {
7885                                proc.thread.scheduleInstallProvider(cpi);
7886                            } catch (RemoteException e) {
7887                            }
7888                        } else {
7889                            proc = startProcessLocked(cpi.processName,
7890                                    cpr.appInfo, false, 0, "content provider",
7891                                    new ComponentName(cpi.applicationInfo.packageName,
7892                                            cpi.name), false, false, false);
7893                            if (proc == null) {
7894                                Slog.w(TAG, "Unable to launch app "
7895                                        + cpi.applicationInfo.packageName + "/"
7896                                        + cpi.applicationInfo.uid + " for provider "
7897                                        + name + ": process is bad");
7898                                return null;
7899                            }
7900                        }
7901                        cpr.launchingApp = proc;
7902                        mLaunchingProviders.add(cpr);
7903                    } finally {
7904                        Binder.restoreCallingIdentity(origId);
7905                    }
7906                }
7907
7908                // Make sure the provider is published (the same provider class
7909                // may be published under multiple names).
7910                if (firstClass) {
7911                    mProviderMap.putProviderByClass(comp, cpr);
7912                }
7913
7914                mProviderMap.putProviderByName(name, cpr);
7915                conn = incProviderCountLocked(r, cpr, token, stable);
7916                if (conn != null) {
7917                    conn.waiting = true;
7918                }
7919            }
7920        }
7921
7922        // Wait for the provider to be published...
7923        synchronized (cpr) {
7924            while (cpr.provider == null) {
7925                if (cpr.launchingApp == null) {
7926                    Slog.w(TAG, "Unable to launch app "
7927                            + cpi.applicationInfo.packageName + "/"
7928                            + cpi.applicationInfo.uid + " for provider "
7929                            + name + ": launching app became null");
7930                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
7931                            UserHandle.getUserId(cpi.applicationInfo.uid),
7932                            cpi.applicationInfo.packageName,
7933                            cpi.applicationInfo.uid, name);
7934                    return null;
7935                }
7936                try {
7937                    if (DEBUG_MU) {
7938                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
7939                                + cpr.launchingApp);
7940                    }
7941                    if (conn != null) {
7942                        conn.waiting = true;
7943                    }
7944                    cpr.wait();
7945                } catch (InterruptedException ex) {
7946                } finally {
7947                    if (conn != null) {
7948                        conn.waiting = false;
7949                    }
7950                }
7951            }
7952        }
7953        return cpr != null ? cpr.newHolder(conn) : null;
7954    }
7955
7956    public final ContentProviderHolder getContentProvider(
7957            IApplicationThread caller, String name, int userId, boolean stable) {
7958        enforceNotIsolatedCaller("getContentProvider");
7959        if (caller == null) {
7960            String msg = "null IApplicationThread when getting content provider "
7961                    + name;
7962            Slog.w(TAG, msg);
7963            throw new SecurityException(msg);
7964        }
7965
7966        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7967                false, true, "getContentProvider", null);
7968        return getContentProviderImpl(caller, name, null, stable, userId);
7969    }
7970
7971    public ContentProviderHolder getContentProviderExternal(
7972            String name, int userId, IBinder token) {
7973        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7974            "Do not have permission in call getContentProviderExternal()");
7975        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7976                false, true, "getContentProvider", null);
7977        return getContentProviderExternalUnchecked(name, token, userId);
7978    }
7979
7980    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
7981            IBinder token, int userId) {
7982        return getContentProviderImpl(null, name, token, true, userId);
7983    }
7984
7985    /**
7986     * Drop a content provider from a ProcessRecord's bookkeeping
7987     */
7988    public void removeContentProvider(IBinder connection, boolean stable) {
7989        enforceNotIsolatedCaller("removeContentProvider");
7990        long ident = Binder.clearCallingIdentity();
7991        try {
7992            synchronized (this) {
7993                ContentProviderConnection conn;
7994                try {
7995                    conn = (ContentProviderConnection)connection;
7996                } catch (ClassCastException e) {
7997                    String msg ="removeContentProvider: " + connection
7998                            + " not a ContentProviderConnection";
7999                    Slog.w(TAG, msg);
8000                    throw new IllegalArgumentException(msg);
8001                }
8002                if (conn == null) {
8003                    throw new NullPointerException("connection is null");
8004                }
8005                if (decProviderCountLocked(conn, null, null, stable)) {
8006                    updateOomAdjLocked();
8007                }
8008            }
8009        } finally {
8010            Binder.restoreCallingIdentity(ident);
8011        }
8012    }
8013
8014    public void removeContentProviderExternal(String name, IBinder token) {
8015        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8016            "Do not have permission in call removeContentProviderExternal()");
8017        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8018    }
8019
8020    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8021        synchronized (this) {
8022            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8023            if(cpr == null) {
8024                //remove from mProvidersByClass
8025                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8026                return;
8027            }
8028
8029            //update content provider record entry info
8030            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8031            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8032            if (localCpr.hasExternalProcessHandles()) {
8033                if (localCpr.removeExternalProcessHandleLocked(token)) {
8034                    updateOomAdjLocked();
8035                } else {
8036                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8037                            + " with no external reference for token: "
8038                            + token + ".");
8039                }
8040            } else {
8041                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8042                        + " with no external references.");
8043            }
8044        }
8045    }
8046
8047    public final void publishContentProviders(IApplicationThread caller,
8048            List<ContentProviderHolder> providers) {
8049        if (providers == null) {
8050            return;
8051        }
8052
8053        enforceNotIsolatedCaller("publishContentProviders");
8054        synchronized (this) {
8055            final ProcessRecord r = getRecordForAppLocked(caller);
8056            if (DEBUG_MU)
8057                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8058            if (r == null) {
8059                throw new SecurityException(
8060                        "Unable to find app for caller " + caller
8061                      + " (pid=" + Binder.getCallingPid()
8062                      + ") when publishing content providers");
8063            }
8064
8065            final long origId = Binder.clearCallingIdentity();
8066
8067            final int N = providers.size();
8068            for (int i=0; i<N; i++) {
8069                ContentProviderHolder src = providers.get(i);
8070                if (src == null || src.info == null || src.provider == null) {
8071                    continue;
8072                }
8073                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8074                if (DEBUG_MU)
8075                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8076                if (dst != null) {
8077                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8078                    mProviderMap.putProviderByClass(comp, dst);
8079                    String names[] = dst.info.authority.split(";");
8080                    for (int j = 0; j < names.length; j++) {
8081                        mProviderMap.putProviderByName(names[j], dst);
8082                    }
8083
8084                    int NL = mLaunchingProviders.size();
8085                    int j;
8086                    for (j=0; j<NL; j++) {
8087                        if (mLaunchingProviders.get(j) == dst) {
8088                            mLaunchingProviders.remove(j);
8089                            j--;
8090                            NL--;
8091                        }
8092                    }
8093                    synchronized (dst) {
8094                        dst.provider = src.provider;
8095                        dst.proc = r;
8096                        dst.notifyAll();
8097                    }
8098                    updateOomAdjLocked(r);
8099                }
8100            }
8101
8102            Binder.restoreCallingIdentity(origId);
8103        }
8104    }
8105
8106    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8107        ContentProviderConnection conn;
8108        try {
8109            conn = (ContentProviderConnection)connection;
8110        } catch (ClassCastException e) {
8111            String msg ="refContentProvider: " + connection
8112                    + " not a ContentProviderConnection";
8113            Slog.w(TAG, msg);
8114            throw new IllegalArgumentException(msg);
8115        }
8116        if (conn == null) {
8117            throw new NullPointerException("connection is null");
8118        }
8119
8120        synchronized (this) {
8121            if (stable > 0) {
8122                conn.numStableIncs += stable;
8123            }
8124            stable = conn.stableCount + stable;
8125            if (stable < 0) {
8126                throw new IllegalStateException("stableCount < 0: " + stable);
8127            }
8128
8129            if (unstable > 0) {
8130                conn.numUnstableIncs += unstable;
8131            }
8132            unstable = conn.unstableCount + unstable;
8133            if (unstable < 0) {
8134                throw new IllegalStateException("unstableCount < 0: " + unstable);
8135            }
8136
8137            if ((stable+unstable) <= 0) {
8138                throw new IllegalStateException("ref counts can't go to zero here: stable="
8139                        + stable + " unstable=" + unstable);
8140            }
8141            conn.stableCount = stable;
8142            conn.unstableCount = unstable;
8143            return !conn.dead;
8144        }
8145    }
8146
8147    public void unstableProviderDied(IBinder connection) {
8148        ContentProviderConnection conn;
8149        try {
8150            conn = (ContentProviderConnection)connection;
8151        } catch (ClassCastException e) {
8152            String msg ="refContentProvider: " + connection
8153                    + " not a ContentProviderConnection";
8154            Slog.w(TAG, msg);
8155            throw new IllegalArgumentException(msg);
8156        }
8157        if (conn == null) {
8158            throw new NullPointerException("connection is null");
8159        }
8160
8161        // Safely retrieve the content provider associated with the connection.
8162        IContentProvider provider;
8163        synchronized (this) {
8164            provider = conn.provider.provider;
8165        }
8166
8167        if (provider == null) {
8168            // Um, yeah, we're way ahead of you.
8169            return;
8170        }
8171
8172        // Make sure the caller is being honest with us.
8173        if (provider.asBinder().pingBinder()) {
8174            // Er, no, still looks good to us.
8175            synchronized (this) {
8176                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8177                        + " says " + conn + " died, but we don't agree");
8178                return;
8179            }
8180        }
8181
8182        // Well look at that!  It's dead!
8183        synchronized (this) {
8184            if (conn.provider.provider != provider) {
8185                // But something changed...  good enough.
8186                return;
8187            }
8188
8189            ProcessRecord proc = conn.provider.proc;
8190            if (proc == null || proc.thread == null) {
8191                // Seems like the process is already cleaned up.
8192                return;
8193            }
8194
8195            // As far as we're concerned, this is just like receiving a
8196            // death notification...  just a bit prematurely.
8197            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8198                    + ") early provider death");
8199            final long ident = Binder.clearCallingIdentity();
8200            try {
8201                appDiedLocked(proc, proc.pid, proc.thread);
8202            } finally {
8203                Binder.restoreCallingIdentity(ident);
8204            }
8205        }
8206    }
8207
8208    @Override
8209    public void appNotRespondingViaProvider(IBinder connection) {
8210        enforceCallingPermission(
8211                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8212
8213        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8214        if (conn == null) {
8215            Slog.w(TAG, "ContentProviderConnection is null");
8216            return;
8217        }
8218
8219        final ProcessRecord host = conn.provider.proc;
8220        if (host == null) {
8221            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8222            return;
8223        }
8224
8225        final long token = Binder.clearCallingIdentity();
8226        try {
8227            appNotResponding(host, null, null, false, "ContentProvider not responding");
8228        } finally {
8229            Binder.restoreCallingIdentity(token);
8230        }
8231    }
8232
8233    public final void installSystemProviders() {
8234        List<ProviderInfo> providers;
8235        synchronized (this) {
8236            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8237            providers = generateApplicationProvidersLocked(app);
8238            if (providers != null) {
8239                for (int i=providers.size()-1; i>=0; i--) {
8240                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8241                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8242                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8243                                + ": not system .apk");
8244                        providers.remove(i);
8245                    }
8246                }
8247            }
8248        }
8249        if (providers != null) {
8250            mSystemThread.installSystemProviders(providers);
8251        }
8252
8253        mCoreSettingsObserver = new CoreSettingsObserver(this);
8254
8255        mUsageStatsService.monitorPackages();
8256    }
8257
8258    /**
8259     * Allows app to retrieve the MIME type of a URI without having permission
8260     * to access its content provider.
8261     *
8262     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8263     *
8264     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8265     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8266     */
8267    public String getProviderMimeType(Uri uri, int userId) {
8268        enforceNotIsolatedCaller("getProviderMimeType");
8269        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8270                userId, false, true, "getProviderMimeType", null);
8271        final String name = uri.getAuthority();
8272        final long ident = Binder.clearCallingIdentity();
8273        ContentProviderHolder holder = null;
8274
8275        try {
8276            holder = getContentProviderExternalUnchecked(name, null, userId);
8277            if (holder != null) {
8278                return holder.provider.getType(uri);
8279            }
8280        } catch (RemoteException e) {
8281            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8282            return null;
8283        } finally {
8284            if (holder != null) {
8285                removeContentProviderExternalUnchecked(name, null, userId);
8286            }
8287            Binder.restoreCallingIdentity(ident);
8288        }
8289
8290        return null;
8291    }
8292
8293    // =========================================================
8294    // GLOBAL MANAGEMENT
8295    // =========================================================
8296
8297    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8298            boolean isolated) {
8299        String proc = customProcess != null ? customProcess : info.processName;
8300        BatteryStatsImpl.Uid.Proc ps = null;
8301        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8302        int uid = info.uid;
8303        if (isolated) {
8304            int userId = UserHandle.getUserId(uid);
8305            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8306            while (true) {
8307                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8308                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8309                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8310                }
8311                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8312                mNextIsolatedProcessUid++;
8313                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8314                    // No process for this uid, use it.
8315                    break;
8316                }
8317                stepsLeft--;
8318                if (stepsLeft <= 0) {
8319                    return null;
8320                }
8321            }
8322        }
8323        return new ProcessRecord(stats, info, proc, uid);
8324    }
8325
8326    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8327        ProcessRecord app;
8328        if (!isolated) {
8329            app = getProcessRecordLocked(info.processName, info.uid, true);
8330        } else {
8331            app = null;
8332        }
8333
8334        if (app == null) {
8335            app = newProcessRecordLocked(info, null, isolated);
8336            mProcessNames.put(info.processName, app.uid, app);
8337            if (isolated) {
8338                mIsolatedProcesses.put(app.uid, app);
8339            }
8340            updateLruProcessLocked(app, false, null);
8341            updateOomAdjLocked();
8342        }
8343
8344        // This package really, really can not be stopped.
8345        try {
8346            AppGlobals.getPackageManager().setPackageStoppedState(
8347                    info.packageName, false, UserHandle.getUserId(app.uid));
8348        } catch (RemoteException e) {
8349        } catch (IllegalArgumentException e) {
8350            Slog.w(TAG, "Failed trying to unstop package "
8351                    + info.packageName + ": " + e);
8352        }
8353
8354        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8355                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8356            app.persistent = true;
8357            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8358        }
8359        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8360            mPersistentStartingProcesses.add(app);
8361            startProcessLocked(app, "added application", app.processName);
8362        }
8363
8364        return app;
8365    }
8366
8367    public void unhandledBack() {
8368        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8369                "unhandledBack()");
8370
8371        synchronized(this) {
8372            final long origId = Binder.clearCallingIdentity();
8373            try {
8374                getFocusedStack().unhandledBackLocked();
8375            } finally {
8376                Binder.restoreCallingIdentity(origId);
8377            }
8378        }
8379    }
8380
8381    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8382        enforceNotIsolatedCaller("openContentUri");
8383        final int userId = UserHandle.getCallingUserId();
8384        String name = uri.getAuthority();
8385        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8386        ParcelFileDescriptor pfd = null;
8387        if (cph != null) {
8388            // We record the binder invoker's uid in thread-local storage before
8389            // going to the content provider to open the file.  Later, in the code
8390            // that handles all permissions checks, we look for this uid and use
8391            // that rather than the Activity Manager's own uid.  The effect is that
8392            // we do the check against the caller's permissions even though it looks
8393            // to the content provider like the Activity Manager itself is making
8394            // the request.
8395            sCallerIdentity.set(new Identity(
8396                    Binder.getCallingPid(), Binder.getCallingUid()));
8397            try {
8398                pfd = cph.provider.openFile(null, uri, "r", null);
8399            } catch (FileNotFoundException e) {
8400                // do nothing; pfd will be returned null
8401            } finally {
8402                // Ensure that whatever happens, we clean up the identity state
8403                sCallerIdentity.remove();
8404            }
8405
8406            // We've got the fd now, so we're done with the provider.
8407            removeContentProviderExternalUnchecked(name, null, userId);
8408        } else {
8409            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8410        }
8411        return pfd;
8412    }
8413
8414    // Actually is sleeping or shutting down or whatever else in the future
8415    // is an inactive state.
8416    public boolean isSleepingOrShuttingDown() {
8417        return mSleeping || mShuttingDown;
8418    }
8419
8420    public void goingToSleep() {
8421        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8422                != PackageManager.PERMISSION_GRANTED) {
8423            throw new SecurityException("Requires permission "
8424                    + android.Manifest.permission.DEVICE_POWER);
8425        }
8426
8427        synchronized(this) {
8428            mWentToSleep = true;
8429            updateEventDispatchingLocked();
8430
8431            if (!mSleeping) {
8432                mSleeping = true;
8433                mStackSupervisor.goingToSleepLocked();
8434
8435                // Initialize the wake times of all processes.
8436                checkExcessivePowerUsageLocked(false);
8437                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8438                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8439                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8440            }
8441        }
8442    }
8443
8444    @Override
8445    public boolean shutdown(int timeout) {
8446        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8447                != PackageManager.PERMISSION_GRANTED) {
8448            throw new SecurityException("Requires permission "
8449                    + android.Manifest.permission.SHUTDOWN);
8450        }
8451
8452        boolean timedout = false;
8453
8454        synchronized(this) {
8455            mShuttingDown = true;
8456            updateEventDispatchingLocked();
8457            timedout = mStackSupervisor.shutdownLocked(timeout);
8458        }
8459
8460        mAppOpsService.shutdown();
8461        mUsageStatsService.shutdown();
8462        mBatteryStatsService.shutdown();
8463        synchronized (this) {
8464            mProcessStats.shutdownLocked();
8465        }
8466
8467        return timedout;
8468    }
8469
8470    public final void activitySlept(IBinder token) {
8471        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8472
8473        final long origId = Binder.clearCallingIdentity();
8474
8475        synchronized (this) {
8476            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8477            if (r != null) {
8478                mStackSupervisor.activitySleptLocked(r);
8479            }
8480        }
8481
8482        Binder.restoreCallingIdentity(origId);
8483    }
8484
8485    void logLockScreen(String msg) {
8486        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8487                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8488                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8489                mStackSupervisor.mDismissKeyguardOnNextActivity);
8490    }
8491
8492    private void comeOutOfSleepIfNeededLocked() {
8493        if (!mWentToSleep && !mLockScreenShown) {
8494            if (mSleeping) {
8495                mSleeping = false;
8496                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8497            }
8498        }
8499    }
8500
8501    public void wakingUp() {
8502        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8503                != PackageManager.PERMISSION_GRANTED) {
8504            throw new SecurityException("Requires permission "
8505                    + android.Manifest.permission.DEVICE_POWER);
8506        }
8507
8508        synchronized(this) {
8509            mWentToSleep = false;
8510            updateEventDispatchingLocked();
8511            comeOutOfSleepIfNeededLocked();
8512        }
8513    }
8514
8515    private void updateEventDispatchingLocked() {
8516        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8517    }
8518
8519    public void setLockScreenShown(boolean shown) {
8520        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8521                != PackageManager.PERMISSION_GRANTED) {
8522            throw new SecurityException("Requires permission "
8523                    + android.Manifest.permission.DEVICE_POWER);
8524        }
8525
8526        synchronized(this) {
8527            long ident = Binder.clearCallingIdentity();
8528            try {
8529                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8530                mLockScreenShown = shown;
8531                comeOutOfSleepIfNeededLocked();
8532            } finally {
8533                Binder.restoreCallingIdentity(ident);
8534            }
8535        }
8536    }
8537
8538    public void stopAppSwitches() {
8539        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8540                != PackageManager.PERMISSION_GRANTED) {
8541            throw new SecurityException("Requires permission "
8542                    + android.Manifest.permission.STOP_APP_SWITCHES);
8543        }
8544
8545        synchronized(this) {
8546            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8547                    + APP_SWITCH_DELAY_TIME;
8548            mDidAppSwitch = false;
8549            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8550            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8551            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8552        }
8553    }
8554
8555    public void resumeAppSwitches() {
8556        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8557                != PackageManager.PERMISSION_GRANTED) {
8558            throw new SecurityException("Requires permission "
8559                    + android.Manifest.permission.STOP_APP_SWITCHES);
8560        }
8561
8562        synchronized(this) {
8563            // Note that we don't execute any pending app switches... we will
8564            // let those wait until either the timeout, or the next start
8565            // activity request.
8566            mAppSwitchesAllowedTime = 0;
8567        }
8568    }
8569
8570    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8571            String name) {
8572        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8573            return true;
8574        }
8575
8576        final int perm = checkComponentPermission(
8577                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8578                callingUid, -1, true);
8579        if (perm == PackageManager.PERMISSION_GRANTED) {
8580            return true;
8581        }
8582
8583        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8584        return false;
8585    }
8586
8587    public void setDebugApp(String packageName, boolean waitForDebugger,
8588            boolean persistent) {
8589        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8590                "setDebugApp()");
8591
8592        long ident = Binder.clearCallingIdentity();
8593        try {
8594            // Note that this is not really thread safe if there are multiple
8595            // callers into it at the same time, but that's not a situation we
8596            // care about.
8597            if (persistent) {
8598                final ContentResolver resolver = mContext.getContentResolver();
8599                Settings.Global.putString(
8600                    resolver, Settings.Global.DEBUG_APP,
8601                    packageName);
8602                Settings.Global.putInt(
8603                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8604                    waitForDebugger ? 1 : 0);
8605            }
8606
8607            synchronized (this) {
8608                if (!persistent) {
8609                    mOrigDebugApp = mDebugApp;
8610                    mOrigWaitForDebugger = mWaitForDebugger;
8611                }
8612                mDebugApp = packageName;
8613                mWaitForDebugger = waitForDebugger;
8614                mDebugTransient = !persistent;
8615                if (packageName != null) {
8616                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8617                            false, UserHandle.USER_ALL, "set debug app");
8618                }
8619            }
8620        } finally {
8621            Binder.restoreCallingIdentity(ident);
8622        }
8623    }
8624
8625    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8626        synchronized (this) {
8627            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8628            if (!isDebuggable) {
8629                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8630                    throw new SecurityException("Process not debuggable: " + app.packageName);
8631                }
8632            }
8633
8634            mOpenGlTraceApp = processName;
8635        }
8636    }
8637
8638    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8639            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8640        synchronized (this) {
8641            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8642            if (!isDebuggable) {
8643                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8644                    throw new SecurityException("Process not debuggable: " + app.packageName);
8645                }
8646            }
8647            mProfileApp = processName;
8648            mProfileFile = profileFile;
8649            if (mProfileFd != null) {
8650                try {
8651                    mProfileFd.close();
8652                } catch (IOException e) {
8653                }
8654                mProfileFd = null;
8655            }
8656            mProfileFd = profileFd;
8657            mProfileType = 0;
8658            mAutoStopProfiler = autoStopProfiler;
8659        }
8660    }
8661
8662    @Override
8663    public void setAlwaysFinish(boolean enabled) {
8664        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8665                "setAlwaysFinish()");
8666
8667        Settings.Global.putInt(
8668                mContext.getContentResolver(),
8669                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8670
8671        synchronized (this) {
8672            mAlwaysFinishActivities = enabled;
8673        }
8674    }
8675
8676    @Override
8677    public void setActivityController(IActivityController controller) {
8678        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8679                "setActivityController()");
8680        synchronized (this) {
8681            mController = controller;
8682            Watchdog.getInstance().setActivityController(controller);
8683        }
8684    }
8685
8686    @Override
8687    public void setUserIsMonkey(boolean userIsMonkey) {
8688        synchronized (this) {
8689            synchronized (mPidsSelfLocked) {
8690                final int callingPid = Binder.getCallingPid();
8691                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8692                if (precessRecord == null) {
8693                    throw new SecurityException("Unknown process: " + callingPid);
8694                }
8695                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8696                    throw new SecurityException("Only an instrumentation process "
8697                            + "with a UiAutomation can call setUserIsMonkey");
8698                }
8699            }
8700            mUserIsMonkey = userIsMonkey;
8701        }
8702    }
8703
8704    @Override
8705    public boolean isUserAMonkey() {
8706        synchronized (this) {
8707            // If there is a controller also implies the user is a monkey.
8708            return (mUserIsMonkey || mController != null);
8709        }
8710    }
8711
8712    public void requestBugReport() {
8713        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8714        SystemProperties.set("ctl.start", "bugreport");
8715    }
8716
8717    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8718        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8719    }
8720
8721    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8722        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8723            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8724        }
8725        return KEY_DISPATCHING_TIMEOUT;
8726    }
8727
8728    @Override
8729    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8730        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8731                != PackageManager.PERMISSION_GRANTED) {
8732            throw new SecurityException("Requires permission "
8733                    + android.Manifest.permission.FILTER_EVENTS);
8734        }
8735        ProcessRecord proc;
8736        long timeout;
8737        synchronized (this) {
8738            synchronized (mPidsSelfLocked) {
8739                proc = mPidsSelfLocked.get(pid);
8740            }
8741            timeout = getInputDispatchingTimeoutLocked(proc);
8742        }
8743
8744        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8745            return -1;
8746        }
8747
8748        return timeout;
8749    }
8750
8751    /**
8752     * Handle input dispatching timeouts.
8753     * Returns whether input dispatching should be aborted or not.
8754     */
8755    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8756            final ActivityRecord activity, final ActivityRecord parent,
8757            final boolean aboveSystem, String reason) {
8758        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8759                != PackageManager.PERMISSION_GRANTED) {
8760            throw new SecurityException("Requires permission "
8761                    + android.Manifest.permission.FILTER_EVENTS);
8762        }
8763
8764        final String annotation;
8765        if (reason == null) {
8766            annotation = "Input dispatching timed out";
8767        } else {
8768            annotation = "Input dispatching timed out (" + reason + ")";
8769        }
8770
8771        if (proc != null) {
8772            synchronized (this) {
8773                if (proc.debugging) {
8774                    return false;
8775                }
8776
8777                if (mDidDexOpt) {
8778                    // Give more time since we were dexopting.
8779                    mDidDexOpt = false;
8780                    return false;
8781                }
8782
8783                if (proc.instrumentationClass != null) {
8784                    Bundle info = new Bundle();
8785                    info.putString("shortMsg", "keyDispatchingTimedOut");
8786                    info.putString("longMsg", annotation);
8787                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8788                    return true;
8789                }
8790            }
8791            mHandler.post(new Runnable() {
8792                @Override
8793                public void run() {
8794                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
8795                }
8796            });
8797        }
8798
8799        return true;
8800    }
8801
8802    public Bundle getAssistContextExtras(int requestType) {
8803        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
8804                "getAssistContextExtras()");
8805        PendingAssistExtras pae;
8806        Bundle extras = new Bundle();
8807        synchronized (this) {
8808            ActivityRecord activity = getFocusedStack().mResumedActivity;
8809            if (activity == null) {
8810                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
8811                return null;
8812            }
8813            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
8814            if (activity.app == null || activity.app.thread == null) {
8815                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
8816                return extras;
8817            }
8818            if (activity.app.pid == Binder.getCallingPid()) {
8819                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
8820                return extras;
8821            }
8822            pae = new PendingAssistExtras(activity);
8823            try {
8824                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
8825                        requestType);
8826                mPendingAssistExtras.add(pae);
8827                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
8828            } catch (RemoteException e) {
8829                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
8830                return extras;
8831            }
8832        }
8833        synchronized (pae) {
8834            while (!pae.haveResult) {
8835                try {
8836                    pae.wait();
8837                } catch (InterruptedException e) {
8838                }
8839            }
8840            if (pae.result != null) {
8841                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
8842            }
8843        }
8844        synchronized (this) {
8845            mPendingAssistExtras.remove(pae);
8846            mHandler.removeCallbacks(pae);
8847        }
8848        return extras;
8849    }
8850
8851    public void reportAssistContextExtras(IBinder token, Bundle extras) {
8852        PendingAssistExtras pae = (PendingAssistExtras)token;
8853        synchronized (pae) {
8854            pae.result = extras;
8855            pae.haveResult = true;
8856            pae.notifyAll();
8857        }
8858    }
8859
8860    public void registerProcessObserver(IProcessObserver observer) {
8861        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8862                "registerProcessObserver()");
8863        synchronized (this) {
8864            mProcessObservers.register(observer);
8865        }
8866    }
8867
8868    @Override
8869    public void unregisterProcessObserver(IProcessObserver observer) {
8870        synchronized (this) {
8871            mProcessObservers.unregister(observer);
8872        }
8873    }
8874
8875    @Override
8876    public boolean convertFromTranslucent(IBinder token) {
8877        final long origId = Binder.clearCallingIdentity();
8878        try {
8879            synchronized (this) {
8880                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8881                if (r == null) {
8882                    return false;
8883                }
8884                if (r.changeWindowTranslucency(true)) {
8885                    mWindowManager.setAppFullscreen(token, true);
8886                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8887                    return true;
8888                }
8889                return false;
8890            }
8891        } finally {
8892            Binder.restoreCallingIdentity(origId);
8893        }
8894    }
8895
8896    @Override
8897    public boolean convertToTranslucent(IBinder token) {
8898        final long origId = Binder.clearCallingIdentity();
8899        try {
8900            synchronized (this) {
8901                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8902                if (r == null) {
8903                    return false;
8904                }
8905                if (r.changeWindowTranslucency(false)) {
8906                    r.task.stack.convertToTranslucent(r);
8907                    mWindowManager.setAppFullscreen(token, false);
8908                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8909                    return true;
8910                }
8911                return false;
8912            }
8913        } finally {
8914            Binder.restoreCallingIdentity(origId);
8915        }
8916    }
8917
8918    @Override
8919    public void setImmersive(IBinder token, boolean immersive) {
8920        synchronized(this) {
8921            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8922            if (r == null) {
8923                throw new IllegalArgumentException();
8924            }
8925            r.immersive = immersive;
8926
8927            // update associated state if we're frontmost
8928            if (r == mFocusedActivity) {
8929                if (DEBUG_IMMERSIVE) {
8930                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
8931                }
8932                applyUpdateLockStateLocked(r);
8933            }
8934        }
8935    }
8936
8937    @Override
8938    public boolean isImmersive(IBinder token) {
8939        synchronized (this) {
8940            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8941            if (r == null) {
8942                throw new IllegalArgumentException();
8943            }
8944            return r.immersive;
8945        }
8946    }
8947
8948    public boolean isTopActivityImmersive() {
8949        enforceNotIsolatedCaller("startActivity");
8950        synchronized (this) {
8951            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
8952            return (r != null) ? r.immersive : false;
8953        }
8954    }
8955
8956    public final void enterSafeMode() {
8957        synchronized(this) {
8958            // It only makes sense to do this before the system is ready
8959            // and started launching other packages.
8960            if (!mSystemReady) {
8961                try {
8962                    AppGlobals.getPackageManager().enterSafeMode();
8963                } catch (RemoteException e) {
8964                }
8965            }
8966        }
8967    }
8968
8969    public final void showSafeModeOverlay() {
8970        View v = LayoutInflater.from(mContext).inflate(
8971                com.android.internal.R.layout.safe_mode, null);
8972        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
8973        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
8974        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
8975        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
8976        lp.gravity = Gravity.BOTTOM | Gravity.START;
8977        lp.format = v.getBackground().getOpacity();
8978        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
8979                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
8980        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
8981        ((WindowManager)mContext.getSystemService(
8982                Context.WINDOW_SERVICE)).addView(v, lp);
8983    }
8984
8985    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
8986        if (!(sender instanceof PendingIntentRecord)) {
8987            return;
8988        }
8989        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8990        synchronized (stats) {
8991            if (mBatteryStatsService.isOnBattery()) {
8992                mBatteryStatsService.enforceCallingPermission();
8993                PendingIntentRecord rec = (PendingIntentRecord)sender;
8994                int MY_UID = Binder.getCallingUid();
8995                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
8996                BatteryStatsImpl.Uid.Pkg pkg =
8997                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
8998                            sourcePkg != null ? sourcePkg : rec.key.packageName);
8999                pkg.incWakeupsLocked();
9000            }
9001        }
9002    }
9003
9004    public boolean killPids(int[] pids, String pReason, boolean secure) {
9005        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9006            throw new SecurityException("killPids only available to the system");
9007        }
9008        String reason = (pReason == null) ? "Unknown" : pReason;
9009        // XXX Note: don't acquire main activity lock here, because the window
9010        // manager calls in with its locks held.
9011
9012        boolean killed = false;
9013        synchronized (mPidsSelfLocked) {
9014            int[] types = new int[pids.length];
9015            int worstType = 0;
9016            for (int i=0; i<pids.length; i++) {
9017                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9018                if (proc != null) {
9019                    int type = proc.setAdj;
9020                    types[i] = type;
9021                    if (type > worstType) {
9022                        worstType = type;
9023                    }
9024                }
9025            }
9026
9027            // If the worst oom_adj is somewhere in the cached proc LRU range,
9028            // then constrain it so we will kill all cached procs.
9029            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9030                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9031                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9032            }
9033
9034            // If this is not a secure call, don't let it kill processes that
9035            // are important.
9036            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9037                worstType = ProcessList.SERVICE_ADJ;
9038            }
9039
9040            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9041            for (int i=0; i<pids.length; i++) {
9042                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9043                if (proc == null) {
9044                    continue;
9045                }
9046                int adj = proc.setAdj;
9047                if (adj >= worstType && !proc.killedByAm) {
9048                    killUnneededProcessLocked(proc, reason);
9049                    killed = true;
9050                }
9051            }
9052        }
9053        return killed;
9054    }
9055
9056    @Override
9057    public void killUid(int uid, String reason) {
9058        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9059            throw new SecurityException("killUid only available to the system");
9060        }
9061        synchronized (this) {
9062            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9063                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9064                    reason != null ? reason : "kill uid");
9065        }
9066    }
9067
9068    @Override
9069    public boolean killProcessesBelowForeground(String reason) {
9070        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9071            throw new SecurityException("killProcessesBelowForeground() only available to system");
9072        }
9073
9074        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9075    }
9076
9077    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9078        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9079            throw new SecurityException("killProcessesBelowAdj() only available to system");
9080        }
9081
9082        boolean killed = false;
9083        synchronized (mPidsSelfLocked) {
9084            final int size = mPidsSelfLocked.size();
9085            for (int i = 0; i < size; i++) {
9086                final int pid = mPidsSelfLocked.keyAt(i);
9087                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9088                if (proc == null) continue;
9089
9090                final int adj = proc.setAdj;
9091                if (adj > belowAdj && !proc.killedByAm) {
9092                    killUnneededProcessLocked(proc, reason);
9093                    killed = true;
9094                }
9095            }
9096        }
9097        return killed;
9098    }
9099
9100    @Override
9101    public void hang(final IBinder who, boolean allowRestart) {
9102        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9103                != PackageManager.PERMISSION_GRANTED) {
9104            throw new SecurityException("Requires permission "
9105                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9106        }
9107
9108        final IBinder.DeathRecipient death = new DeathRecipient() {
9109            @Override
9110            public void binderDied() {
9111                synchronized (this) {
9112                    notifyAll();
9113                }
9114            }
9115        };
9116
9117        try {
9118            who.linkToDeath(death, 0);
9119        } catch (RemoteException e) {
9120            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9121            return;
9122        }
9123
9124        synchronized (this) {
9125            Watchdog.getInstance().setAllowRestart(allowRestart);
9126            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9127            synchronized (death) {
9128                while (who.isBinderAlive()) {
9129                    try {
9130                        death.wait();
9131                    } catch (InterruptedException e) {
9132                    }
9133                }
9134            }
9135            Watchdog.getInstance().setAllowRestart(true);
9136        }
9137    }
9138
9139    @Override
9140    public void restart() {
9141        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9142                != PackageManager.PERMISSION_GRANTED) {
9143            throw new SecurityException("Requires permission "
9144                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9145        }
9146
9147        Log.i(TAG, "Sending shutdown broadcast...");
9148
9149        BroadcastReceiver br = new BroadcastReceiver() {
9150            @Override public void onReceive(Context context, Intent intent) {
9151                // Now the broadcast is done, finish up the low-level shutdown.
9152                Log.i(TAG, "Shutting down activity manager...");
9153                shutdown(10000);
9154                Log.i(TAG, "Shutdown complete, restarting!");
9155                Process.killProcess(Process.myPid());
9156                System.exit(10);
9157            }
9158        };
9159
9160        // First send the high-level shut down broadcast.
9161        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9162        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9163        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9164        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9165        mContext.sendOrderedBroadcastAsUser(intent,
9166                UserHandle.ALL, null, br, mHandler, 0, null, null);
9167        */
9168        br.onReceive(mContext, intent);
9169    }
9170
9171    private long getLowRamTimeSinceIdle(long now) {
9172        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9173    }
9174
9175    @Override
9176    public void performIdleMaintenance() {
9177        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9178                != PackageManager.PERMISSION_GRANTED) {
9179            throw new SecurityException("Requires permission "
9180                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9181        }
9182
9183        synchronized (this) {
9184            final long now = SystemClock.uptimeMillis();
9185            final long timeSinceLastIdle = now - mLastIdleTime;
9186            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9187            mLastIdleTime = now;
9188            mLowRamTimeSinceLastIdle = 0;
9189            if (mLowRamStartTime != 0) {
9190                mLowRamStartTime = now;
9191            }
9192
9193            StringBuilder sb = new StringBuilder(128);
9194            sb.append("Idle maintenance over ");
9195            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9196            sb.append(" low RAM for ");
9197            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9198            Slog.i(TAG, sb.toString());
9199
9200            // If at least 1/3 of our time since the last idle period has been spent
9201            // with RAM low, then we want to kill processes.
9202            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9203
9204            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9205                ProcessRecord proc = mLruProcesses.get(i);
9206                if (proc.notCachedSinceIdle) {
9207                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9208                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9209                        if (doKilling && proc.initialIdlePss != 0
9210                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9211                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9212                                    + " from " + proc.initialIdlePss + ")");
9213                        }
9214                    }
9215                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9216                    proc.notCachedSinceIdle = true;
9217                    proc.initialIdlePss = 0;
9218                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9219                            mSleeping, now);
9220                }
9221            }
9222
9223            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9224            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9225        }
9226    }
9227
9228    public final void startRunning(String pkg, String cls, String action,
9229            String data) {
9230        synchronized(this) {
9231            if (mStartRunning) {
9232                return;
9233            }
9234            mStartRunning = true;
9235            mTopComponent = pkg != null && cls != null
9236                    ? new ComponentName(pkg, cls) : null;
9237            mTopAction = action != null ? action : Intent.ACTION_MAIN;
9238            mTopData = data;
9239            if (!mSystemReady) {
9240                return;
9241            }
9242        }
9243
9244        systemReady(null);
9245    }
9246
9247    private void retrieveSettings() {
9248        final ContentResolver resolver = mContext.getContentResolver();
9249        String debugApp = Settings.Global.getString(
9250            resolver, Settings.Global.DEBUG_APP);
9251        boolean waitForDebugger = Settings.Global.getInt(
9252            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9253        boolean alwaysFinishActivities = Settings.Global.getInt(
9254            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9255        boolean forceRtl = Settings.Global.getInt(
9256                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9257        // Transfer any global setting for forcing RTL layout, into a System Property
9258        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9259
9260        Configuration configuration = new Configuration();
9261        Settings.System.getConfiguration(resolver, configuration);
9262        if (forceRtl) {
9263            // This will take care of setting the correct layout direction flags
9264            configuration.setLayoutDirection(configuration.locale);
9265        }
9266
9267        synchronized (this) {
9268            mDebugApp = mOrigDebugApp = debugApp;
9269            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9270            mAlwaysFinishActivities = alwaysFinishActivities;
9271            // This happens before any activities are started, so we can
9272            // change mConfiguration in-place.
9273            updateConfigurationLocked(configuration, null, false, true);
9274            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9275        }
9276    }
9277
9278    public boolean testIsSystemReady() {
9279        // no need to synchronize(this) just to read & return the value
9280        return mSystemReady;
9281    }
9282
9283    private static File getCalledPreBootReceiversFile() {
9284        File dataDir = Environment.getDataDirectory();
9285        File systemDir = new File(dataDir, "system");
9286        File fname = new File(systemDir, "called_pre_boots.dat");
9287        return fname;
9288    }
9289
9290    static final int LAST_DONE_VERSION = 10000;
9291
9292    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9293        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9294        File file = getCalledPreBootReceiversFile();
9295        FileInputStream fis = null;
9296        try {
9297            fis = new FileInputStream(file);
9298            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9299            int fvers = dis.readInt();
9300            if (fvers == LAST_DONE_VERSION) {
9301                String vers = dis.readUTF();
9302                String codename = dis.readUTF();
9303                String build = dis.readUTF();
9304                if (android.os.Build.VERSION.RELEASE.equals(vers)
9305                        && android.os.Build.VERSION.CODENAME.equals(codename)
9306                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9307                    int num = dis.readInt();
9308                    while (num > 0) {
9309                        num--;
9310                        String pkg = dis.readUTF();
9311                        String cls = dis.readUTF();
9312                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9313                    }
9314                }
9315            }
9316        } catch (FileNotFoundException e) {
9317        } catch (IOException e) {
9318            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9319        } finally {
9320            if (fis != null) {
9321                try {
9322                    fis.close();
9323                } catch (IOException e) {
9324                }
9325            }
9326        }
9327        return lastDoneReceivers;
9328    }
9329
9330    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9331        File file = getCalledPreBootReceiversFile();
9332        FileOutputStream fos = null;
9333        DataOutputStream dos = null;
9334        try {
9335            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9336            fos = new FileOutputStream(file);
9337            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9338            dos.writeInt(LAST_DONE_VERSION);
9339            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9340            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9341            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9342            dos.writeInt(list.size());
9343            for (int i=0; i<list.size(); i++) {
9344                dos.writeUTF(list.get(i).getPackageName());
9345                dos.writeUTF(list.get(i).getClassName());
9346            }
9347        } catch (IOException e) {
9348            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9349            file.delete();
9350        } finally {
9351            FileUtils.sync(fos);
9352            if (dos != null) {
9353                try {
9354                    dos.close();
9355                } catch (IOException e) {
9356                    // TODO Auto-generated catch block
9357                    e.printStackTrace();
9358                }
9359            }
9360        }
9361    }
9362
9363    public void systemReady(final Runnable goingCallback) {
9364        synchronized(this) {
9365            if (mSystemReady) {
9366                if (goingCallback != null) goingCallback.run();
9367                return;
9368            }
9369
9370            // Check to see if there are any update receivers to run.
9371            if (!mDidUpdate) {
9372                if (mWaitingUpdate) {
9373                    return;
9374                }
9375                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9376                List<ResolveInfo> ris = null;
9377                try {
9378                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9379                            intent, null, 0, 0);
9380                } catch (RemoteException e) {
9381                }
9382                if (ris != null) {
9383                    for (int i=ris.size()-1; i>=0; i--) {
9384                        if ((ris.get(i).activityInfo.applicationInfo.flags
9385                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9386                            ris.remove(i);
9387                        }
9388                    }
9389                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9390
9391                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9392
9393                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9394                    for (int i=0; i<ris.size(); i++) {
9395                        ActivityInfo ai = ris.get(i).activityInfo;
9396                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9397                        if (lastDoneReceivers.contains(comp)) {
9398                            // We already did the pre boot receiver for this app with the current
9399                            // platform version, so don't do it again...
9400                            ris.remove(i);
9401                            i--;
9402                            // ...however, do keep it as one that has been done, so we don't
9403                            // forget about it when rewriting the file of last done receivers.
9404                            doneReceivers.add(comp);
9405                        }
9406                    }
9407
9408                    final int[] users = getUsersLocked();
9409                    for (int i=0; i<ris.size(); i++) {
9410                        ActivityInfo ai = ris.get(i).activityInfo;
9411                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9412                        doneReceivers.add(comp);
9413                        intent.setComponent(comp);
9414                        for (int j=0; j<users.length; j++) {
9415                            IIntentReceiver finisher = null;
9416                            if (i == ris.size()-1 && j == users.length-1) {
9417                                finisher = new IIntentReceiver.Stub() {
9418                                    public void performReceive(Intent intent, int resultCode,
9419                                            String data, Bundle extras, boolean ordered,
9420                                            boolean sticky, int sendingUser) {
9421                                        // The raw IIntentReceiver interface is called
9422                                        // with the AM lock held, so redispatch to
9423                                        // execute our code without the lock.
9424                                        mHandler.post(new Runnable() {
9425                                            public void run() {
9426                                                synchronized (ActivityManagerService.this) {
9427                                                    mDidUpdate = true;
9428                                                }
9429                                                writeLastDonePreBootReceivers(doneReceivers);
9430                                                showBootMessage(mContext.getText(
9431                                                        R.string.android_upgrading_complete),
9432                                                        false);
9433                                                systemReady(goingCallback);
9434                                            }
9435                                        });
9436                                    }
9437                                };
9438                            }
9439                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9440                                    + " for user " + users[j]);
9441                            broadcastIntentLocked(null, null, intent, null, finisher,
9442                                    0, null, null, null, AppOpsManager.OP_NONE,
9443                                    true, false, MY_PID, Process.SYSTEM_UID,
9444                                    users[j]);
9445                            if (finisher != null) {
9446                                mWaitingUpdate = true;
9447                            }
9448                        }
9449                    }
9450                }
9451                if (mWaitingUpdate) {
9452                    return;
9453                }
9454                mDidUpdate = true;
9455            }
9456
9457            mAppOpsService.systemReady();
9458            mSystemReady = true;
9459            if (!mStartRunning) {
9460                return;
9461            }
9462        }
9463
9464        ArrayList<ProcessRecord> procsToKill = null;
9465        synchronized(mPidsSelfLocked) {
9466            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9467                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9468                if (!isAllowedWhileBooting(proc.info)){
9469                    if (procsToKill == null) {
9470                        procsToKill = new ArrayList<ProcessRecord>();
9471                    }
9472                    procsToKill.add(proc);
9473                }
9474            }
9475        }
9476
9477        synchronized(this) {
9478            if (procsToKill != null) {
9479                for (int i=procsToKill.size()-1; i>=0; i--) {
9480                    ProcessRecord proc = procsToKill.get(i);
9481                    Slog.i(TAG, "Removing system update proc: " + proc);
9482                    removeProcessLocked(proc, true, false, "system update done");
9483                }
9484            }
9485
9486            // Now that we have cleaned up any update processes, we
9487            // are ready to start launching real processes and know that
9488            // we won't trample on them any more.
9489            mProcessesReady = true;
9490        }
9491
9492        Slog.i(TAG, "System now ready");
9493        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9494            SystemClock.uptimeMillis());
9495
9496        synchronized(this) {
9497            // Make sure we have no pre-ready processes sitting around.
9498
9499            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9500                ResolveInfo ri = mContext.getPackageManager()
9501                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9502                                STOCK_PM_FLAGS);
9503                CharSequence errorMsg = null;
9504                if (ri != null) {
9505                    ActivityInfo ai = ri.activityInfo;
9506                    ApplicationInfo app = ai.applicationInfo;
9507                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9508                        mTopAction = Intent.ACTION_FACTORY_TEST;
9509                        mTopData = null;
9510                        mTopComponent = new ComponentName(app.packageName,
9511                                ai.name);
9512                    } else {
9513                        errorMsg = mContext.getResources().getText(
9514                                com.android.internal.R.string.factorytest_not_system);
9515                    }
9516                } else {
9517                    errorMsg = mContext.getResources().getText(
9518                            com.android.internal.R.string.factorytest_no_action);
9519                }
9520                if (errorMsg != null) {
9521                    mTopAction = null;
9522                    mTopData = null;
9523                    mTopComponent = null;
9524                    Message msg = Message.obtain();
9525                    msg.what = SHOW_FACTORY_ERROR_MSG;
9526                    msg.getData().putCharSequence("msg", errorMsg);
9527                    mHandler.sendMessage(msg);
9528                }
9529            }
9530        }
9531
9532        retrieveSettings();
9533
9534        synchronized (this) {
9535            readGrantedUriPermissionsLocked();
9536        }
9537
9538        if (goingCallback != null) goingCallback.run();
9539
9540        synchronized (this) {
9541            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9542                try {
9543                    List apps = AppGlobals.getPackageManager().
9544                        getPersistentApplications(STOCK_PM_FLAGS);
9545                    if (apps != null) {
9546                        int N = apps.size();
9547                        int i;
9548                        for (i=0; i<N; i++) {
9549                            ApplicationInfo info
9550                                = (ApplicationInfo)apps.get(i);
9551                            if (info != null &&
9552                                    !info.packageName.equals("android")) {
9553                                addAppLocked(info, false);
9554                            }
9555                        }
9556                    }
9557                } catch (RemoteException ex) {
9558                    // pm is in same process, this will never happen.
9559                }
9560            }
9561
9562            // Start up initial activity.
9563            mBooting = true;
9564
9565            try {
9566                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9567                    Message msg = Message.obtain();
9568                    msg.what = SHOW_UID_ERROR_MSG;
9569                    mHandler.sendMessage(msg);
9570                }
9571            } catch (RemoteException e) {
9572            }
9573
9574            long ident = Binder.clearCallingIdentity();
9575            try {
9576                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9577                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9578                        | Intent.FLAG_RECEIVER_FOREGROUND);
9579                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9580                broadcastIntentLocked(null, null, intent,
9581                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9582                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9583                intent = new Intent(Intent.ACTION_USER_STARTING);
9584                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9585                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9586                broadcastIntentLocked(null, null, intent,
9587                        null, new IIntentReceiver.Stub() {
9588                            @Override
9589                            public void performReceive(Intent intent, int resultCode, String data,
9590                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9591                                    throws RemoteException {
9592                            }
9593                        }, 0, null, null,
9594                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9595                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9596            } finally {
9597                Binder.restoreCallingIdentity(ident);
9598            }
9599            mStackSupervisor.resumeTopActivitiesLocked();
9600            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9601        }
9602    }
9603
9604    private boolean makeAppCrashingLocked(ProcessRecord app,
9605            String shortMsg, String longMsg, String stackTrace) {
9606        app.crashing = true;
9607        app.crashingReport = generateProcessError(app,
9608                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9609        startAppProblemLocked(app);
9610        app.stopFreezingAllLocked();
9611        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9612    }
9613
9614    private void makeAppNotRespondingLocked(ProcessRecord app,
9615            String activity, String shortMsg, String longMsg) {
9616        app.notResponding = true;
9617        app.notRespondingReport = generateProcessError(app,
9618                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9619                activity, shortMsg, longMsg, null);
9620        startAppProblemLocked(app);
9621        app.stopFreezingAllLocked();
9622    }
9623
9624    /**
9625     * Generate a process error record, suitable for attachment to a ProcessRecord.
9626     *
9627     * @param app The ProcessRecord in which the error occurred.
9628     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9629     *                      ActivityManager.AppErrorStateInfo
9630     * @param activity The activity associated with the crash, if known.
9631     * @param shortMsg Short message describing the crash.
9632     * @param longMsg Long message describing the crash.
9633     * @param stackTrace Full crash stack trace, may be null.
9634     *
9635     * @return Returns a fully-formed AppErrorStateInfo record.
9636     */
9637    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9638            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9639        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9640
9641        report.condition = condition;
9642        report.processName = app.processName;
9643        report.pid = app.pid;
9644        report.uid = app.info.uid;
9645        report.tag = activity;
9646        report.shortMsg = shortMsg;
9647        report.longMsg = longMsg;
9648        report.stackTrace = stackTrace;
9649
9650        return report;
9651    }
9652
9653    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9654        synchronized (this) {
9655            app.crashing = false;
9656            app.crashingReport = null;
9657            app.notResponding = false;
9658            app.notRespondingReport = null;
9659            if (app.anrDialog == fromDialog) {
9660                app.anrDialog = null;
9661            }
9662            if (app.waitDialog == fromDialog) {
9663                app.waitDialog = null;
9664            }
9665            if (app.pid > 0 && app.pid != MY_PID) {
9666                handleAppCrashLocked(app, null, null, null);
9667                killUnneededProcessLocked(app, "user request after error");
9668            }
9669        }
9670    }
9671
9672    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9673            String stackTrace) {
9674        long now = SystemClock.uptimeMillis();
9675
9676        Long crashTime;
9677        if (!app.isolated) {
9678            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9679        } else {
9680            crashTime = null;
9681        }
9682        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9683            // This process loses!
9684            Slog.w(TAG, "Process " + app.info.processName
9685                    + " has crashed too many times: killing!");
9686            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9687                    app.userId, app.info.processName, app.uid);
9688            mStackSupervisor.handleAppCrashLocked(app);
9689            if (!app.persistent) {
9690                // We don't want to start this process again until the user
9691                // explicitly does so...  but for persistent process, we really
9692                // need to keep it running.  If a persistent process is actually
9693                // repeatedly crashing, then badness for everyone.
9694                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9695                        app.info.processName);
9696                if (!app.isolated) {
9697                    // XXX We don't have a way to mark isolated processes
9698                    // as bad, since they don't have a peristent identity.
9699                    mBadProcesses.put(app.info.processName, app.uid,
9700                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9701                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9702                }
9703                app.bad = true;
9704                app.removed = true;
9705                // Don't let services in this process be restarted and potentially
9706                // annoy the user repeatedly.  Unless it is persistent, since those
9707                // processes run critical code.
9708                removeProcessLocked(app, false, false, "crash");
9709                mStackSupervisor.resumeTopActivitiesLocked();
9710                return false;
9711            }
9712            mStackSupervisor.resumeTopActivitiesLocked();
9713        } else {
9714            mStackSupervisor.finishTopRunningActivityLocked(app);
9715        }
9716
9717        // Bump up the crash count of any services currently running in the proc.
9718        for (int i=app.services.size()-1; i>=0; i--) {
9719            // Any services running in the application need to be placed
9720            // back in the pending list.
9721            ServiceRecord sr = app.services.valueAt(i);
9722            sr.crashCount++;
9723        }
9724
9725        // If the crashing process is what we consider to be the "home process" and it has been
9726        // replaced by a third-party app, clear the package preferred activities from packages
9727        // with a home activity running in the process to prevent a repeatedly crashing app
9728        // from blocking the user to manually clear the list.
9729        final ArrayList<ActivityRecord> activities = app.activities;
9730        if (app == mHomeProcess && activities.size() > 0
9731                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9732            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9733                final ActivityRecord r = activities.get(activityNdx);
9734                if (r.isHomeActivity()) {
9735                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9736                    try {
9737                        ActivityThread.getPackageManager()
9738                                .clearPackagePreferredActivities(r.packageName);
9739                    } catch (RemoteException c) {
9740                        // pm is in same process, this will never happen.
9741                    }
9742                }
9743            }
9744        }
9745
9746        if (!app.isolated) {
9747            // XXX Can't keep track of crash times for isolated processes,
9748            // because they don't have a perisistent identity.
9749            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9750        }
9751
9752        return true;
9753    }
9754
9755    void startAppProblemLocked(ProcessRecord app) {
9756        if (app.userId == mCurrentUserId) {
9757            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9758                    mContext, app.info.packageName, app.info.flags);
9759        } else {
9760            // If this app is not running under the current user, then we
9761            // can't give it a report button because that would require
9762            // launching the report UI under a different user.
9763            app.errorReportReceiver = null;
9764        }
9765        skipCurrentReceiverLocked(app);
9766    }
9767
9768    void skipCurrentReceiverLocked(ProcessRecord app) {
9769        for (BroadcastQueue queue : mBroadcastQueues) {
9770            queue.skipCurrentReceiverLocked(app);
9771        }
9772    }
9773
9774    /**
9775     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9776     * The application process will exit immediately after this call returns.
9777     * @param app object of the crashing app, null for the system server
9778     * @param crashInfo describing the exception
9779     */
9780    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9781        ProcessRecord r = findAppProcess(app, "Crash");
9782        final String processName = app == null ? "system_server"
9783                : (r == null ? "unknown" : r.processName);
9784
9785        handleApplicationCrashInner("crash", r, processName, crashInfo);
9786    }
9787
9788    /* Native crash reporting uses this inner version because it needs to be somewhat
9789     * decoupled from the AM-managed cleanup lifecycle
9790     */
9791    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
9792            ApplicationErrorReport.CrashInfo crashInfo) {
9793        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
9794                UserHandle.getUserId(Binder.getCallingUid()), processName,
9795                r == null ? -1 : r.info.flags,
9796                crashInfo.exceptionClassName,
9797                crashInfo.exceptionMessage,
9798                crashInfo.throwFileName,
9799                crashInfo.throwLineNumber);
9800
9801        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
9802
9803        crashApplication(r, crashInfo);
9804    }
9805
9806    public void handleApplicationStrictModeViolation(
9807            IBinder app,
9808            int violationMask,
9809            StrictMode.ViolationInfo info) {
9810        ProcessRecord r = findAppProcess(app, "StrictMode");
9811        if (r == null) {
9812            return;
9813        }
9814
9815        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
9816            Integer stackFingerprint = info.hashCode();
9817            boolean logIt = true;
9818            synchronized (mAlreadyLoggedViolatedStacks) {
9819                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
9820                    logIt = false;
9821                    // TODO: sub-sample into EventLog for these, with
9822                    // the info.durationMillis?  Then we'd get
9823                    // the relative pain numbers, without logging all
9824                    // the stack traces repeatedly.  We'd want to do
9825                    // likewise in the client code, which also does
9826                    // dup suppression, before the Binder call.
9827                } else {
9828                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
9829                        mAlreadyLoggedViolatedStacks.clear();
9830                    }
9831                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
9832                }
9833            }
9834            if (logIt) {
9835                logStrictModeViolationToDropBox(r, info);
9836            }
9837        }
9838
9839        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
9840            AppErrorResult result = new AppErrorResult();
9841            synchronized (this) {
9842                final long origId = Binder.clearCallingIdentity();
9843
9844                Message msg = Message.obtain();
9845                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
9846                HashMap<String, Object> data = new HashMap<String, Object>();
9847                data.put("result", result);
9848                data.put("app", r);
9849                data.put("violationMask", violationMask);
9850                data.put("info", info);
9851                msg.obj = data;
9852                mHandler.sendMessage(msg);
9853
9854                Binder.restoreCallingIdentity(origId);
9855            }
9856            int res = result.get();
9857            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
9858        }
9859    }
9860
9861    // Depending on the policy in effect, there could be a bunch of
9862    // these in quick succession so we try to batch these together to
9863    // minimize disk writes, number of dropbox entries, and maximize
9864    // compression, by having more fewer, larger records.
9865    private void logStrictModeViolationToDropBox(
9866            ProcessRecord process,
9867            StrictMode.ViolationInfo info) {
9868        if (info == null) {
9869            return;
9870        }
9871        final boolean isSystemApp = process == null ||
9872                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
9873                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
9874        final String processName = process == null ? "unknown" : process.processName;
9875        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
9876        final DropBoxManager dbox = (DropBoxManager)
9877                mContext.getSystemService(Context.DROPBOX_SERVICE);
9878
9879        // Exit early if the dropbox isn't configured to accept this report type.
9880        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9881
9882        boolean bufferWasEmpty;
9883        boolean needsFlush;
9884        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
9885        synchronized (sb) {
9886            bufferWasEmpty = sb.length() == 0;
9887            appendDropBoxProcessHeaders(process, processName, sb);
9888            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9889            sb.append("System-App: ").append(isSystemApp).append("\n");
9890            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
9891            if (info.violationNumThisLoop != 0) {
9892                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
9893            }
9894            if (info.numAnimationsRunning != 0) {
9895                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
9896            }
9897            if (info.broadcastIntentAction != null) {
9898                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
9899            }
9900            if (info.durationMillis != -1) {
9901                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
9902            }
9903            if (info.numInstances != -1) {
9904                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
9905            }
9906            if (info.tags != null) {
9907                for (String tag : info.tags) {
9908                    sb.append("Span-Tag: ").append(tag).append("\n");
9909                }
9910            }
9911            sb.append("\n");
9912            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
9913                sb.append(info.crashInfo.stackTrace);
9914            }
9915            sb.append("\n");
9916
9917            // Only buffer up to ~64k.  Various logging bits truncate
9918            // things at 128k.
9919            needsFlush = (sb.length() > 64 * 1024);
9920        }
9921
9922        // Flush immediately if the buffer's grown too large, or this
9923        // is a non-system app.  Non-system apps are isolated with a
9924        // different tag & policy and not batched.
9925        //
9926        // Batching is useful during internal testing with
9927        // StrictMode settings turned up high.  Without batching,
9928        // thousands of separate files could be created on boot.
9929        if (!isSystemApp || needsFlush) {
9930            new Thread("Error dump: " + dropboxTag) {
9931                @Override
9932                public void run() {
9933                    String report;
9934                    synchronized (sb) {
9935                        report = sb.toString();
9936                        sb.delete(0, sb.length());
9937                        sb.trimToSize();
9938                    }
9939                    if (report.length() != 0) {
9940                        dbox.addText(dropboxTag, report);
9941                    }
9942                }
9943            }.start();
9944            return;
9945        }
9946
9947        // System app batching:
9948        if (!bufferWasEmpty) {
9949            // An existing dropbox-writing thread is outstanding, so
9950            // we don't need to start it up.  The existing thread will
9951            // catch the buffer appends we just did.
9952            return;
9953        }
9954
9955        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
9956        // (After this point, we shouldn't access AMS internal data structures.)
9957        new Thread("Error dump: " + dropboxTag) {
9958            @Override
9959            public void run() {
9960                // 5 second sleep to let stacks arrive and be batched together
9961                try {
9962                    Thread.sleep(5000);  // 5 seconds
9963                } catch (InterruptedException e) {}
9964
9965                String errorReport;
9966                synchronized (mStrictModeBuffer) {
9967                    errorReport = mStrictModeBuffer.toString();
9968                    if (errorReport.length() == 0) {
9969                        return;
9970                    }
9971                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
9972                    mStrictModeBuffer.trimToSize();
9973                }
9974                dbox.addText(dropboxTag, errorReport);
9975            }
9976        }.start();
9977    }
9978
9979    /**
9980     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
9981     * @param app object of the crashing app, null for the system server
9982     * @param tag reported by the caller
9983     * @param crashInfo describing the context of the error
9984     * @return true if the process should exit immediately (WTF is fatal)
9985     */
9986    public boolean handleApplicationWtf(IBinder app, String tag,
9987            ApplicationErrorReport.CrashInfo crashInfo) {
9988        ProcessRecord r = findAppProcess(app, "WTF");
9989        final String processName = app == null ? "system_server"
9990                : (r == null ? "unknown" : r.processName);
9991
9992        EventLog.writeEvent(EventLogTags.AM_WTF,
9993                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
9994                processName,
9995                r == null ? -1 : r.info.flags,
9996                tag, crashInfo.exceptionMessage);
9997
9998        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
9999
10000        if (r != null && r.pid != Process.myPid() &&
10001                Settings.Global.getInt(mContext.getContentResolver(),
10002                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10003            crashApplication(r, crashInfo);
10004            return true;
10005        } else {
10006            return false;
10007        }
10008    }
10009
10010    /**
10011     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10012     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10013     */
10014    private ProcessRecord findAppProcess(IBinder app, String reason) {
10015        if (app == null) {
10016            return null;
10017        }
10018
10019        synchronized (this) {
10020            final int NP = mProcessNames.getMap().size();
10021            for (int ip=0; ip<NP; ip++) {
10022                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10023                final int NA = apps.size();
10024                for (int ia=0; ia<NA; ia++) {
10025                    ProcessRecord p = apps.valueAt(ia);
10026                    if (p.thread != null && p.thread.asBinder() == app) {
10027                        return p;
10028                    }
10029                }
10030            }
10031
10032            Slog.w(TAG, "Can't find mystery application for " + reason
10033                    + " from pid=" + Binder.getCallingPid()
10034                    + " uid=" + Binder.getCallingUid() + ": " + app);
10035            return null;
10036        }
10037    }
10038
10039    /**
10040     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10041     * to append various headers to the dropbox log text.
10042     */
10043    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10044            StringBuilder sb) {
10045        // Watchdog thread ends up invoking this function (with
10046        // a null ProcessRecord) to add the stack file to dropbox.
10047        // Do not acquire a lock on this (am) in such cases, as it
10048        // could cause a potential deadlock, if and when watchdog
10049        // is invoked due to unavailability of lock on am and it
10050        // would prevent watchdog from killing system_server.
10051        if (process == null) {
10052            sb.append("Process: ").append(processName).append("\n");
10053            return;
10054        }
10055        // Note: ProcessRecord 'process' is guarded by the service
10056        // instance.  (notably process.pkgList, which could otherwise change
10057        // concurrently during execution of this method)
10058        synchronized (this) {
10059            sb.append("Process: ").append(processName).append("\n");
10060            int flags = process.info.flags;
10061            IPackageManager pm = AppGlobals.getPackageManager();
10062            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10063            for (int ip=0; ip<process.pkgList.size(); ip++) {
10064                String pkg = process.pkgList.keyAt(ip);
10065                sb.append("Package: ").append(pkg);
10066                try {
10067                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10068                    if (pi != null) {
10069                        sb.append(" v").append(pi.versionCode);
10070                        if (pi.versionName != null) {
10071                            sb.append(" (").append(pi.versionName).append(")");
10072                        }
10073                    }
10074                } catch (RemoteException e) {
10075                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10076                }
10077                sb.append("\n");
10078            }
10079        }
10080    }
10081
10082    private static String processClass(ProcessRecord process) {
10083        if (process == null || process.pid == MY_PID) {
10084            return "system_server";
10085        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10086            return "system_app";
10087        } else {
10088            return "data_app";
10089        }
10090    }
10091
10092    /**
10093     * Write a description of an error (crash, WTF, ANR) to the drop box.
10094     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10095     * @param process which caused the error, null means the system server
10096     * @param activity which triggered the error, null if unknown
10097     * @param parent activity related to the error, null if unknown
10098     * @param subject line related to the error, null if absent
10099     * @param report in long form describing the error, null if absent
10100     * @param logFile to include in the report, null if none
10101     * @param crashInfo giving an application stack trace, null if absent
10102     */
10103    public void addErrorToDropBox(String eventType,
10104            ProcessRecord process, String processName, ActivityRecord activity,
10105            ActivityRecord parent, String subject,
10106            final String report, final File logFile,
10107            final ApplicationErrorReport.CrashInfo crashInfo) {
10108        // NOTE -- this must never acquire the ActivityManagerService lock,
10109        // otherwise the watchdog may be prevented from resetting the system.
10110
10111        final String dropboxTag = processClass(process) + "_" + eventType;
10112        final DropBoxManager dbox = (DropBoxManager)
10113                mContext.getSystemService(Context.DROPBOX_SERVICE);
10114
10115        // Exit early if the dropbox isn't configured to accept this report type.
10116        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10117
10118        final StringBuilder sb = new StringBuilder(1024);
10119        appendDropBoxProcessHeaders(process, processName, sb);
10120        if (activity != null) {
10121            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10122        }
10123        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10124            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10125        }
10126        if (parent != null && parent != activity) {
10127            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10128        }
10129        if (subject != null) {
10130            sb.append("Subject: ").append(subject).append("\n");
10131        }
10132        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10133        if (Debug.isDebuggerConnected()) {
10134            sb.append("Debugger: Connected\n");
10135        }
10136        sb.append("\n");
10137
10138        // Do the rest in a worker thread to avoid blocking the caller on I/O
10139        // (After this point, we shouldn't access AMS internal data structures.)
10140        Thread worker = new Thread("Error dump: " + dropboxTag) {
10141            @Override
10142            public void run() {
10143                if (report != null) {
10144                    sb.append(report);
10145                }
10146                if (logFile != null) {
10147                    try {
10148                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10149                                    "\n\n[[TRUNCATED]]"));
10150                    } catch (IOException e) {
10151                        Slog.e(TAG, "Error reading " + logFile, e);
10152                    }
10153                }
10154                if (crashInfo != null && crashInfo.stackTrace != null) {
10155                    sb.append(crashInfo.stackTrace);
10156                }
10157
10158                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10159                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10160                if (lines > 0) {
10161                    sb.append("\n");
10162
10163                    // Merge several logcat streams, and take the last N lines
10164                    InputStreamReader input = null;
10165                    try {
10166                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10167                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10168                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10169
10170                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10171                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10172                        input = new InputStreamReader(logcat.getInputStream());
10173
10174                        int num;
10175                        char[] buf = new char[8192];
10176                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10177                    } catch (IOException e) {
10178                        Slog.e(TAG, "Error running logcat", e);
10179                    } finally {
10180                        if (input != null) try { input.close(); } catch (IOException e) {}
10181                    }
10182                }
10183
10184                dbox.addText(dropboxTag, sb.toString());
10185            }
10186        };
10187
10188        if (process == null) {
10189            // If process is null, we are being called from some internal code
10190            // and may be about to die -- run this synchronously.
10191            worker.run();
10192        } else {
10193            worker.start();
10194        }
10195    }
10196
10197    /**
10198     * Bring up the "unexpected error" dialog box for a crashing app.
10199     * Deal with edge cases (intercepts from instrumented applications,
10200     * ActivityController, error intent receivers, that sort of thing).
10201     * @param r the application crashing
10202     * @param crashInfo describing the failure
10203     */
10204    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10205        long timeMillis = System.currentTimeMillis();
10206        String shortMsg = crashInfo.exceptionClassName;
10207        String longMsg = crashInfo.exceptionMessage;
10208        String stackTrace = crashInfo.stackTrace;
10209        if (shortMsg != null && longMsg != null) {
10210            longMsg = shortMsg + ": " + longMsg;
10211        } else if (shortMsg != null) {
10212            longMsg = shortMsg;
10213        }
10214
10215        AppErrorResult result = new AppErrorResult();
10216        synchronized (this) {
10217            if (mController != null) {
10218                try {
10219                    String name = r != null ? r.processName : null;
10220                    int pid = r != null ? r.pid : Binder.getCallingPid();
10221                    if (!mController.appCrashed(name, pid,
10222                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10223                        Slog.w(TAG, "Force-killing crashed app " + name
10224                                + " at watcher's request");
10225                        Process.killProcess(pid);
10226                        return;
10227                    }
10228                } catch (RemoteException e) {
10229                    mController = null;
10230                    Watchdog.getInstance().setActivityController(null);
10231                }
10232            }
10233
10234            final long origId = Binder.clearCallingIdentity();
10235
10236            // If this process is running instrumentation, finish it.
10237            if (r != null && r.instrumentationClass != null) {
10238                Slog.w(TAG, "Error in app " + r.processName
10239                      + " running instrumentation " + r.instrumentationClass + ":");
10240                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10241                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10242                Bundle info = new Bundle();
10243                info.putString("shortMsg", shortMsg);
10244                info.putString("longMsg", longMsg);
10245                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10246                Binder.restoreCallingIdentity(origId);
10247                return;
10248            }
10249
10250            // If we can't identify the process or it's already exceeded its crash quota,
10251            // quit right away without showing a crash dialog.
10252            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10253                Binder.restoreCallingIdentity(origId);
10254                return;
10255            }
10256
10257            Message msg = Message.obtain();
10258            msg.what = SHOW_ERROR_MSG;
10259            HashMap data = new HashMap();
10260            data.put("result", result);
10261            data.put("app", r);
10262            msg.obj = data;
10263            mHandler.sendMessage(msg);
10264
10265            Binder.restoreCallingIdentity(origId);
10266        }
10267
10268        int res = result.get();
10269
10270        Intent appErrorIntent = null;
10271        synchronized (this) {
10272            if (r != null && !r.isolated) {
10273                // XXX Can't keep track of crash time for isolated processes,
10274                // since they don't have a persistent identity.
10275                mProcessCrashTimes.put(r.info.processName, r.uid,
10276                        SystemClock.uptimeMillis());
10277            }
10278            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10279                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10280            }
10281        }
10282
10283        if (appErrorIntent != null) {
10284            try {
10285                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10286            } catch (ActivityNotFoundException e) {
10287                Slog.w(TAG, "bug report receiver dissappeared", e);
10288            }
10289        }
10290    }
10291
10292    Intent createAppErrorIntentLocked(ProcessRecord r,
10293            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10294        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10295        if (report == null) {
10296            return null;
10297        }
10298        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10299        result.setComponent(r.errorReportReceiver);
10300        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10301        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10302        return result;
10303    }
10304
10305    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10306            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10307        if (r.errorReportReceiver == null) {
10308            return null;
10309        }
10310
10311        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10312            return null;
10313        }
10314
10315        ApplicationErrorReport report = new ApplicationErrorReport();
10316        report.packageName = r.info.packageName;
10317        report.installerPackageName = r.errorReportReceiver.getPackageName();
10318        report.processName = r.processName;
10319        report.time = timeMillis;
10320        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10321
10322        if (r.crashing || r.forceCrashReport) {
10323            report.type = ApplicationErrorReport.TYPE_CRASH;
10324            report.crashInfo = crashInfo;
10325        } else if (r.notResponding) {
10326            report.type = ApplicationErrorReport.TYPE_ANR;
10327            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10328
10329            report.anrInfo.activity = r.notRespondingReport.tag;
10330            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10331            report.anrInfo.info = r.notRespondingReport.longMsg;
10332        }
10333
10334        return report;
10335    }
10336
10337    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10338        enforceNotIsolatedCaller("getProcessesInErrorState");
10339        // assume our apps are happy - lazy create the list
10340        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10341
10342        final boolean allUsers = ActivityManager.checkUidPermission(
10343                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10344                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10345        int userId = UserHandle.getUserId(Binder.getCallingUid());
10346
10347        synchronized (this) {
10348
10349            // iterate across all processes
10350            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10351                ProcessRecord app = mLruProcesses.get(i);
10352                if (!allUsers && app.userId != userId) {
10353                    continue;
10354                }
10355                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10356                    // This one's in trouble, so we'll generate a report for it
10357                    // crashes are higher priority (in case there's a crash *and* an anr)
10358                    ActivityManager.ProcessErrorStateInfo report = null;
10359                    if (app.crashing) {
10360                        report = app.crashingReport;
10361                    } else if (app.notResponding) {
10362                        report = app.notRespondingReport;
10363                    }
10364
10365                    if (report != null) {
10366                        if (errList == null) {
10367                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10368                        }
10369                        errList.add(report);
10370                    } else {
10371                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10372                                " crashing = " + app.crashing +
10373                                " notResponding = " + app.notResponding);
10374                    }
10375                }
10376            }
10377        }
10378
10379        return errList;
10380    }
10381
10382    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10383        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10384            if (currApp != null) {
10385                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10386            }
10387            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10388        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10389            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10390        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10391            if (currApp != null) {
10392                currApp.lru = 0;
10393            }
10394            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10395        } else if (adj >= ProcessList.SERVICE_ADJ) {
10396            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10397        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10398            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10399        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10400            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10401        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10402            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10403        } else {
10404            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10405        }
10406    }
10407
10408    private void fillInProcMemInfo(ProcessRecord app,
10409            ActivityManager.RunningAppProcessInfo outInfo) {
10410        outInfo.pid = app.pid;
10411        outInfo.uid = app.info.uid;
10412        if (mHeavyWeightProcess == app) {
10413            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10414        }
10415        if (app.persistent) {
10416            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10417        }
10418        if (app.activities.size() > 0) {
10419            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10420        }
10421        outInfo.lastTrimLevel = app.trimMemoryLevel;
10422        int adj = app.curAdj;
10423        outInfo.importance = oomAdjToImportance(adj, outInfo);
10424        outInfo.importanceReasonCode = app.adjTypeCode;
10425    }
10426
10427    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10428        enforceNotIsolatedCaller("getRunningAppProcesses");
10429        // Lazy instantiation of list
10430        List<ActivityManager.RunningAppProcessInfo> runList = null;
10431        final boolean allUsers = ActivityManager.checkUidPermission(
10432                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10433                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10434        int userId = UserHandle.getUserId(Binder.getCallingUid());
10435        synchronized (this) {
10436            // Iterate across all processes
10437            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10438                ProcessRecord app = mLruProcesses.get(i);
10439                if (!allUsers && app.userId != userId) {
10440                    continue;
10441                }
10442                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10443                    // Generate process state info for running application
10444                    ActivityManager.RunningAppProcessInfo currApp =
10445                        new ActivityManager.RunningAppProcessInfo(app.processName,
10446                                app.pid, app.getPackageList());
10447                    fillInProcMemInfo(app, currApp);
10448                    if (app.adjSource instanceof ProcessRecord) {
10449                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10450                        currApp.importanceReasonImportance = oomAdjToImportance(
10451                                app.adjSourceOom, null);
10452                    } else if (app.adjSource instanceof ActivityRecord) {
10453                        ActivityRecord r = (ActivityRecord)app.adjSource;
10454                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10455                    }
10456                    if (app.adjTarget instanceof ComponentName) {
10457                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10458                    }
10459                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10460                    //        + " lru=" + currApp.lru);
10461                    if (runList == null) {
10462                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10463                    }
10464                    runList.add(currApp);
10465                }
10466            }
10467        }
10468        return runList;
10469    }
10470
10471    public List<ApplicationInfo> getRunningExternalApplications() {
10472        enforceNotIsolatedCaller("getRunningExternalApplications");
10473        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10474        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10475        if (runningApps != null && runningApps.size() > 0) {
10476            Set<String> extList = new HashSet<String>();
10477            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10478                if (app.pkgList != null) {
10479                    for (String pkg : app.pkgList) {
10480                        extList.add(pkg);
10481                    }
10482                }
10483            }
10484            IPackageManager pm = AppGlobals.getPackageManager();
10485            for (String pkg : extList) {
10486                try {
10487                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10488                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10489                        retList.add(info);
10490                    }
10491                } catch (RemoteException e) {
10492                }
10493            }
10494        }
10495        return retList;
10496    }
10497
10498    @Override
10499    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10500        enforceNotIsolatedCaller("getMyMemoryState");
10501        synchronized (this) {
10502            ProcessRecord proc;
10503            synchronized (mPidsSelfLocked) {
10504                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10505            }
10506            fillInProcMemInfo(proc, outInfo);
10507        }
10508    }
10509
10510    @Override
10511    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10512        if (checkCallingPermission(android.Manifest.permission.DUMP)
10513                != PackageManager.PERMISSION_GRANTED) {
10514            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10515                    + Binder.getCallingPid()
10516                    + ", uid=" + Binder.getCallingUid()
10517                    + " without permission "
10518                    + android.Manifest.permission.DUMP);
10519            return;
10520        }
10521
10522        boolean dumpAll = false;
10523        boolean dumpClient = false;
10524        String dumpPackage = null;
10525
10526        int opti = 0;
10527        while (opti < args.length) {
10528            String opt = args[opti];
10529            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10530                break;
10531            }
10532            opti++;
10533            if ("-a".equals(opt)) {
10534                dumpAll = true;
10535            } else if ("-c".equals(opt)) {
10536                dumpClient = true;
10537            } else if ("-h".equals(opt)) {
10538                pw.println("Activity manager dump options:");
10539                pw.println("  [-a] [-c] [-h] [cmd] ...");
10540                pw.println("  cmd may be one of:");
10541                pw.println("    a[ctivities]: activity stack state");
10542                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10543                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10544                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10545                pw.println("    o[om]: out of memory management");
10546                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10547                pw.println("    provider [COMP_SPEC]: provider client-side state");
10548                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10549                pw.println("    service [COMP_SPEC]: service client-side state");
10550                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10551                pw.println("    all: dump all activities");
10552                pw.println("    top: dump the top activity");
10553                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10554                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10555                pw.println("    a partial substring in a component name, a");
10556                pw.println("    hex object identifier.");
10557                pw.println("  -a: include all available server state.");
10558                pw.println("  -c: include client state.");
10559                return;
10560            } else {
10561                pw.println("Unknown argument: " + opt + "; use -h for help");
10562            }
10563        }
10564
10565        long origId = Binder.clearCallingIdentity();
10566        boolean more = false;
10567        // Is the caller requesting to dump a particular piece of data?
10568        if (opti < args.length) {
10569            String cmd = args[opti];
10570            opti++;
10571            if ("activities".equals(cmd) || "a".equals(cmd)) {
10572                synchronized (this) {
10573                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10574                }
10575            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10576                String[] newArgs;
10577                String name;
10578                if (opti >= args.length) {
10579                    name = null;
10580                    newArgs = EMPTY_STRING_ARRAY;
10581                } else {
10582                    name = args[opti];
10583                    opti++;
10584                    newArgs = new String[args.length - opti];
10585                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10586                            args.length - opti);
10587                }
10588                synchronized (this) {
10589                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10590                }
10591            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10592                String[] newArgs;
10593                String name;
10594                if (opti >= args.length) {
10595                    name = null;
10596                    newArgs = EMPTY_STRING_ARRAY;
10597                } else {
10598                    name = args[opti];
10599                    opti++;
10600                    newArgs = new String[args.length - opti];
10601                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10602                            args.length - opti);
10603                }
10604                synchronized (this) {
10605                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10606                }
10607            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10608                String[] newArgs;
10609                String name;
10610                if (opti >= args.length) {
10611                    name = null;
10612                    newArgs = EMPTY_STRING_ARRAY;
10613                } else {
10614                    name = args[opti];
10615                    opti++;
10616                    newArgs = new String[args.length - opti];
10617                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10618                            args.length - opti);
10619                }
10620                synchronized (this) {
10621                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10622                }
10623            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10624                synchronized (this) {
10625                    dumpOomLocked(fd, pw, args, opti, true);
10626                }
10627            } else if ("provider".equals(cmd)) {
10628                String[] newArgs;
10629                String name;
10630                if (opti >= args.length) {
10631                    name = null;
10632                    newArgs = EMPTY_STRING_ARRAY;
10633                } else {
10634                    name = args[opti];
10635                    opti++;
10636                    newArgs = new String[args.length - opti];
10637                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10638                }
10639                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10640                    pw.println("No providers match: " + name);
10641                    pw.println("Use -h for help.");
10642                }
10643            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10644                synchronized (this) {
10645                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10646                }
10647            } else if ("service".equals(cmd)) {
10648                String[] newArgs;
10649                String name;
10650                if (opti >= args.length) {
10651                    name = null;
10652                    newArgs = EMPTY_STRING_ARRAY;
10653                } else {
10654                    name = args[opti];
10655                    opti++;
10656                    newArgs = new String[args.length - opti];
10657                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10658                            args.length - opti);
10659                }
10660                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10661                    pw.println("No services match: " + name);
10662                    pw.println("Use -h for help.");
10663                }
10664            } else if ("package".equals(cmd)) {
10665                String[] newArgs;
10666                if (opti >= args.length) {
10667                    pw.println("package: no package name specified");
10668                    pw.println("Use -h for help.");
10669                } else {
10670                    dumpPackage = args[opti];
10671                    opti++;
10672                    newArgs = new String[args.length - opti];
10673                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10674                            args.length - opti);
10675                    args = newArgs;
10676                    opti = 0;
10677                    more = true;
10678                }
10679            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10680                synchronized (this) {
10681                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10682                }
10683            } else {
10684                // Dumping a single activity?
10685                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10686                    pw.println("Bad activity command, or no activities match: " + cmd);
10687                    pw.println("Use -h for help.");
10688                }
10689            }
10690            if (!more) {
10691                Binder.restoreCallingIdentity(origId);
10692                return;
10693            }
10694        }
10695
10696        // No piece of data specified, dump everything.
10697        synchronized (this) {
10698            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10699            pw.println();
10700            if (dumpAll) {
10701                pw.println("-------------------------------------------------------------------------------");
10702            }
10703            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10704            pw.println();
10705            if (dumpAll) {
10706                pw.println("-------------------------------------------------------------------------------");
10707            }
10708            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10709            pw.println();
10710            if (dumpAll) {
10711                pw.println("-------------------------------------------------------------------------------");
10712            }
10713            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10714            pw.println();
10715            if (dumpAll) {
10716                pw.println("-------------------------------------------------------------------------------");
10717            }
10718            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10719            pw.println();
10720            if (dumpAll) {
10721                pw.println("-------------------------------------------------------------------------------");
10722            }
10723            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10724        }
10725        Binder.restoreCallingIdentity(origId);
10726    }
10727
10728    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10729            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10730        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10731
10732        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10733                dumpPackage);
10734        boolean needSep = printedAnything;
10735
10736        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10737                dumpPackage, needSep, "  mFocusedActivity: ");
10738        if (printed) {
10739            printedAnything = true;
10740            needSep = false;
10741        }
10742
10743        if (dumpPackage == null) {
10744            if (needSep) {
10745                pw.println();
10746            }
10747            needSep = true;
10748            printedAnything = true;
10749            mStackSupervisor.dump(pw, "  ");
10750        }
10751
10752        if (mRecentTasks.size() > 0) {
10753            boolean printedHeader = false;
10754
10755            final int N = mRecentTasks.size();
10756            for (int i=0; i<N; i++) {
10757                TaskRecord tr = mRecentTasks.get(i);
10758                if (dumpPackage != null) {
10759                    if (tr.realActivity == null ||
10760                            !dumpPackage.equals(tr.realActivity)) {
10761                        continue;
10762                    }
10763                }
10764                if (!printedHeader) {
10765                    if (needSep) {
10766                        pw.println();
10767                    }
10768                    pw.println("  Recent tasks:");
10769                    printedHeader = true;
10770                    printedAnything = true;
10771                }
10772                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10773                        pw.println(tr);
10774                if (dumpAll) {
10775                    mRecentTasks.get(i).dump(pw, "    ");
10776                }
10777            }
10778        }
10779
10780        if (!printedAnything) {
10781            pw.println("  (nothing)");
10782        }
10783    }
10784
10785    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10786            int opti, boolean dumpAll, String dumpPackage) {
10787        boolean needSep = false;
10788        boolean printedAnything = false;
10789        int numPers = 0;
10790
10791        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
10792
10793        if (dumpAll) {
10794            final int NP = mProcessNames.getMap().size();
10795            for (int ip=0; ip<NP; ip++) {
10796                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
10797                final int NA = procs.size();
10798                for (int ia=0; ia<NA; ia++) {
10799                    ProcessRecord r = procs.valueAt(ia);
10800                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10801                        continue;
10802                    }
10803                    if (!needSep) {
10804                        pw.println("  All known processes:");
10805                        needSep = true;
10806                        printedAnything = true;
10807                    }
10808                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
10809                        pw.print(" UID "); pw.print(procs.keyAt(ia));
10810                        pw.print(" "); pw.println(r);
10811                    r.dump(pw, "    ");
10812                    if (r.persistent) {
10813                        numPers++;
10814                    }
10815                }
10816            }
10817        }
10818
10819        if (mIsolatedProcesses.size() > 0) {
10820            boolean printed = false;
10821            for (int i=0; i<mIsolatedProcesses.size(); i++) {
10822                ProcessRecord r = mIsolatedProcesses.valueAt(i);
10823                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10824                    continue;
10825                }
10826                if (!printed) {
10827                    if (needSep) {
10828                        pw.println();
10829                    }
10830                    pw.println("  Isolated process list (sorted by uid):");
10831                    printedAnything = true;
10832                    printed = true;
10833                    needSep = true;
10834                }
10835                pw.println(String.format("%sIsolated #%2d: %s",
10836                        "    ", i, r.toString()));
10837            }
10838        }
10839
10840        if (mLruProcesses.size() > 0) {
10841            if (needSep) {
10842                pw.println();
10843            }
10844            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
10845                    pw.print(" total, non-act at ");
10846                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10847                    pw.print(", non-svc at ");
10848                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10849                    pw.println("):");
10850            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
10851            needSep = true;
10852            printedAnything = true;
10853        }
10854
10855        if (dumpAll || dumpPackage != null) {
10856            synchronized (mPidsSelfLocked) {
10857                boolean printed = false;
10858                for (int i=0; i<mPidsSelfLocked.size(); i++) {
10859                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
10860                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10861                        continue;
10862                    }
10863                    if (!printed) {
10864                        if (needSep) pw.println();
10865                        needSep = true;
10866                        pw.println("  PID mappings:");
10867                        printed = true;
10868                        printedAnything = true;
10869                    }
10870                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
10871                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
10872                }
10873            }
10874        }
10875
10876        if (mForegroundProcesses.size() > 0) {
10877            synchronized (mPidsSelfLocked) {
10878                boolean printed = false;
10879                for (int i=0; i<mForegroundProcesses.size(); i++) {
10880                    ProcessRecord r = mPidsSelfLocked.get(
10881                            mForegroundProcesses.valueAt(i).pid);
10882                    if (dumpPackage != null && (r == null
10883                            || !r.pkgList.containsKey(dumpPackage))) {
10884                        continue;
10885                    }
10886                    if (!printed) {
10887                        if (needSep) pw.println();
10888                        needSep = true;
10889                        pw.println("  Foreground Processes:");
10890                        printed = true;
10891                        printedAnything = true;
10892                    }
10893                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
10894                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
10895                }
10896            }
10897        }
10898
10899        if (mPersistentStartingProcesses.size() > 0) {
10900            if (needSep) pw.println();
10901            needSep = true;
10902            printedAnything = true;
10903            pw.println("  Persisent processes that are starting:");
10904            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
10905                    "Starting Norm", "Restarting PERS", dumpPackage);
10906        }
10907
10908        if (mRemovedProcesses.size() > 0) {
10909            if (needSep) pw.println();
10910            needSep = true;
10911            printedAnything = true;
10912            pw.println("  Processes that are being removed:");
10913            dumpProcessList(pw, this, mRemovedProcesses, "    ",
10914                    "Removed Norm", "Removed PERS", dumpPackage);
10915        }
10916
10917        if (mProcessesOnHold.size() > 0) {
10918            if (needSep) pw.println();
10919            needSep = true;
10920            printedAnything = true;
10921            pw.println("  Processes that are on old until the system is ready:");
10922            dumpProcessList(pw, this, mProcessesOnHold, "    ",
10923                    "OnHold Norm", "OnHold PERS", dumpPackage);
10924        }
10925
10926        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
10927
10928        if (mProcessCrashTimes.getMap().size() > 0) {
10929            boolean printed = false;
10930            long now = SystemClock.uptimeMillis();
10931            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
10932            final int NP = pmap.size();
10933            for (int ip=0; ip<NP; ip++) {
10934                String pname = pmap.keyAt(ip);
10935                SparseArray<Long> uids = pmap.valueAt(ip);
10936                final int N = uids.size();
10937                for (int i=0; i<N; i++) {
10938                    int puid = uids.keyAt(i);
10939                    ProcessRecord r = mProcessNames.get(pname, puid);
10940                    if (dumpPackage != null && (r == null
10941                            || !r.pkgList.containsKey(dumpPackage))) {
10942                        continue;
10943                    }
10944                    if (!printed) {
10945                        if (needSep) pw.println();
10946                        needSep = true;
10947                        pw.println("  Time since processes crashed:");
10948                        printed = true;
10949                        printedAnything = true;
10950                    }
10951                    pw.print("    Process "); pw.print(pname);
10952                            pw.print(" uid "); pw.print(puid);
10953                            pw.print(": last crashed ");
10954                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
10955                            pw.println(" ago");
10956                }
10957            }
10958        }
10959
10960        if (mBadProcesses.getMap().size() > 0) {
10961            boolean printed = false;
10962            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
10963            final int NP = pmap.size();
10964            for (int ip=0; ip<NP; ip++) {
10965                String pname = pmap.keyAt(ip);
10966                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
10967                final int N = uids.size();
10968                for (int i=0; i<N; i++) {
10969                    int puid = uids.keyAt(i);
10970                    ProcessRecord r = mProcessNames.get(pname, puid);
10971                    if (dumpPackage != null && (r == null
10972                            || !r.pkgList.containsKey(dumpPackage))) {
10973                        continue;
10974                    }
10975                    if (!printed) {
10976                        if (needSep) pw.println();
10977                        needSep = true;
10978                        pw.println("  Bad processes:");
10979                        printedAnything = true;
10980                    }
10981                    BadProcessInfo info = uids.valueAt(i);
10982                    pw.print("    Bad process "); pw.print(pname);
10983                            pw.print(" uid "); pw.print(puid);
10984                            pw.print(": crashed at time "); pw.println(info.time);
10985                    if (info.shortMsg != null) {
10986                        pw.print("      Short msg: "); pw.println(info.shortMsg);
10987                    }
10988                    if (info.longMsg != null) {
10989                        pw.print("      Long msg: "); pw.println(info.longMsg);
10990                    }
10991                    if (info.stack != null) {
10992                        pw.println("      Stack:");
10993                        int lastPos = 0;
10994                        for (int pos=0; pos<info.stack.length(); pos++) {
10995                            if (info.stack.charAt(pos) == '\n') {
10996                                pw.print("        ");
10997                                pw.write(info.stack, lastPos, pos-lastPos);
10998                                pw.println();
10999                                lastPos = pos+1;
11000                            }
11001                        }
11002                        if (lastPos < info.stack.length()) {
11003                            pw.print("        ");
11004                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11005                            pw.println();
11006                        }
11007                    }
11008                }
11009            }
11010        }
11011
11012        if (dumpPackage == null) {
11013            pw.println();
11014            needSep = false;
11015            pw.println("  mStartedUsers:");
11016            for (int i=0; i<mStartedUsers.size(); i++) {
11017                UserStartedState uss = mStartedUsers.valueAt(i);
11018                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11019                        pw.print(": "); uss.dump("", pw);
11020            }
11021            pw.print("  mStartedUserArray: [");
11022            for (int i=0; i<mStartedUserArray.length; i++) {
11023                if (i > 0) pw.print(", ");
11024                pw.print(mStartedUserArray[i]);
11025            }
11026            pw.println("]");
11027            pw.print("  mUserLru: [");
11028            for (int i=0; i<mUserLru.size(); i++) {
11029                if (i > 0) pw.print(", ");
11030                pw.print(mUserLru.get(i));
11031            }
11032            pw.println("]");
11033            if (dumpAll) {
11034                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11035            }
11036        }
11037        if (mHomeProcess != null && (dumpPackage == null
11038                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11039            if (needSep) {
11040                pw.println();
11041                needSep = false;
11042            }
11043            pw.println("  mHomeProcess: " + mHomeProcess);
11044        }
11045        if (mPreviousProcess != null && (dumpPackage == null
11046                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11047            if (needSep) {
11048                pw.println();
11049                needSep = false;
11050            }
11051            pw.println("  mPreviousProcess: " + mPreviousProcess);
11052        }
11053        if (dumpAll) {
11054            StringBuilder sb = new StringBuilder(128);
11055            sb.append("  mPreviousProcessVisibleTime: ");
11056            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11057            pw.println(sb);
11058        }
11059        if (mHeavyWeightProcess != null && (dumpPackage == null
11060                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11061            if (needSep) {
11062                pw.println();
11063                needSep = false;
11064            }
11065            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11066        }
11067        if (dumpPackage == null) {
11068            pw.println("  mConfiguration: " + mConfiguration);
11069        }
11070        if (dumpAll) {
11071            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11072            if (mCompatModePackages.getPackages().size() > 0) {
11073                boolean printed = false;
11074                for (Map.Entry<String, Integer> entry
11075                        : mCompatModePackages.getPackages().entrySet()) {
11076                    String pkg = entry.getKey();
11077                    int mode = entry.getValue();
11078                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11079                        continue;
11080                    }
11081                    if (!printed) {
11082                        pw.println("  mScreenCompatPackages:");
11083                        printed = true;
11084                    }
11085                    pw.print("    "); pw.print(pkg); pw.print(": ");
11086                            pw.print(mode); pw.println();
11087                }
11088            }
11089        }
11090        if (dumpPackage == null) {
11091            if (mSleeping || mWentToSleep || mLockScreenShown) {
11092                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11093                        + " mLockScreenShown " + mLockScreenShown);
11094            }
11095            if (mShuttingDown) {
11096                pw.println("  mShuttingDown=" + mShuttingDown);
11097            }
11098        }
11099        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11100                || mOrigWaitForDebugger) {
11101            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11102                    || dumpPackage.equals(mOrigDebugApp)) {
11103                if (needSep) {
11104                    pw.println();
11105                    needSep = false;
11106                }
11107                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11108                        + " mDebugTransient=" + mDebugTransient
11109                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11110            }
11111        }
11112        if (mOpenGlTraceApp != null) {
11113            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11114                if (needSep) {
11115                    pw.println();
11116                    needSep = false;
11117                }
11118                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11119            }
11120        }
11121        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11122                || mProfileFd != null) {
11123            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11124                if (needSep) {
11125                    pw.println();
11126                    needSep = false;
11127                }
11128                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11129                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11130                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11131                        + mAutoStopProfiler);
11132            }
11133        }
11134        if (dumpPackage == null) {
11135            if (mAlwaysFinishActivities || mController != null) {
11136                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11137                        + " mController=" + mController);
11138            }
11139            if (dumpAll) {
11140                pw.println("  Total persistent processes: " + numPers);
11141                pw.println("  mStartRunning=" + mStartRunning
11142                        + " mProcessesReady=" + mProcessesReady
11143                        + " mSystemReady=" + mSystemReady);
11144                pw.println("  mBooting=" + mBooting
11145                        + " mBooted=" + mBooted
11146                        + " mFactoryTest=" + mFactoryTest);
11147                pw.print("  mLastPowerCheckRealtime=");
11148                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11149                        pw.println("");
11150                pw.print("  mLastPowerCheckUptime=");
11151                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11152                        pw.println("");
11153                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11154                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11155                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11156                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11157                        + " (" + mLruProcesses.size() + " total)"
11158                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11159                        + " mNumServiceProcs=" + mNumServiceProcs
11160                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11161                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11162                        + " mLastMemoryLevel" + mLastMemoryLevel
11163                        + " mLastNumProcesses" + mLastNumProcesses);
11164                long now = SystemClock.uptimeMillis();
11165                pw.print("  mLastIdleTime=");
11166                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11167                        pw.print(" mLowRamSinceLastIdle=");
11168                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11169                        pw.println();
11170            }
11171        }
11172
11173        if (!printedAnything) {
11174            pw.println("  (nothing)");
11175        }
11176    }
11177
11178    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11179            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11180        if (mProcessesToGc.size() > 0) {
11181            boolean printed = false;
11182            long now = SystemClock.uptimeMillis();
11183            for (int i=0; i<mProcessesToGc.size(); i++) {
11184                ProcessRecord proc = mProcessesToGc.get(i);
11185                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11186                    continue;
11187                }
11188                if (!printed) {
11189                    if (needSep) pw.println();
11190                    needSep = true;
11191                    pw.println("  Processes that are waiting to GC:");
11192                    printed = true;
11193                }
11194                pw.print("    Process "); pw.println(proc);
11195                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11196                        pw.print(", last gced=");
11197                        pw.print(now-proc.lastRequestedGc);
11198                        pw.print(" ms ago, last lowMem=");
11199                        pw.print(now-proc.lastLowMemory);
11200                        pw.println(" ms ago");
11201
11202            }
11203        }
11204        return needSep;
11205    }
11206
11207    void printOomLevel(PrintWriter pw, String name, int adj) {
11208        pw.print("    ");
11209        if (adj >= 0) {
11210            pw.print(' ');
11211            if (adj < 10) pw.print(' ');
11212        } else {
11213            if (adj > -10) pw.print(' ');
11214        }
11215        pw.print(adj);
11216        pw.print(": ");
11217        pw.print(name);
11218        pw.print(" (");
11219        pw.print(mProcessList.getMemLevel(adj)/1024);
11220        pw.println(" kB)");
11221    }
11222
11223    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11224            int opti, boolean dumpAll) {
11225        boolean needSep = false;
11226
11227        if (mLruProcesses.size() > 0) {
11228            if (needSep) pw.println();
11229            needSep = true;
11230            pw.println("  OOM levels:");
11231            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11232            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11233            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11234            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11235            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11236            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11237            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11238            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11239            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11240            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11241            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11242            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11243            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11244
11245            if (needSep) pw.println();
11246            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11247                    pw.print(" total, non-act at ");
11248                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11249                    pw.print(", non-svc at ");
11250                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11251                    pw.println("):");
11252            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11253            needSep = true;
11254        }
11255
11256        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11257
11258        pw.println();
11259        pw.println("  mHomeProcess: " + mHomeProcess);
11260        pw.println("  mPreviousProcess: " + mPreviousProcess);
11261        if (mHeavyWeightProcess != null) {
11262            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11263        }
11264
11265        return true;
11266    }
11267
11268    /**
11269     * There are three ways to call this:
11270     *  - no provider specified: dump all the providers
11271     *  - a flattened component name that matched an existing provider was specified as the
11272     *    first arg: dump that one provider
11273     *  - the first arg isn't the flattened component name of an existing provider:
11274     *    dump all providers whose component contains the first arg as a substring
11275     */
11276    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11277            int opti, boolean dumpAll) {
11278        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11279    }
11280
11281    static class ItemMatcher {
11282        ArrayList<ComponentName> components;
11283        ArrayList<String> strings;
11284        ArrayList<Integer> objects;
11285        boolean all;
11286
11287        ItemMatcher() {
11288            all = true;
11289        }
11290
11291        void build(String name) {
11292            ComponentName componentName = ComponentName.unflattenFromString(name);
11293            if (componentName != null) {
11294                if (components == null) {
11295                    components = new ArrayList<ComponentName>();
11296                }
11297                components.add(componentName);
11298                all = false;
11299            } else {
11300                int objectId = 0;
11301                // Not a '/' separated full component name; maybe an object ID?
11302                try {
11303                    objectId = Integer.parseInt(name, 16);
11304                    if (objects == null) {
11305                        objects = new ArrayList<Integer>();
11306                    }
11307                    objects.add(objectId);
11308                    all = false;
11309                } catch (RuntimeException e) {
11310                    // Not an integer; just do string match.
11311                    if (strings == null) {
11312                        strings = new ArrayList<String>();
11313                    }
11314                    strings.add(name);
11315                    all = false;
11316                }
11317            }
11318        }
11319
11320        int build(String[] args, int opti) {
11321            for (; opti<args.length; opti++) {
11322                String name = args[opti];
11323                if ("--".equals(name)) {
11324                    return opti+1;
11325                }
11326                build(name);
11327            }
11328            return opti;
11329        }
11330
11331        boolean match(Object object, ComponentName comp) {
11332            if (all) {
11333                return true;
11334            }
11335            if (components != null) {
11336                for (int i=0; i<components.size(); i++) {
11337                    if (components.get(i).equals(comp)) {
11338                        return true;
11339                    }
11340                }
11341            }
11342            if (objects != null) {
11343                for (int i=0; i<objects.size(); i++) {
11344                    if (System.identityHashCode(object) == objects.get(i)) {
11345                        return true;
11346                    }
11347                }
11348            }
11349            if (strings != null) {
11350                String flat = comp.flattenToString();
11351                for (int i=0; i<strings.size(); i++) {
11352                    if (flat.contains(strings.get(i))) {
11353                        return true;
11354                    }
11355                }
11356            }
11357            return false;
11358        }
11359    }
11360
11361    /**
11362     * There are three things that cmd can be:
11363     *  - a flattened component name that matches an existing activity
11364     *  - the cmd arg isn't the flattened component name of an existing activity:
11365     *    dump all activity whose component contains the cmd as a substring
11366     *  - A hex number of the ActivityRecord object instance.
11367     */
11368    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11369            int opti, boolean dumpAll) {
11370        ArrayList<ActivityRecord> activities;
11371
11372        synchronized (this) {
11373            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11374        }
11375
11376        if (activities.size() <= 0) {
11377            return false;
11378        }
11379
11380        String[] newArgs = new String[args.length - opti];
11381        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11382
11383        TaskRecord lastTask = null;
11384        boolean needSep = false;
11385        for (int i=activities.size()-1; i>=0; i--) {
11386            ActivityRecord r = activities.get(i);
11387            if (needSep) {
11388                pw.println();
11389            }
11390            needSep = true;
11391            synchronized (this) {
11392                if (lastTask != r.task) {
11393                    lastTask = r.task;
11394                    pw.print("TASK "); pw.print(lastTask.affinity);
11395                            pw.print(" id="); pw.println(lastTask.taskId);
11396                    if (dumpAll) {
11397                        lastTask.dump(pw, "  ");
11398                    }
11399                }
11400            }
11401            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11402        }
11403        return true;
11404    }
11405
11406    /**
11407     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11408     * there is a thread associated with the activity.
11409     */
11410    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11411            final ActivityRecord r, String[] args, boolean dumpAll) {
11412        String innerPrefix = prefix + "  ";
11413        synchronized (this) {
11414            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11415                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11416                    pw.print(" pid=");
11417                    if (r.app != null) pw.println(r.app.pid);
11418                    else pw.println("(not running)");
11419            if (dumpAll) {
11420                r.dump(pw, innerPrefix);
11421            }
11422        }
11423        if (r.app != null && r.app.thread != null) {
11424            // flush anything that is already in the PrintWriter since the thread is going
11425            // to write to the file descriptor directly
11426            pw.flush();
11427            try {
11428                TransferPipe tp = new TransferPipe();
11429                try {
11430                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11431                            r.appToken, innerPrefix, args);
11432                    tp.go(fd);
11433                } finally {
11434                    tp.kill();
11435                }
11436            } catch (IOException e) {
11437                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11438            } catch (RemoteException e) {
11439                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11440            }
11441        }
11442    }
11443
11444    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11445            int opti, boolean dumpAll, String dumpPackage) {
11446        boolean needSep = false;
11447        boolean onlyHistory = false;
11448        boolean printedAnything = false;
11449
11450        if ("history".equals(dumpPackage)) {
11451            if (opti < args.length && "-s".equals(args[opti])) {
11452                dumpAll = false;
11453            }
11454            onlyHistory = true;
11455            dumpPackage = null;
11456        }
11457
11458        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11459        if (!onlyHistory && dumpAll) {
11460            if (mRegisteredReceivers.size() > 0) {
11461                boolean printed = false;
11462                Iterator it = mRegisteredReceivers.values().iterator();
11463                while (it.hasNext()) {
11464                    ReceiverList r = (ReceiverList)it.next();
11465                    if (dumpPackage != null && (r.app == null ||
11466                            !dumpPackage.equals(r.app.info.packageName))) {
11467                        continue;
11468                    }
11469                    if (!printed) {
11470                        pw.println("  Registered Receivers:");
11471                        needSep = true;
11472                        printed = true;
11473                        printedAnything = true;
11474                    }
11475                    pw.print("  * "); pw.println(r);
11476                    r.dump(pw, "    ");
11477                }
11478            }
11479
11480            if (mReceiverResolver.dump(pw, needSep ?
11481                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11482                    "    ", dumpPackage, false)) {
11483                needSep = true;
11484                printedAnything = true;
11485            }
11486        }
11487
11488        for (BroadcastQueue q : mBroadcastQueues) {
11489            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11490            printedAnything |= needSep;
11491        }
11492
11493        needSep = true;
11494
11495        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11496            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11497                if (needSep) {
11498                    pw.println();
11499                }
11500                needSep = true;
11501                printedAnything = true;
11502                pw.print("  Sticky broadcasts for user ");
11503                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11504                StringBuilder sb = new StringBuilder(128);
11505                for (Map.Entry<String, ArrayList<Intent>> ent
11506                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11507                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11508                    if (dumpAll) {
11509                        pw.println(":");
11510                        ArrayList<Intent> intents = ent.getValue();
11511                        final int N = intents.size();
11512                        for (int i=0; i<N; i++) {
11513                            sb.setLength(0);
11514                            sb.append("    Intent: ");
11515                            intents.get(i).toShortString(sb, false, true, false, false);
11516                            pw.println(sb.toString());
11517                            Bundle bundle = intents.get(i).getExtras();
11518                            if (bundle != null) {
11519                                pw.print("      ");
11520                                pw.println(bundle.toString());
11521                            }
11522                        }
11523                    } else {
11524                        pw.println("");
11525                    }
11526                }
11527            }
11528        }
11529
11530        if (!onlyHistory && dumpAll) {
11531            pw.println();
11532            for (BroadcastQueue queue : mBroadcastQueues) {
11533                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11534                        + queue.mBroadcastsScheduled);
11535            }
11536            pw.println("  mHandler:");
11537            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11538            needSep = true;
11539            printedAnything = true;
11540        }
11541
11542        if (!printedAnything) {
11543            pw.println("  (nothing)");
11544        }
11545    }
11546
11547    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11548            int opti, boolean dumpAll, String dumpPackage) {
11549        boolean needSep;
11550        boolean printedAnything = false;
11551
11552        ItemMatcher matcher = new ItemMatcher();
11553        matcher.build(args, opti);
11554
11555        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11556
11557        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11558        printedAnything |= needSep;
11559
11560        if (mLaunchingProviders.size() > 0) {
11561            boolean printed = false;
11562            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11563                ContentProviderRecord r = mLaunchingProviders.get(i);
11564                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11565                    continue;
11566                }
11567                if (!printed) {
11568                    if (needSep) pw.println();
11569                    needSep = true;
11570                    pw.println("  Launching content providers:");
11571                    printed = true;
11572                    printedAnything = true;
11573                }
11574                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11575                        pw.println(r);
11576            }
11577        }
11578
11579        if (mGrantedUriPermissions.size() > 0) {
11580            boolean printed = false;
11581            int dumpUid = -2;
11582            if (dumpPackage != null) {
11583                try {
11584                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11585                } catch (NameNotFoundException e) {
11586                    dumpUid = -1;
11587                }
11588            }
11589            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11590                int uid = mGrantedUriPermissions.keyAt(i);
11591                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11592                    continue;
11593                }
11594                ArrayMap<Uri, UriPermission> perms
11595                        = mGrantedUriPermissions.valueAt(i);
11596                if (!printed) {
11597                    if (needSep) pw.println();
11598                    needSep = true;
11599                    pw.println("  Granted Uri Permissions:");
11600                    printed = true;
11601                    printedAnything = true;
11602                }
11603                pw.print("  * UID "); pw.print(uid);
11604                        pw.println(" holds:");
11605                for (UriPermission perm : perms.values()) {
11606                    pw.print("    "); pw.println(perm);
11607                    if (dumpAll) {
11608                        perm.dump(pw, "      ");
11609                    }
11610                }
11611            }
11612        }
11613
11614        if (!printedAnything) {
11615            pw.println("  (nothing)");
11616        }
11617    }
11618
11619    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11620            int opti, boolean dumpAll, String dumpPackage) {
11621        boolean printed = false;
11622
11623        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11624
11625        if (mIntentSenderRecords.size() > 0) {
11626            Iterator<WeakReference<PendingIntentRecord>> it
11627                    = mIntentSenderRecords.values().iterator();
11628            while (it.hasNext()) {
11629                WeakReference<PendingIntentRecord> ref = it.next();
11630                PendingIntentRecord rec = ref != null ? ref.get(): null;
11631                if (dumpPackage != null && (rec == null
11632                        || !dumpPackage.equals(rec.key.packageName))) {
11633                    continue;
11634                }
11635                printed = true;
11636                if (rec != null) {
11637                    pw.print("  * "); pw.println(rec);
11638                    if (dumpAll) {
11639                        rec.dump(pw, "    ");
11640                    }
11641                } else {
11642                    pw.print("  * "); pw.println(ref);
11643                }
11644            }
11645        }
11646
11647        if (!printed) {
11648            pw.println("  (nothing)");
11649        }
11650    }
11651
11652    private static final int dumpProcessList(PrintWriter pw,
11653            ActivityManagerService service, List list,
11654            String prefix, String normalLabel, String persistentLabel,
11655            String dumpPackage) {
11656        int numPers = 0;
11657        final int N = list.size()-1;
11658        for (int i=N; i>=0; i--) {
11659            ProcessRecord r = (ProcessRecord)list.get(i);
11660            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11661                continue;
11662            }
11663            pw.println(String.format("%s%s #%2d: %s",
11664                    prefix, (r.persistent ? persistentLabel : normalLabel),
11665                    i, r.toString()));
11666            if (r.persistent) {
11667                numPers++;
11668            }
11669        }
11670        return numPers;
11671    }
11672
11673    private static final boolean dumpProcessOomList(PrintWriter pw,
11674            ActivityManagerService service, List<ProcessRecord> origList,
11675            String prefix, String normalLabel, String persistentLabel,
11676            boolean inclDetails, String dumpPackage) {
11677
11678        ArrayList<Pair<ProcessRecord, Integer>> list
11679                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11680        for (int i=0; i<origList.size(); i++) {
11681            ProcessRecord r = origList.get(i);
11682            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11683                continue;
11684            }
11685            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11686        }
11687
11688        if (list.size() <= 0) {
11689            return false;
11690        }
11691
11692        Comparator<Pair<ProcessRecord, Integer>> comparator
11693                = new Comparator<Pair<ProcessRecord, Integer>>() {
11694            @Override
11695            public int compare(Pair<ProcessRecord, Integer> object1,
11696                    Pair<ProcessRecord, Integer> object2) {
11697                if (object1.first.setAdj != object2.first.setAdj) {
11698                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11699                }
11700                if (object1.second.intValue() != object2.second.intValue()) {
11701                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11702                }
11703                return 0;
11704            }
11705        };
11706
11707        Collections.sort(list, comparator);
11708
11709        final long curRealtime = SystemClock.elapsedRealtime();
11710        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11711        final long curUptime = SystemClock.uptimeMillis();
11712        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11713
11714        for (int i=list.size()-1; i>=0; i--) {
11715            ProcessRecord r = list.get(i).first;
11716            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11717            char schedGroup;
11718            switch (r.setSchedGroup) {
11719                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11720                    schedGroup = 'B';
11721                    break;
11722                case Process.THREAD_GROUP_DEFAULT:
11723                    schedGroup = 'F';
11724                    break;
11725                default:
11726                    schedGroup = '?';
11727                    break;
11728            }
11729            char foreground;
11730            if (r.foregroundActivities) {
11731                foreground = 'A';
11732            } else if (r.foregroundServices) {
11733                foreground = 'S';
11734            } else {
11735                foreground = ' ';
11736            }
11737            String procState = ProcessList.makeProcStateString(r.curProcState);
11738            pw.print(prefix);
11739            pw.print(r.persistent ? persistentLabel : normalLabel);
11740            pw.print(" #");
11741            int num = (origList.size()-1)-list.get(i).second;
11742            if (num < 10) pw.print(' ');
11743            pw.print(num);
11744            pw.print(": ");
11745            pw.print(oomAdj);
11746            pw.print(' ');
11747            pw.print(schedGroup);
11748            pw.print('/');
11749            pw.print(foreground);
11750            pw.print('/');
11751            pw.print(procState);
11752            pw.print(" trm:");
11753            if (r.trimMemoryLevel < 10) pw.print(' ');
11754            pw.print(r.trimMemoryLevel);
11755            pw.print(' ');
11756            pw.print(r.toShortString());
11757            pw.print(" (");
11758            pw.print(r.adjType);
11759            pw.println(')');
11760            if (r.adjSource != null || r.adjTarget != null) {
11761                pw.print(prefix);
11762                pw.print("    ");
11763                if (r.adjTarget instanceof ComponentName) {
11764                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11765                } else if (r.adjTarget != null) {
11766                    pw.print(r.adjTarget.toString());
11767                } else {
11768                    pw.print("{null}");
11769                }
11770                pw.print("<=");
11771                if (r.adjSource instanceof ProcessRecord) {
11772                    pw.print("Proc{");
11773                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11774                    pw.println("}");
11775                } else if (r.adjSource != null) {
11776                    pw.println(r.adjSource.toString());
11777                } else {
11778                    pw.println("{null}");
11779                }
11780            }
11781            if (inclDetails) {
11782                pw.print(prefix);
11783                pw.print("    ");
11784                pw.print("oom: max="); pw.print(r.maxAdj);
11785                pw.print(" curRaw="); pw.print(r.curRawAdj);
11786                pw.print(" setRaw="); pw.print(r.setRawAdj);
11787                pw.print(" cur="); pw.print(r.curAdj);
11788                pw.print(" set="); pw.println(r.setAdj);
11789                pw.print(prefix);
11790                pw.print("    ");
11791                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
11792                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
11793                pw.print(" lastPss="); pw.print(r.lastPss);
11794                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
11795                pw.print(prefix);
11796                pw.print("    ");
11797                pw.print("keeping="); pw.print(r.keeping);
11798                pw.print(" cached="); pw.print(r.cached);
11799                pw.print(" empty="); pw.print(r.empty);
11800                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
11801
11802                if (!r.keeping) {
11803                    if (r.lastWakeTime != 0) {
11804                        long wtime;
11805                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
11806                        synchronized (stats) {
11807                            wtime = stats.getProcessWakeTime(r.info.uid,
11808                                    r.pid, curRealtime);
11809                        }
11810                        long timeUsed = wtime - r.lastWakeTime;
11811                        pw.print(prefix);
11812                        pw.print("    ");
11813                        pw.print("keep awake over ");
11814                        TimeUtils.formatDuration(realtimeSince, pw);
11815                        pw.print(" used ");
11816                        TimeUtils.formatDuration(timeUsed, pw);
11817                        pw.print(" (");
11818                        pw.print((timeUsed*100)/realtimeSince);
11819                        pw.println("%)");
11820                    }
11821                    if (r.lastCpuTime != 0) {
11822                        long timeUsed = r.curCpuTime - r.lastCpuTime;
11823                        pw.print(prefix);
11824                        pw.print("    ");
11825                        pw.print("run cpu over ");
11826                        TimeUtils.formatDuration(uptimeSince, pw);
11827                        pw.print(" used ");
11828                        TimeUtils.formatDuration(timeUsed, pw);
11829                        pw.print(" (");
11830                        pw.print((timeUsed*100)/uptimeSince);
11831                        pw.println("%)");
11832                    }
11833                }
11834            }
11835        }
11836        return true;
11837    }
11838
11839    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
11840        ArrayList<ProcessRecord> procs;
11841        synchronized (this) {
11842            if (args != null && args.length > start
11843                    && args[start].charAt(0) != '-') {
11844                procs = new ArrayList<ProcessRecord>();
11845                int pid = -1;
11846                try {
11847                    pid = Integer.parseInt(args[start]);
11848                } catch (NumberFormatException e) {
11849                }
11850                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11851                    ProcessRecord proc = mLruProcesses.get(i);
11852                    if (proc.pid == pid) {
11853                        procs.add(proc);
11854                    } else if (proc.processName.equals(args[start])) {
11855                        procs.add(proc);
11856                    }
11857                }
11858                if (procs.size() <= 0) {
11859                    return null;
11860                }
11861            } else {
11862                procs = new ArrayList<ProcessRecord>(mLruProcesses);
11863            }
11864        }
11865        return procs;
11866    }
11867
11868    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
11869            PrintWriter pw, String[] args) {
11870        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11871        if (procs == null) {
11872            pw.println("No process found for: " + args[0]);
11873            return;
11874        }
11875
11876        long uptime = SystemClock.uptimeMillis();
11877        long realtime = SystemClock.elapsedRealtime();
11878        pw.println("Applications Graphics Acceleration Info:");
11879        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11880
11881        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11882            ProcessRecord r = procs.get(i);
11883            if (r.thread != null) {
11884                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
11885                pw.flush();
11886                try {
11887                    TransferPipe tp = new TransferPipe();
11888                    try {
11889                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
11890                        tp.go(fd);
11891                    } finally {
11892                        tp.kill();
11893                    }
11894                } catch (IOException e) {
11895                    pw.println("Failure while dumping the app: " + r);
11896                    pw.flush();
11897                } catch (RemoteException e) {
11898                    pw.println("Got a RemoteException while dumping the app " + r);
11899                    pw.flush();
11900                }
11901            }
11902        }
11903    }
11904
11905    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
11906        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11907        if (procs == null) {
11908            pw.println("No process found for: " + args[0]);
11909            return;
11910        }
11911
11912        pw.println("Applications Database Info:");
11913
11914        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11915            ProcessRecord r = procs.get(i);
11916            if (r.thread != null) {
11917                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
11918                pw.flush();
11919                try {
11920                    TransferPipe tp = new TransferPipe();
11921                    try {
11922                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
11923                        tp.go(fd);
11924                    } finally {
11925                        tp.kill();
11926                    }
11927                } catch (IOException e) {
11928                    pw.println("Failure while dumping the app: " + r);
11929                    pw.flush();
11930                } catch (RemoteException e) {
11931                    pw.println("Got a RemoteException while dumping the app " + r);
11932                    pw.flush();
11933                }
11934            }
11935        }
11936    }
11937
11938    final static class MemItem {
11939        final boolean isProc;
11940        final String label;
11941        final String shortLabel;
11942        final long pss;
11943        final int id;
11944        final boolean hasActivities;
11945        ArrayList<MemItem> subitems;
11946
11947        public MemItem(String _label, String _shortLabel, long _pss, int _id,
11948                boolean _hasActivities) {
11949            isProc = true;
11950            label = _label;
11951            shortLabel = _shortLabel;
11952            pss = _pss;
11953            id = _id;
11954            hasActivities = _hasActivities;
11955        }
11956
11957        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
11958            isProc = false;
11959            label = _label;
11960            shortLabel = _shortLabel;
11961            pss = _pss;
11962            id = _id;
11963            hasActivities = false;
11964        }
11965    }
11966
11967    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
11968            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
11969        if (sort && !isCompact) {
11970            Collections.sort(items, new Comparator<MemItem>() {
11971                @Override
11972                public int compare(MemItem lhs, MemItem rhs) {
11973                    if (lhs.pss < rhs.pss) {
11974                        return 1;
11975                    } else if (lhs.pss > rhs.pss) {
11976                        return -1;
11977                    }
11978                    return 0;
11979                }
11980            });
11981        }
11982
11983        for (int i=0; i<items.size(); i++) {
11984            MemItem mi = items.get(i);
11985            if (!isCompact) {
11986                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
11987            } else if (mi.isProc) {
11988                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
11989                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
11990                pw.println(mi.hasActivities ? ",a" : ",e");
11991            } else {
11992                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
11993                pw.println(mi.pss);
11994            }
11995            if (mi.subitems != null) {
11996                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
11997                        true, isCompact);
11998            }
11999        }
12000    }
12001
12002    // These are in KB.
12003    static final long[] DUMP_MEM_BUCKETS = new long[] {
12004        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12005        120*1024, 160*1024, 200*1024,
12006        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12007        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12008    };
12009
12010    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12011            boolean stackLike) {
12012        int start = label.lastIndexOf('.');
12013        if (start >= 0) start++;
12014        else start = 0;
12015        int end = label.length();
12016        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12017            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12018                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12019                out.append(bucket);
12020                out.append(stackLike ? "MB." : "MB ");
12021                out.append(label, start, end);
12022                return;
12023            }
12024        }
12025        out.append(memKB/1024);
12026        out.append(stackLike ? "MB." : "MB ");
12027        out.append(label, start, end);
12028    }
12029
12030    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12031            ProcessList.NATIVE_ADJ,
12032            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12033            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12034            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12035            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12036            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12037    };
12038    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12039            "Native",
12040            "System", "Persistent", "Foreground",
12041            "Visible", "Perceptible",
12042            "Heavy Weight", "Backup",
12043            "A Services", "Home",
12044            "Previous", "B Services", "Cached"
12045    };
12046    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12047            "native",
12048            "sys", "pers", "fore",
12049            "vis", "percept",
12050            "heavy", "backup",
12051            "servicea", "home",
12052            "prev", "serviceb", "cached"
12053    };
12054
12055    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12056            long realtime, boolean isCheckinRequest, boolean isCompact) {
12057        if (isCheckinRequest || isCompact) {
12058            // short checkin version
12059            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12060        } else {
12061            pw.println("Applications Memory Usage (kB):");
12062            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12063        }
12064    }
12065
12066    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12067            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12068        boolean dumpDetails = false;
12069        boolean dumpFullDetails = false;
12070        boolean dumpDalvik = false;
12071        boolean oomOnly = false;
12072        boolean isCompact = false;
12073        boolean localOnly = false;
12074
12075        int opti = 0;
12076        while (opti < args.length) {
12077            String opt = args[opti];
12078            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12079                break;
12080            }
12081            opti++;
12082            if ("-a".equals(opt)) {
12083                dumpDetails = true;
12084                dumpFullDetails = true;
12085                dumpDalvik = true;
12086            } else if ("-d".equals(opt)) {
12087                dumpDalvik = true;
12088            } else if ("-c".equals(opt)) {
12089                isCompact = true;
12090            } else if ("--oom".equals(opt)) {
12091                oomOnly = true;
12092            } else if ("--local".equals(opt)) {
12093                localOnly = true;
12094            } else if ("-h".equals(opt)) {
12095                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12096                pw.println("  -a: include all available information for each process.");
12097                pw.println("  -d: include dalvik details when dumping process details.");
12098                pw.println("  -c: dump in a compact machine-parseable representation.");
12099                pw.println("  --oom: only show processes organized by oom adj.");
12100                pw.println("  --local: only collect details locally, don't call process.");
12101                pw.println("If [process] is specified it can be the name or ");
12102                pw.println("pid of a specific process to dump.");
12103                return;
12104            } else {
12105                pw.println("Unknown argument: " + opt + "; use -h for help");
12106            }
12107        }
12108
12109        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12110        long uptime = SystemClock.uptimeMillis();
12111        long realtime = SystemClock.elapsedRealtime();
12112        final long[] tmpLong = new long[1];
12113
12114        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12115        if (procs == null) {
12116            // No Java processes.  Maybe they want to print a native process.
12117            if (args != null && args.length > opti
12118                    && args[opti].charAt(0) != '-') {
12119                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12120                        = new ArrayList<ProcessCpuTracker.Stats>();
12121                updateCpuStatsNow();
12122                int findPid = -1;
12123                try {
12124                    findPid = Integer.parseInt(args[opti]);
12125                } catch (NumberFormatException e) {
12126                }
12127                synchronized (mProcessCpuThread) {
12128                    final int N = mProcessCpuTracker.countStats();
12129                    for (int i=0; i<N; i++) {
12130                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12131                        if (st.pid == findPid || (st.baseName != null
12132                                && st.baseName.equals(args[opti]))) {
12133                            nativeProcs.add(st);
12134                        }
12135                    }
12136                }
12137                if (nativeProcs.size() > 0) {
12138                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12139                            isCompact);
12140                    Debug.MemoryInfo mi = null;
12141                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12142                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12143                        final int pid = r.pid;
12144                        if (!isCheckinRequest && dumpDetails) {
12145                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12146                        }
12147                        if (mi == null) {
12148                            mi = new Debug.MemoryInfo();
12149                        }
12150                        if (dumpDetails || (!brief && !oomOnly)) {
12151                            Debug.getMemoryInfo(pid, mi);
12152                        } else {
12153                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12154                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12155                        }
12156                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12157                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12158                        if (isCheckinRequest) {
12159                            pw.println();
12160                        }
12161                    }
12162                    return;
12163                }
12164            }
12165            pw.println("No process found for: " + args[opti]);
12166            return;
12167        }
12168
12169        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12170            dumpDetails = true;
12171        }
12172
12173        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12174
12175        String[] innerArgs = new String[args.length-opti];
12176        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12177
12178        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12179        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12180        long nativePss=0, dalvikPss=0, otherPss=0;
12181        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12182
12183        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12184        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12185                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12186
12187        long totalPss = 0;
12188        long cachedPss = 0;
12189
12190        Debug.MemoryInfo mi = null;
12191        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12192            final ProcessRecord r = procs.get(i);
12193            final IApplicationThread thread;
12194            final int pid;
12195            final int oomAdj;
12196            final boolean hasActivities;
12197            synchronized (this) {
12198                thread = r.thread;
12199                pid = r.pid;
12200                oomAdj = r.getSetAdjWithServices();
12201                hasActivities = r.activities.size() > 0;
12202            }
12203            if (thread != null) {
12204                if (!isCheckinRequest && dumpDetails) {
12205                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12206                }
12207                if (mi == null) {
12208                    mi = new Debug.MemoryInfo();
12209                }
12210                if (dumpDetails || (!brief && !oomOnly)) {
12211                    Debug.getMemoryInfo(pid, mi);
12212                } else {
12213                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12214                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12215                }
12216                if (dumpDetails) {
12217                    if (localOnly) {
12218                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12219                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12220                        if (isCheckinRequest) {
12221                            pw.println();
12222                        }
12223                    } else {
12224                        try {
12225                            pw.flush();
12226                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12227                                    dumpDalvik, innerArgs);
12228                        } catch (RemoteException e) {
12229                            if (!isCheckinRequest) {
12230                                pw.println("Got RemoteException!");
12231                                pw.flush();
12232                            }
12233                        }
12234                    }
12235                }
12236
12237                final long myTotalPss = mi.getTotalPss();
12238                final long myTotalUss = mi.getTotalUss();
12239
12240                synchronized (this) {
12241                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12242                        // Record this for posterity if the process has been stable.
12243                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12244                    }
12245                }
12246
12247                if (!isCheckinRequest && mi != null) {
12248                    totalPss += myTotalPss;
12249                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12250                            (hasActivities ? " / activities)" : ")"),
12251                            r.processName, myTotalPss, pid, hasActivities);
12252                    procMems.add(pssItem);
12253                    procMemsMap.put(pid, pssItem);
12254
12255                    nativePss += mi.nativePss;
12256                    dalvikPss += mi.dalvikPss;
12257                    otherPss += mi.otherPss;
12258                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12259                        long mem = mi.getOtherPss(j);
12260                        miscPss[j] += mem;
12261                        otherPss -= mem;
12262                    }
12263
12264                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12265                        cachedPss += myTotalPss;
12266                    }
12267
12268                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12269                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12270                                || oomIndex == (oomPss.length-1)) {
12271                            oomPss[oomIndex] += myTotalPss;
12272                            if (oomProcs[oomIndex] == null) {
12273                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12274                            }
12275                            oomProcs[oomIndex].add(pssItem);
12276                            break;
12277                        }
12278                    }
12279                }
12280            }
12281        }
12282
12283        if (!isCheckinRequest && procs.size() > 1) {
12284            // If we are showing aggregations, also look for native processes to
12285            // include so that our aggregations are more accurate.
12286            updateCpuStatsNow();
12287            synchronized (mProcessCpuThread) {
12288                final int N = mProcessCpuTracker.countStats();
12289                for (int i=0; i<N; i++) {
12290                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12291                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12292                        if (mi == null) {
12293                            mi = new Debug.MemoryInfo();
12294                        }
12295                        if (!brief && !oomOnly) {
12296                            Debug.getMemoryInfo(st.pid, mi);
12297                        } else {
12298                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12299                            mi.nativePrivateDirty = (int)tmpLong[0];
12300                        }
12301
12302                        final long myTotalPss = mi.getTotalPss();
12303                        totalPss += myTotalPss;
12304
12305                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12306                                st.name, myTotalPss, st.pid, false);
12307                        procMems.add(pssItem);
12308
12309                        nativePss += mi.nativePss;
12310                        dalvikPss += mi.dalvikPss;
12311                        otherPss += mi.otherPss;
12312                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12313                            long mem = mi.getOtherPss(j);
12314                            miscPss[j] += mem;
12315                            otherPss -= mem;
12316                        }
12317                        oomPss[0] += myTotalPss;
12318                        if (oomProcs[0] == null) {
12319                            oomProcs[0] = new ArrayList<MemItem>();
12320                        }
12321                        oomProcs[0].add(pssItem);
12322                    }
12323                }
12324            }
12325
12326            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12327
12328            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12329            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12330            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12331            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12332                String label = Debug.MemoryInfo.getOtherLabel(j);
12333                catMems.add(new MemItem(label, label, miscPss[j], j));
12334            }
12335
12336            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12337            for (int j=0; j<oomPss.length; j++) {
12338                if (oomPss[j] != 0) {
12339                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12340                            : DUMP_MEM_OOM_LABEL[j];
12341                    MemItem item = new MemItem(label, label, oomPss[j],
12342                            DUMP_MEM_OOM_ADJ[j]);
12343                    item.subitems = oomProcs[j];
12344                    oomMems.add(item);
12345                }
12346            }
12347
12348            if (!brief && !oomOnly && !isCompact) {
12349                pw.println();
12350                pw.println("Total PSS by process:");
12351                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12352                pw.println();
12353            }
12354            if (!isCompact) {
12355                pw.println("Total PSS by OOM adjustment:");
12356            }
12357            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12358            if (!brief && !oomOnly) {
12359                PrintWriter out = categoryPw != null ? categoryPw : pw;
12360                if (!isCompact) {
12361                    out.println();
12362                    out.println("Total PSS by category:");
12363                }
12364                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12365            }
12366            if (!isCompact) {
12367                pw.println();
12368            }
12369            MemInfoReader memInfo = new MemInfoReader();
12370            memInfo.readMemInfo();
12371            if (!brief) {
12372                if (!isCompact) {
12373                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12374                    pw.print(" kB (status ");
12375                    switch (mLastMemoryLevel) {
12376                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12377                            pw.println("normal)");
12378                            break;
12379                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12380                            pw.println("moderate)");
12381                            break;
12382                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12383                            pw.println("low)");
12384                            break;
12385                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12386                            pw.println("critical)");
12387                            break;
12388                        default:
12389                            pw.print(mLastMemoryLevel);
12390                            pw.println(")");
12391                            break;
12392                    }
12393                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12394                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12395                            pw.print(cachedPss); pw.print(" cached pss + ");
12396                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12397                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12398                } else {
12399                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12400                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12401                            + memInfo.getFreeSizeKb()); pw.print(",");
12402                    pw.println(totalPss - cachedPss);
12403                }
12404            }
12405            if (!isCompact) {
12406                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12407                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12408                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12409                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12410                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12411                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12412                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12413                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12414                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12415                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12416                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12417            }
12418            if (!brief) {
12419                if (memInfo.getZramTotalSizeKb() != 0) {
12420                    if (!isCompact) {
12421                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12422                                pw.print(" kB physical used for ");
12423                                pw.print(memInfo.getSwapTotalSizeKb()
12424                                        - memInfo.getSwapFreeSizeKb());
12425                                pw.print(" kB in swap (");
12426                                pw.print(memInfo.getSwapTotalSizeKb());
12427                                pw.println(" kB total swap)");
12428                    } else {
12429                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12430                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12431                                pw.println(memInfo.getSwapFreeSizeKb());
12432                    }
12433                }
12434                final int[] SINGLE_LONG_FORMAT = new int[] {
12435                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12436                };
12437                long[] longOut = new long[1];
12438                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12439                        SINGLE_LONG_FORMAT, null, longOut, null);
12440                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12441                longOut[0] = 0;
12442                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12443                        SINGLE_LONG_FORMAT, null, longOut, null);
12444                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12445                longOut[0] = 0;
12446                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12447                        SINGLE_LONG_FORMAT, null, longOut, null);
12448                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12449                longOut[0] = 0;
12450                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12451                        SINGLE_LONG_FORMAT, null, longOut, null);
12452                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12453                if (!isCompact) {
12454                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12455                        pw.print("      KSM: "); pw.print(sharing);
12456                                pw.print(" kB saved from shared ");
12457                                pw.print(shared); pw.println(" kB");
12458                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12459                                pw.print(voltile); pw.println(" kB volatile");
12460                    }
12461                    pw.print("   Tuning: ");
12462                    pw.print(ActivityManager.staticGetMemoryClass());
12463                    pw.print(" (large ");
12464                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12465                    pw.print("), oom ");
12466                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12467                    pw.print(" kB");
12468                    pw.print(", restore limit ");
12469                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12470                    pw.print(" kB");
12471                    if (ActivityManager.isLowRamDeviceStatic()) {
12472                        pw.print(" (low-ram)");
12473                    }
12474                    if (ActivityManager.isHighEndGfx()) {
12475                        pw.print(" (high-end-gfx)");
12476                    }
12477                    pw.println();
12478                } else {
12479                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12480                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12481                    pw.println(voltile);
12482                    pw.print("tuning,");
12483                    pw.print(ActivityManager.staticGetMemoryClass());
12484                    pw.print(',');
12485                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12486                    pw.print(',');
12487                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12488                    if (ActivityManager.isLowRamDeviceStatic()) {
12489                        pw.print(",low-ram");
12490                    }
12491                    if (ActivityManager.isHighEndGfx()) {
12492                        pw.print(",high-end-gfx");
12493                    }
12494                    pw.println();
12495                }
12496            }
12497        }
12498    }
12499
12500    /**
12501     * Searches array of arguments for the specified string
12502     * @param args array of argument strings
12503     * @param value value to search for
12504     * @return true if the value is contained in the array
12505     */
12506    private static boolean scanArgs(String[] args, String value) {
12507        if (args != null) {
12508            for (String arg : args) {
12509                if (value.equals(arg)) {
12510                    return true;
12511                }
12512            }
12513        }
12514        return false;
12515    }
12516
12517    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12518            ContentProviderRecord cpr, boolean always) {
12519        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12520
12521        if (!inLaunching || always) {
12522            synchronized (cpr) {
12523                cpr.launchingApp = null;
12524                cpr.notifyAll();
12525            }
12526            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12527            String names[] = cpr.info.authority.split(";");
12528            for (int j = 0; j < names.length; j++) {
12529                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12530            }
12531        }
12532
12533        for (int i=0; i<cpr.connections.size(); i++) {
12534            ContentProviderConnection conn = cpr.connections.get(i);
12535            if (conn.waiting) {
12536                // If this connection is waiting for the provider, then we don't
12537                // need to mess with its process unless we are always removing
12538                // or for some reason the provider is not currently launching.
12539                if (inLaunching && !always) {
12540                    continue;
12541                }
12542            }
12543            ProcessRecord capp = conn.client;
12544            conn.dead = true;
12545            if (conn.stableCount > 0) {
12546                if (!capp.persistent && capp.thread != null
12547                        && capp.pid != 0
12548                        && capp.pid != MY_PID) {
12549                    killUnneededProcessLocked(capp, "depends on provider "
12550                            + cpr.name.flattenToShortString()
12551                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12552                }
12553            } else if (capp.thread != null && conn.provider.provider != null) {
12554                try {
12555                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12556                } catch (RemoteException e) {
12557                }
12558                // In the protocol here, we don't expect the client to correctly
12559                // clean up this connection, we'll just remove it.
12560                cpr.connections.remove(i);
12561                conn.client.conProviders.remove(conn);
12562            }
12563        }
12564
12565        if (inLaunching && always) {
12566            mLaunchingProviders.remove(cpr);
12567        }
12568        return inLaunching;
12569    }
12570
12571    /**
12572     * Main code for cleaning up a process when it has gone away.  This is
12573     * called both as a result of the process dying, or directly when stopping
12574     * a process when running in single process mode.
12575     */
12576    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12577            boolean restarting, boolean allowRestart, int index) {
12578        if (index >= 0) {
12579            removeLruProcessLocked(app);
12580            ProcessList.remove(app.pid);
12581        }
12582
12583        mProcessesToGc.remove(app);
12584        mPendingPssProcesses.remove(app);
12585
12586        // Dismiss any open dialogs.
12587        if (app.crashDialog != null && !app.forceCrashReport) {
12588            app.crashDialog.dismiss();
12589            app.crashDialog = null;
12590        }
12591        if (app.anrDialog != null) {
12592            app.anrDialog.dismiss();
12593            app.anrDialog = null;
12594        }
12595        if (app.waitDialog != null) {
12596            app.waitDialog.dismiss();
12597            app.waitDialog = null;
12598        }
12599
12600        app.crashing = false;
12601        app.notResponding = false;
12602
12603        app.resetPackageList(mProcessStats);
12604        app.unlinkDeathRecipient();
12605        app.makeInactive(mProcessStats);
12606        app.forcingToForeground = null;
12607        updateProcessForegroundLocked(app, false, false);
12608        app.foregroundActivities = false;
12609        app.hasShownUi = false;
12610        app.treatLikeActivity = false;
12611        app.hasAboveClient = false;
12612        app.hasClientActivities = false;
12613
12614        mServices.killServicesLocked(app, allowRestart);
12615
12616        boolean restart = false;
12617
12618        // Remove published content providers.
12619        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12620            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12621            final boolean always = app.bad || !allowRestart;
12622            if (removeDyingProviderLocked(app, cpr, always) || always) {
12623                // We left the provider in the launching list, need to
12624                // restart it.
12625                restart = true;
12626            }
12627
12628            cpr.provider = null;
12629            cpr.proc = null;
12630        }
12631        app.pubProviders.clear();
12632
12633        // Take care of any launching providers waiting for this process.
12634        if (checkAppInLaunchingProvidersLocked(app, false)) {
12635            restart = true;
12636        }
12637
12638        // Unregister from connected content providers.
12639        if (!app.conProviders.isEmpty()) {
12640            for (int i=0; i<app.conProviders.size(); i++) {
12641                ContentProviderConnection conn = app.conProviders.get(i);
12642                conn.provider.connections.remove(conn);
12643            }
12644            app.conProviders.clear();
12645        }
12646
12647        // At this point there may be remaining entries in mLaunchingProviders
12648        // where we were the only one waiting, so they are no longer of use.
12649        // Look for these and clean up if found.
12650        // XXX Commented out for now.  Trying to figure out a way to reproduce
12651        // the actual situation to identify what is actually going on.
12652        if (false) {
12653            for (int i=0; i<mLaunchingProviders.size(); i++) {
12654                ContentProviderRecord cpr = (ContentProviderRecord)
12655                        mLaunchingProviders.get(i);
12656                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12657                    synchronized (cpr) {
12658                        cpr.launchingApp = null;
12659                        cpr.notifyAll();
12660                    }
12661                }
12662            }
12663        }
12664
12665        skipCurrentReceiverLocked(app);
12666
12667        // Unregister any receivers.
12668        for (int i=app.receivers.size()-1; i>=0; i--) {
12669            removeReceiverLocked(app.receivers.valueAt(i));
12670        }
12671        app.receivers.clear();
12672
12673        // If the app is undergoing backup, tell the backup manager about it
12674        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12675            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12676                    + mBackupTarget.appInfo + " died during backup");
12677            try {
12678                IBackupManager bm = IBackupManager.Stub.asInterface(
12679                        ServiceManager.getService(Context.BACKUP_SERVICE));
12680                bm.agentDisconnected(app.info.packageName);
12681            } catch (RemoteException e) {
12682                // can't happen; backup manager is local
12683            }
12684        }
12685
12686        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12687            ProcessChangeItem item = mPendingProcessChanges.get(i);
12688            if (item.pid == app.pid) {
12689                mPendingProcessChanges.remove(i);
12690                mAvailProcessChanges.add(item);
12691            }
12692        }
12693        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12694
12695        // If the caller is restarting this app, then leave it in its
12696        // current lists and let the caller take care of it.
12697        if (restarting) {
12698            return;
12699        }
12700
12701        if (!app.persistent || app.isolated) {
12702            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12703                    "Removing non-persistent process during cleanup: " + app);
12704            mProcessNames.remove(app.processName, app.uid);
12705            mIsolatedProcesses.remove(app.uid);
12706            if (mHeavyWeightProcess == app) {
12707                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12708                        mHeavyWeightProcess.userId, 0));
12709                mHeavyWeightProcess = null;
12710            }
12711        } else if (!app.removed) {
12712            // This app is persistent, so we need to keep its record around.
12713            // If it is not already on the pending app list, add it there
12714            // and start a new process for it.
12715            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12716                mPersistentStartingProcesses.add(app);
12717                restart = true;
12718            }
12719        }
12720        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12721                "Clean-up removing on hold: " + app);
12722        mProcessesOnHold.remove(app);
12723
12724        if (app == mHomeProcess) {
12725            mHomeProcess = null;
12726        }
12727        if (app == mPreviousProcess) {
12728            mPreviousProcess = null;
12729        }
12730
12731        if (restart && !app.isolated) {
12732            // We have components that still need to be running in the
12733            // process, so re-launch it.
12734            mProcessNames.put(app.processName, app.uid, app);
12735            startProcessLocked(app, "restart", app.processName);
12736        } else if (app.pid > 0 && app.pid != MY_PID) {
12737            // Goodbye!
12738            boolean removed;
12739            synchronized (mPidsSelfLocked) {
12740                mPidsSelfLocked.remove(app.pid);
12741                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12742            }
12743            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
12744                    app.processName, app.info.uid);
12745            if (app.isolated) {
12746                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
12747            }
12748            app.setPid(0);
12749        }
12750    }
12751
12752    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12753        // Look through the content providers we are waiting to have launched,
12754        // and if any run in this process then either schedule a restart of
12755        // the process or kill the client waiting for it if this process has
12756        // gone bad.
12757        int NL = mLaunchingProviders.size();
12758        boolean restart = false;
12759        for (int i=0; i<NL; i++) {
12760            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12761            if (cpr.launchingApp == app) {
12762                if (!alwaysBad && !app.bad) {
12763                    restart = true;
12764                } else {
12765                    removeDyingProviderLocked(app, cpr, true);
12766                    // cpr should have been removed from mLaunchingProviders
12767                    NL = mLaunchingProviders.size();
12768                    i--;
12769                }
12770            }
12771        }
12772        return restart;
12773    }
12774
12775    // =========================================================
12776    // SERVICES
12777    // =========================================================
12778
12779    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12780            int flags) {
12781        enforceNotIsolatedCaller("getServices");
12782        synchronized (this) {
12783            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12784        }
12785    }
12786
12787    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12788        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12789        synchronized (this) {
12790            return mServices.getRunningServiceControlPanelLocked(name);
12791        }
12792    }
12793
12794    public ComponentName startService(IApplicationThread caller, Intent service,
12795            String resolvedType, int userId) {
12796        enforceNotIsolatedCaller("startService");
12797        // Refuse possible leaked file descriptors
12798        if (service != null && service.hasFileDescriptors() == true) {
12799            throw new IllegalArgumentException("File descriptors passed in Intent");
12800        }
12801
12802        if (DEBUG_SERVICE)
12803            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
12804        synchronized(this) {
12805            final int callingPid = Binder.getCallingPid();
12806            final int callingUid = Binder.getCallingUid();
12807            final long origId = Binder.clearCallingIdentity();
12808            ComponentName res = mServices.startServiceLocked(caller, service,
12809                    resolvedType, callingPid, callingUid, userId);
12810            Binder.restoreCallingIdentity(origId);
12811            return res;
12812        }
12813    }
12814
12815    ComponentName startServiceInPackage(int uid,
12816            Intent service, String resolvedType, int userId) {
12817        synchronized(this) {
12818            if (DEBUG_SERVICE)
12819                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
12820            final long origId = Binder.clearCallingIdentity();
12821            ComponentName res = mServices.startServiceLocked(null, service,
12822                    resolvedType, -1, uid, userId);
12823            Binder.restoreCallingIdentity(origId);
12824            return res;
12825        }
12826    }
12827
12828    public int stopService(IApplicationThread caller, Intent service,
12829            String resolvedType, int userId) {
12830        enforceNotIsolatedCaller("stopService");
12831        // Refuse possible leaked file descriptors
12832        if (service != null && service.hasFileDescriptors() == true) {
12833            throw new IllegalArgumentException("File descriptors passed in Intent");
12834        }
12835
12836        synchronized(this) {
12837            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
12838        }
12839    }
12840
12841    public IBinder peekService(Intent service, String resolvedType) {
12842        enforceNotIsolatedCaller("peekService");
12843        // Refuse possible leaked file descriptors
12844        if (service != null && service.hasFileDescriptors() == true) {
12845            throw new IllegalArgumentException("File descriptors passed in Intent");
12846        }
12847        synchronized(this) {
12848            return mServices.peekServiceLocked(service, resolvedType);
12849        }
12850    }
12851
12852    public boolean stopServiceToken(ComponentName className, IBinder token,
12853            int startId) {
12854        synchronized(this) {
12855            return mServices.stopServiceTokenLocked(className, token, startId);
12856        }
12857    }
12858
12859    public void setServiceForeground(ComponentName className, IBinder token,
12860            int id, Notification notification, boolean removeNotification) {
12861        synchronized(this) {
12862            mServices.setServiceForegroundLocked(className, token, id, notification,
12863                    removeNotification);
12864        }
12865    }
12866
12867    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
12868            boolean requireFull, String name, String callerPackage) {
12869        final int callingUserId = UserHandle.getUserId(callingUid);
12870        if (callingUserId != userId) {
12871            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
12872                if ((requireFull || checkComponentPermission(
12873                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12874                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
12875                        && checkComponentPermission(
12876                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
12877                                callingPid, callingUid, -1, true)
12878                                != PackageManager.PERMISSION_GRANTED) {
12879                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
12880                        // In this case, they would like to just execute as their
12881                        // owner user instead of failing.
12882                        userId = callingUserId;
12883                    } else {
12884                        StringBuilder builder = new StringBuilder(128);
12885                        builder.append("Permission Denial: ");
12886                        builder.append(name);
12887                        if (callerPackage != null) {
12888                            builder.append(" from ");
12889                            builder.append(callerPackage);
12890                        }
12891                        builder.append(" asks to run as user ");
12892                        builder.append(userId);
12893                        builder.append(" but is calling from user ");
12894                        builder.append(UserHandle.getUserId(callingUid));
12895                        builder.append("; this requires ");
12896                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
12897                        if (!requireFull) {
12898                            builder.append(" or ");
12899                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
12900                        }
12901                        String msg = builder.toString();
12902                        Slog.w(TAG, msg);
12903                        throw new SecurityException(msg);
12904                    }
12905                }
12906            }
12907            if (userId == UserHandle.USER_CURRENT
12908                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
12909                // Note that we may be accessing this outside of a lock...
12910                // shouldn't be a big deal, if this is being called outside
12911                // of a locked context there is intrinsically a race with
12912                // the value the caller will receive and someone else changing it.
12913                userId = mCurrentUserId;
12914            }
12915            if (!allowAll && userId < 0) {
12916                throw new IllegalArgumentException(
12917                        "Call does not support special user #" + userId);
12918            }
12919        }
12920        return userId;
12921    }
12922
12923    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
12924            String className, int flags) {
12925        boolean result = false;
12926        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
12927            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
12928                if (ActivityManager.checkUidPermission(
12929                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12930                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
12931                    ComponentName comp = new ComponentName(aInfo.packageName, className);
12932                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
12933                            + " requests FLAG_SINGLE_USER, but app does not hold "
12934                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
12935                    Slog.w(TAG, msg);
12936                    throw new SecurityException(msg);
12937                }
12938                result = true;
12939            }
12940        } else if (componentProcessName == aInfo.packageName) {
12941            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
12942        } else if ("system".equals(componentProcessName)) {
12943            result = true;
12944        }
12945        if (DEBUG_MU) {
12946            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
12947                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
12948        }
12949        return result;
12950    }
12951
12952    public int bindService(IApplicationThread caller, IBinder token,
12953            Intent service, String resolvedType,
12954            IServiceConnection connection, int flags, int userId) {
12955        enforceNotIsolatedCaller("bindService");
12956        // Refuse possible leaked file descriptors
12957        if (service != null && service.hasFileDescriptors() == true) {
12958            throw new IllegalArgumentException("File descriptors passed in Intent");
12959        }
12960
12961        synchronized(this) {
12962            return mServices.bindServiceLocked(caller, token, service, resolvedType,
12963                    connection, flags, userId);
12964        }
12965    }
12966
12967    public boolean unbindService(IServiceConnection connection) {
12968        synchronized (this) {
12969            return mServices.unbindServiceLocked(connection);
12970        }
12971    }
12972
12973    public void publishService(IBinder token, Intent intent, IBinder service) {
12974        // Refuse possible leaked file descriptors
12975        if (intent != null && intent.hasFileDescriptors() == true) {
12976            throw new IllegalArgumentException("File descriptors passed in Intent");
12977        }
12978
12979        synchronized(this) {
12980            if (!(token instanceof ServiceRecord)) {
12981                throw new IllegalArgumentException("Invalid service token");
12982            }
12983            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
12984        }
12985    }
12986
12987    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
12988        // Refuse possible leaked file descriptors
12989        if (intent != null && intent.hasFileDescriptors() == true) {
12990            throw new IllegalArgumentException("File descriptors passed in Intent");
12991        }
12992
12993        synchronized(this) {
12994            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
12995        }
12996    }
12997
12998    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
12999        synchronized(this) {
13000            if (!(token instanceof ServiceRecord)) {
13001                throw new IllegalArgumentException("Invalid service token");
13002            }
13003            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13004        }
13005    }
13006
13007    // =========================================================
13008    // BACKUP AND RESTORE
13009    // =========================================================
13010
13011    // Cause the target app to be launched if necessary and its backup agent
13012    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13013    // activity manager to announce its creation.
13014    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13015        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13016        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
13017
13018        synchronized(this) {
13019            // !!! TODO: currently no check here that we're already bound
13020            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13021            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13022            synchronized (stats) {
13023                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13024            }
13025
13026            // Backup agent is now in use, its package can't be stopped.
13027            try {
13028                AppGlobals.getPackageManager().setPackageStoppedState(
13029                        app.packageName, false, UserHandle.getUserId(app.uid));
13030            } catch (RemoteException e) {
13031            } catch (IllegalArgumentException e) {
13032                Slog.w(TAG, "Failed trying to unstop package "
13033                        + app.packageName + ": " + e);
13034            }
13035
13036            BackupRecord r = new BackupRecord(ss, app, backupMode);
13037            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13038                    ? new ComponentName(app.packageName, app.backupAgentName)
13039                    : new ComponentName("android", "FullBackupAgent");
13040            // startProcessLocked() returns existing proc's record if it's already running
13041            ProcessRecord proc = startProcessLocked(app.processName, app,
13042                    false, 0, "backup", hostingName, false, false, false);
13043            if (proc == null) {
13044                Slog.e(TAG, "Unable to start backup agent process " + r);
13045                return false;
13046            }
13047
13048            r.app = proc;
13049            mBackupTarget = r;
13050            mBackupAppName = app.packageName;
13051
13052            // Try not to kill the process during backup
13053            updateOomAdjLocked(proc);
13054
13055            // If the process is already attached, schedule the creation of the backup agent now.
13056            // If it is not yet live, this will be done when it attaches to the framework.
13057            if (proc.thread != null) {
13058                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13059                try {
13060                    proc.thread.scheduleCreateBackupAgent(app,
13061                            compatibilityInfoForPackageLocked(app), backupMode);
13062                } catch (RemoteException e) {
13063                    // Will time out on the backup manager side
13064                }
13065            } else {
13066                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13067            }
13068            // Invariants: at this point, the target app process exists and the application
13069            // is either already running or in the process of coming up.  mBackupTarget and
13070            // mBackupAppName describe the app, so that when it binds back to the AM we
13071            // know that it's scheduled for a backup-agent operation.
13072        }
13073
13074        return true;
13075    }
13076
13077    @Override
13078    public void clearPendingBackup() {
13079        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13080        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13081
13082        synchronized (this) {
13083            mBackupTarget = null;
13084            mBackupAppName = null;
13085        }
13086    }
13087
13088    // A backup agent has just come up
13089    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13090        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13091                + " = " + agent);
13092
13093        synchronized(this) {
13094            if (!agentPackageName.equals(mBackupAppName)) {
13095                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13096                return;
13097            }
13098        }
13099
13100        long oldIdent = Binder.clearCallingIdentity();
13101        try {
13102            IBackupManager bm = IBackupManager.Stub.asInterface(
13103                    ServiceManager.getService(Context.BACKUP_SERVICE));
13104            bm.agentConnected(agentPackageName, agent);
13105        } catch (RemoteException e) {
13106            // can't happen; the backup manager service is local
13107        } catch (Exception e) {
13108            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13109            e.printStackTrace();
13110        } finally {
13111            Binder.restoreCallingIdentity(oldIdent);
13112        }
13113    }
13114
13115    // done with this agent
13116    public void unbindBackupAgent(ApplicationInfo appInfo) {
13117        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13118        if (appInfo == null) {
13119            Slog.w(TAG, "unbind backup agent for null app");
13120            return;
13121        }
13122
13123        synchronized(this) {
13124            try {
13125                if (mBackupAppName == null) {
13126                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13127                    return;
13128                }
13129
13130                if (!mBackupAppName.equals(appInfo.packageName)) {
13131                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13132                    return;
13133                }
13134
13135                // Not backing this app up any more; reset its OOM adjustment
13136                final ProcessRecord proc = mBackupTarget.app;
13137                updateOomAdjLocked(proc);
13138
13139                // If the app crashed during backup, 'thread' will be null here
13140                if (proc.thread != null) {
13141                    try {
13142                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13143                                compatibilityInfoForPackageLocked(appInfo));
13144                    } catch (Exception e) {
13145                        Slog.e(TAG, "Exception when unbinding backup agent:");
13146                        e.printStackTrace();
13147                    }
13148                }
13149            } finally {
13150                mBackupTarget = null;
13151                mBackupAppName = null;
13152            }
13153        }
13154    }
13155    // =========================================================
13156    // BROADCASTS
13157    // =========================================================
13158
13159    private final List getStickiesLocked(String action, IntentFilter filter,
13160            List cur, int userId) {
13161        final ContentResolver resolver = mContext.getContentResolver();
13162        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13163        if (stickies == null) {
13164            return cur;
13165        }
13166        final ArrayList<Intent> list = stickies.get(action);
13167        if (list == null) {
13168            return cur;
13169        }
13170        int N = list.size();
13171        for (int i=0; i<N; i++) {
13172            Intent intent = list.get(i);
13173            if (filter.match(resolver, intent, true, TAG) >= 0) {
13174                if (cur == null) {
13175                    cur = new ArrayList<Intent>();
13176                }
13177                cur.add(intent);
13178            }
13179        }
13180        return cur;
13181    }
13182
13183    boolean isPendingBroadcastProcessLocked(int pid) {
13184        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13185                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13186    }
13187
13188    void skipPendingBroadcastLocked(int pid) {
13189            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13190            for (BroadcastQueue queue : mBroadcastQueues) {
13191                queue.skipPendingBroadcastLocked(pid);
13192            }
13193    }
13194
13195    // The app just attached; send any pending broadcasts that it should receive
13196    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13197        boolean didSomething = false;
13198        for (BroadcastQueue queue : mBroadcastQueues) {
13199            didSomething |= queue.sendPendingBroadcastsLocked(app);
13200        }
13201        return didSomething;
13202    }
13203
13204    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13205            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13206        enforceNotIsolatedCaller("registerReceiver");
13207        int callingUid;
13208        int callingPid;
13209        synchronized(this) {
13210            ProcessRecord callerApp = null;
13211            if (caller != null) {
13212                callerApp = getRecordForAppLocked(caller);
13213                if (callerApp == null) {
13214                    throw new SecurityException(
13215                            "Unable to find app for caller " + caller
13216                            + " (pid=" + Binder.getCallingPid()
13217                            + ") when registering receiver " + receiver);
13218                }
13219                if (callerApp.info.uid != Process.SYSTEM_UID &&
13220                        !callerApp.pkgList.containsKey(callerPackage) &&
13221                        !"android".equals(callerPackage)) {
13222                    throw new SecurityException("Given caller package " + callerPackage
13223                            + " is not running in process " + callerApp);
13224                }
13225                callingUid = callerApp.info.uid;
13226                callingPid = callerApp.pid;
13227            } else {
13228                callerPackage = null;
13229                callingUid = Binder.getCallingUid();
13230                callingPid = Binder.getCallingPid();
13231            }
13232
13233            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13234                    true, true, "registerReceiver", callerPackage);
13235
13236            List allSticky = null;
13237
13238            // Look for any matching sticky broadcasts...
13239            Iterator actions = filter.actionsIterator();
13240            if (actions != null) {
13241                while (actions.hasNext()) {
13242                    String action = (String)actions.next();
13243                    allSticky = getStickiesLocked(action, filter, allSticky,
13244                            UserHandle.USER_ALL);
13245                    allSticky = getStickiesLocked(action, filter, allSticky,
13246                            UserHandle.getUserId(callingUid));
13247                }
13248            } else {
13249                allSticky = getStickiesLocked(null, filter, allSticky,
13250                        UserHandle.USER_ALL);
13251                allSticky = getStickiesLocked(null, filter, allSticky,
13252                        UserHandle.getUserId(callingUid));
13253            }
13254
13255            // The first sticky in the list is returned directly back to
13256            // the client.
13257            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13258
13259            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13260                    + ": " + sticky);
13261
13262            if (receiver == null) {
13263                return sticky;
13264            }
13265
13266            ReceiverList rl
13267                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13268            if (rl == null) {
13269                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13270                        userId, receiver);
13271                if (rl.app != null) {
13272                    rl.app.receivers.add(rl);
13273                } else {
13274                    try {
13275                        receiver.asBinder().linkToDeath(rl, 0);
13276                    } catch (RemoteException e) {
13277                        return sticky;
13278                    }
13279                    rl.linkedToDeath = true;
13280                }
13281                mRegisteredReceivers.put(receiver.asBinder(), rl);
13282            } else if (rl.uid != callingUid) {
13283                throw new IllegalArgumentException(
13284                        "Receiver requested to register for uid " + callingUid
13285                        + " was previously registered for uid " + rl.uid);
13286            } else if (rl.pid != callingPid) {
13287                throw new IllegalArgumentException(
13288                        "Receiver requested to register for pid " + callingPid
13289                        + " was previously registered for pid " + rl.pid);
13290            } else if (rl.userId != userId) {
13291                throw new IllegalArgumentException(
13292                        "Receiver requested to register for user " + userId
13293                        + " was previously registered for user " + rl.userId);
13294            }
13295            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13296                    permission, callingUid, userId);
13297            rl.add(bf);
13298            if (!bf.debugCheck()) {
13299                Slog.w(TAG, "==> For Dynamic broadast");
13300            }
13301            mReceiverResolver.addFilter(bf);
13302
13303            // Enqueue broadcasts for all existing stickies that match
13304            // this filter.
13305            if (allSticky != null) {
13306                ArrayList receivers = new ArrayList();
13307                receivers.add(bf);
13308
13309                int N = allSticky.size();
13310                for (int i=0; i<N; i++) {
13311                    Intent intent = (Intent)allSticky.get(i);
13312                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13313                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13314                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13315                            null, null, false, true, true, -1);
13316                    queue.enqueueParallelBroadcastLocked(r);
13317                    queue.scheduleBroadcastsLocked();
13318                }
13319            }
13320
13321            return sticky;
13322        }
13323    }
13324
13325    public void unregisterReceiver(IIntentReceiver receiver) {
13326        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13327
13328        final long origId = Binder.clearCallingIdentity();
13329        try {
13330            boolean doTrim = false;
13331
13332            synchronized(this) {
13333                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13334                if (rl != null) {
13335                    if (rl.curBroadcast != null) {
13336                        BroadcastRecord r = rl.curBroadcast;
13337                        final boolean doNext = finishReceiverLocked(
13338                                receiver.asBinder(), r.resultCode, r.resultData,
13339                                r.resultExtras, r.resultAbort);
13340                        if (doNext) {
13341                            doTrim = true;
13342                            r.queue.processNextBroadcast(false);
13343                        }
13344                    }
13345
13346                    if (rl.app != null) {
13347                        rl.app.receivers.remove(rl);
13348                    }
13349                    removeReceiverLocked(rl);
13350                    if (rl.linkedToDeath) {
13351                        rl.linkedToDeath = false;
13352                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13353                    }
13354                }
13355            }
13356
13357            // If we actually concluded any broadcasts, we might now be able
13358            // to trim the recipients' apps from our working set
13359            if (doTrim) {
13360                trimApplications();
13361                return;
13362            }
13363
13364        } finally {
13365            Binder.restoreCallingIdentity(origId);
13366        }
13367    }
13368
13369    void removeReceiverLocked(ReceiverList rl) {
13370        mRegisteredReceivers.remove(rl.receiver.asBinder());
13371        int N = rl.size();
13372        for (int i=0; i<N; i++) {
13373            mReceiverResolver.removeFilter(rl.get(i));
13374        }
13375    }
13376
13377    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13378        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13379            ProcessRecord r = mLruProcesses.get(i);
13380            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13381                try {
13382                    r.thread.dispatchPackageBroadcast(cmd, packages);
13383                } catch (RemoteException ex) {
13384                }
13385            }
13386        }
13387    }
13388
13389    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13390            int[] users) {
13391        List<ResolveInfo> receivers = null;
13392        try {
13393            HashSet<ComponentName> singleUserReceivers = null;
13394            boolean scannedFirstReceivers = false;
13395            for (int user : users) {
13396                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13397                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13398                if (user != 0 && newReceivers != null) {
13399                    // If this is not the primary user, we need to check for
13400                    // any receivers that should be filtered out.
13401                    for (int i=0; i<newReceivers.size(); i++) {
13402                        ResolveInfo ri = newReceivers.get(i);
13403                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13404                            newReceivers.remove(i);
13405                            i--;
13406                        }
13407                    }
13408                }
13409                if (newReceivers != null && newReceivers.size() == 0) {
13410                    newReceivers = null;
13411                }
13412                if (receivers == null) {
13413                    receivers = newReceivers;
13414                } else if (newReceivers != null) {
13415                    // We need to concatenate the additional receivers
13416                    // found with what we have do far.  This would be easy,
13417                    // but we also need to de-dup any receivers that are
13418                    // singleUser.
13419                    if (!scannedFirstReceivers) {
13420                        // Collect any single user receivers we had already retrieved.
13421                        scannedFirstReceivers = true;
13422                        for (int i=0; i<receivers.size(); i++) {
13423                            ResolveInfo ri = receivers.get(i);
13424                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13425                                ComponentName cn = new ComponentName(
13426                                        ri.activityInfo.packageName, ri.activityInfo.name);
13427                                if (singleUserReceivers == null) {
13428                                    singleUserReceivers = new HashSet<ComponentName>();
13429                                }
13430                                singleUserReceivers.add(cn);
13431                            }
13432                        }
13433                    }
13434                    // Add the new results to the existing results, tracking
13435                    // and de-dupping single user receivers.
13436                    for (int i=0; i<newReceivers.size(); i++) {
13437                        ResolveInfo ri = newReceivers.get(i);
13438                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13439                            ComponentName cn = new ComponentName(
13440                                    ri.activityInfo.packageName, ri.activityInfo.name);
13441                            if (singleUserReceivers == null) {
13442                                singleUserReceivers = new HashSet<ComponentName>();
13443                            }
13444                            if (!singleUserReceivers.contains(cn)) {
13445                                singleUserReceivers.add(cn);
13446                                receivers.add(ri);
13447                            }
13448                        } else {
13449                            receivers.add(ri);
13450                        }
13451                    }
13452                }
13453            }
13454        } catch (RemoteException ex) {
13455            // pm is in same process, this will never happen.
13456        }
13457        return receivers;
13458    }
13459
13460    private final int broadcastIntentLocked(ProcessRecord callerApp,
13461            String callerPackage, Intent intent, String resolvedType,
13462            IIntentReceiver resultTo, int resultCode, String resultData,
13463            Bundle map, String requiredPermission, int appOp,
13464            boolean ordered, boolean sticky, int callingPid, int callingUid,
13465            int userId) {
13466        intent = new Intent(intent);
13467
13468        // By default broadcasts do not go to stopped apps.
13469        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13470
13471        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13472            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13473            + " ordered=" + ordered + " userid=" + userId);
13474        if ((resultTo != null) && !ordered) {
13475            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13476        }
13477
13478        userId = handleIncomingUser(callingPid, callingUid, userId,
13479                true, false, "broadcast", callerPackage);
13480
13481        // Make sure that the user who is receiving this broadcast is started.
13482        // If not, we will just skip it.
13483        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13484            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13485                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13486                Slog.w(TAG, "Skipping broadcast of " + intent
13487                        + ": user " + userId + " is stopped");
13488                return ActivityManager.BROADCAST_SUCCESS;
13489            }
13490        }
13491
13492        /*
13493         * Prevent non-system code (defined here to be non-persistent
13494         * processes) from sending protected broadcasts.
13495         */
13496        int callingAppId = UserHandle.getAppId(callingUid);
13497        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13498            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13499            callingUid == 0) {
13500            // Always okay.
13501        } else if (callerApp == null || !callerApp.persistent) {
13502            try {
13503                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13504                        intent.getAction())) {
13505                    String msg = "Permission Denial: not allowed to send broadcast "
13506                            + intent.getAction() + " from pid="
13507                            + callingPid + ", uid=" + callingUid;
13508                    Slog.w(TAG, msg);
13509                    throw new SecurityException(msg);
13510                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13511                    // Special case for compatibility: we don't want apps to send this,
13512                    // but historically it has not been protected and apps may be using it
13513                    // to poke their own app widget.  So, instead of making it protected,
13514                    // just limit it to the caller.
13515                    if (callerApp == null) {
13516                        String msg = "Permission Denial: not allowed to send broadcast "
13517                                + intent.getAction() + " from unknown caller.";
13518                        Slog.w(TAG, msg);
13519                        throw new SecurityException(msg);
13520                    } else if (intent.getComponent() != null) {
13521                        // They are good enough to send to an explicit component...  verify
13522                        // it is being sent to the calling app.
13523                        if (!intent.getComponent().getPackageName().equals(
13524                                callerApp.info.packageName)) {
13525                            String msg = "Permission Denial: not allowed to send broadcast "
13526                                    + intent.getAction() + " to "
13527                                    + intent.getComponent().getPackageName() + " from "
13528                                    + callerApp.info.packageName;
13529                            Slog.w(TAG, msg);
13530                            throw new SecurityException(msg);
13531                        }
13532                    } else {
13533                        // Limit broadcast to their own package.
13534                        intent.setPackage(callerApp.info.packageName);
13535                    }
13536                }
13537            } catch (RemoteException e) {
13538                Slog.w(TAG, "Remote exception", e);
13539                return ActivityManager.BROADCAST_SUCCESS;
13540            }
13541        }
13542
13543        // Handle special intents: if this broadcast is from the package
13544        // manager about a package being removed, we need to remove all of
13545        // its activities from the history stack.
13546        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13547                intent.getAction());
13548        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13549                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13550                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13551                || uidRemoved) {
13552            if (checkComponentPermission(
13553                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13554                    callingPid, callingUid, -1, true)
13555                    == PackageManager.PERMISSION_GRANTED) {
13556                if (uidRemoved) {
13557                    final Bundle intentExtras = intent.getExtras();
13558                    final int uid = intentExtras != null
13559                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13560                    if (uid >= 0) {
13561                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13562                        synchronized (bs) {
13563                            bs.removeUidStatsLocked(uid);
13564                        }
13565                        mAppOpsService.uidRemoved(uid);
13566                    }
13567                } else {
13568                    // If resources are unavailable just force stop all
13569                    // those packages and flush the attribute cache as well.
13570                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13571                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13572                        if (list != null && (list.length > 0)) {
13573                            for (String pkg : list) {
13574                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13575                                        "storage unmount");
13576                            }
13577                            sendPackageBroadcastLocked(
13578                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13579                        }
13580                    } else {
13581                        Uri data = intent.getData();
13582                        String ssp;
13583                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13584                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13585                                    intent.getAction());
13586                            boolean fullUninstall = removed &&
13587                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13588                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13589                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13590                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13591                                        false, fullUninstall, userId,
13592                                        removed ? "pkg removed" : "pkg changed");
13593                            }
13594                            if (removed) {
13595                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13596                                        new String[] {ssp}, userId);
13597                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13598                                    mAppOpsService.packageRemoved(
13599                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13600
13601                                    // Remove all permissions granted from/to this package
13602                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13603                                }
13604                            }
13605                        }
13606                    }
13607                }
13608            } else {
13609                String msg = "Permission Denial: " + intent.getAction()
13610                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13611                        + ", uid=" + callingUid + ")"
13612                        + " requires "
13613                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13614                Slog.w(TAG, msg);
13615                throw new SecurityException(msg);
13616            }
13617
13618        // Special case for adding a package: by default turn on compatibility
13619        // mode.
13620        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13621            Uri data = intent.getData();
13622            String ssp;
13623            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13624                mCompatModePackages.handlePackageAddedLocked(ssp,
13625                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13626            }
13627        }
13628
13629        /*
13630         * If this is the time zone changed action, queue up a message that will reset the timezone
13631         * of all currently running processes. This message will get queued up before the broadcast
13632         * happens.
13633         */
13634        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13635            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13636        }
13637
13638        /*
13639         * If the user set the time, let all running processes know.
13640         */
13641        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
13642            final int is24Hour = intent.getBooleanExtra(
13643                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
13644            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
13645        }
13646
13647        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13648            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13649        }
13650
13651        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13652            ProxyProperties proxy = intent.getParcelableExtra("proxy");
13653            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13654        }
13655
13656        // Add to the sticky list if requested.
13657        if (sticky) {
13658            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13659                    callingPid, callingUid)
13660                    != PackageManager.PERMISSION_GRANTED) {
13661                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13662                        + callingPid + ", uid=" + callingUid
13663                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13664                Slog.w(TAG, msg);
13665                throw new SecurityException(msg);
13666            }
13667            if (requiredPermission != null) {
13668                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13669                        + " and enforce permission " + requiredPermission);
13670                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13671            }
13672            if (intent.getComponent() != null) {
13673                throw new SecurityException(
13674                        "Sticky broadcasts can't target a specific component");
13675            }
13676            // We use userId directly here, since the "all" target is maintained
13677            // as a separate set of sticky broadcasts.
13678            if (userId != UserHandle.USER_ALL) {
13679                // But first, if this is not a broadcast to all users, then
13680                // make sure it doesn't conflict with an existing broadcast to
13681                // all users.
13682                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13683                        UserHandle.USER_ALL);
13684                if (stickies != null) {
13685                    ArrayList<Intent> list = stickies.get(intent.getAction());
13686                    if (list != null) {
13687                        int N = list.size();
13688                        int i;
13689                        for (i=0; i<N; i++) {
13690                            if (intent.filterEquals(list.get(i))) {
13691                                throw new IllegalArgumentException(
13692                                        "Sticky broadcast " + intent + " for user "
13693                                        + userId + " conflicts with existing global broadcast");
13694                            }
13695                        }
13696                    }
13697                }
13698            }
13699            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13700            if (stickies == null) {
13701                stickies = new ArrayMap<String, ArrayList<Intent>>();
13702                mStickyBroadcasts.put(userId, stickies);
13703            }
13704            ArrayList<Intent> list = stickies.get(intent.getAction());
13705            if (list == null) {
13706                list = new ArrayList<Intent>();
13707                stickies.put(intent.getAction(), list);
13708            }
13709            int N = list.size();
13710            int i;
13711            for (i=0; i<N; i++) {
13712                if (intent.filterEquals(list.get(i))) {
13713                    // This sticky already exists, replace it.
13714                    list.set(i, new Intent(intent));
13715                    break;
13716                }
13717            }
13718            if (i >= N) {
13719                list.add(new Intent(intent));
13720            }
13721        }
13722
13723        int[] users;
13724        if (userId == UserHandle.USER_ALL) {
13725            // Caller wants broadcast to go to all started users.
13726            users = mStartedUserArray;
13727        } else {
13728            // Caller wants broadcast to go to one specific user.
13729            users = new int[] {userId};
13730        }
13731
13732        // Figure out who all will receive this broadcast.
13733        List receivers = null;
13734        List<BroadcastFilter> registeredReceivers = null;
13735        // Need to resolve the intent to interested receivers...
13736        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13737                 == 0) {
13738            receivers = collectReceiverComponents(intent, resolvedType, users);
13739        }
13740        if (intent.getComponent() == null) {
13741            registeredReceivers = mReceiverResolver.queryIntent(intent,
13742                    resolvedType, false, userId);
13743        }
13744
13745        final boolean replacePending =
13746                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13747
13748        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13749                + " replacePending=" + replacePending);
13750
13751        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13752        if (!ordered && NR > 0) {
13753            // If we are not serializing this broadcast, then send the
13754            // registered receivers separately so they don't wait for the
13755            // components to be launched.
13756            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13757            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13758                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13759                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13760                    ordered, sticky, false, userId);
13761            if (DEBUG_BROADCAST) Slog.v(
13762                    TAG, "Enqueueing parallel broadcast " + r);
13763            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13764            if (!replaced) {
13765                queue.enqueueParallelBroadcastLocked(r);
13766                queue.scheduleBroadcastsLocked();
13767            }
13768            registeredReceivers = null;
13769            NR = 0;
13770        }
13771
13772        // Merge into one list.
13773        int ir = 0;
13774        if (receivers != null) {
13775            // A special case for PACKAGE_ADDED: do not allow the package
13776            // being added to see this broadcast.  This prevents them from
13777            // using this as a back door to get run as soon as they are
13778            // installed.  Maybe in the future we want to have a special install
13779            // broadcast or such for apps, but we'd like to deliberately make
13780            // this decision.
13781            String skipPackages[] = null;
13782            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13783                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13784                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13785                Uri data = intent.getData();
13786                if (data != null) {
13787                    String pkgName = data.getSchemeSpecificPart();
13788                    if (pkgName != null) {
13789                        skipPackages = new String[] { pkgName };
13790                    }
13791                }
13792            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13793                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13794            }
13795            if (skipPackages != null && (skipPackages.length > 0)) {
13796                for (String skipPackage : skipPackages) {
13797                    if (skipPackage != null) {
13798                        int NT = receivers.size();
13799                        for (int it=0; it<NT; it++) {
13800                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
13801                            if (curt.activityInfo.packageName.equals(skipPackage)) {
13802                                receivers.remove(it);
13803                                it--;
13804                                NT--;
13805                            }
13806                        }
13807                    }
13808                }
13809            }
13810
13811            int NT = receivers != null ? receivers.size() : 0;
13812            int it = 0;
13813            ResolveInfo curt = null;
13814            BroadcastFilter curr = null;
13815            while (it < NT && ir < NR) {
13816                if (curt == null) {
13817                    curt = (ResolveInfo)receivers.get(it);
13818                }
13819                if (curr == null) {
13820                    curr = registeredReceivers.get(ir);
13821                }
13822                if (curr.getPriority() >= curt.priority) {
13823                    // Insert this broadcast record into the final list.
13824                    receivers.add(it, curr);
13825                    ir++;
13826                    curr = null;
13827                    it++;
13828                    NT++;
13829                } else {
13830                    // Skip to the next ResolveInfo in the final list.
13831                    it++;
13832                    curt = null;
13833                }
13834            }
13835        }
13836        while (ir < NR) {
13837            if (receivers == null) {
13838                receivers = new ArrayList();
13839            }
13840            receivers.add(registeredReceivers.get(ir));
13841            ir++;
13842        }
13843
13844        if ((receivers != null && receivers.size() > 0)
13845                || resultTo != null) {
13846            BroadcastQueue queue = broadcastQueueForIntent(intent);
13847            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13848                    callerPackage, callingPid, callingUid, resolvedType,
13849                    requiredPermission, appOp, receivers, resultTo, resultCode,
13850                    resultData, map, ordered, sticky, false, userId);
13851            if (DEBUG_BROADCAST) Slog.v(
13852                    TAG, "Enqueueing ordered broadcast " + r
13853                    + ": prev had " + queue.mOrderedBroadcasts.size());
13854            if (DEBUG_BROADCAST) {
13855                int seq = r.intent.getIntExtra("seq", -1);
13856                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
13857            }
13858            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
13859            if (!replaced) {
13860                queue.enqueueOrderedBroadcastLocked(r);
13861                queue.scheduleBroadcastsLocked();
13862            }
13863        }
13864
13865        return ActivityManager.BROADCAST_SUCCESS;
13866    }
13867
13868    final Intent verifyBroadcastLocked(Intent intent) {
13869        // Refuse possible leaked file descriptors
13870        if (intent != null && intent.hasFileDescriptors() == true) {
13871            throw new IllegalArgumentException("File descriptors passed in Intent");
13872        }
13873
13874        int flags = intent.getFlags();
13875
13876        if (!mProcessesReady) {
13877            // if the caller really truly claims to know what they're doing, go
13878            // ahead and allow the broadcast without launching any receivers
13879            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
13880                intent = new Intent(intent);
13881                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13882            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
13883                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
13884                        + " before boot completion");
13885                throw new IllegalStateException("Cannot broadcast before boot completed");
13886            }
13887        }
13888
13889        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
13890            throw new IllegalArgumentException(
13891                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
13892        }
13893
13894        return intent;
13895    }
13896
13897    public final int broadcastIntent(IApplicationThread caller,
13898            Intent intent, String resolvedType, IIntentReceiver resultTo,
13899            int resultCode, String resultData, Bundle map,
13900            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
13901        enforceNotIsolatedCaller("broadcastIntent");
13902        synchronized(this) {
13903            intent = verifyBroadcastLocked(intent);
13904
13905            final ProcessRecord callerApp = getRecordForAppLocked(caller);
13906            final int callingPid = Binder.getCallingPid();
13907            final int callingUid = Binder.getCallingUid();
13908            final long origId = Binder.clearCallingIdentity();
13909            int res = broadcastIntentLocked(callerApp,
13910                    callerApp != null ? callerApp.info.packageName : null,
13911                    intent, resolvedType, resultTo,
13912                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
13913                    callingPid, callingUid, userId);
13914            Binder.restoreCallingIdentity(origId);
13915            return res;
13916        }
13917    }
13918
13919    int broadcastIntentInPackage(String packageName, int uid,
13920            Intent intent, String resolvedType, IIntentReceiver resultTo,
13921            int resultCode, String resultData, Bundle map,
13922            String requiredPermission, boolean serialized, boolean sticky, int userId) {
13923        synchronized(this) {
13924            intent = verifyBroadcastLocked(intent);
13925
13926            final long origId = Binder.clearCallingIdentity();
13927            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
13928                    resultTo, resultCode, resultData, map, requiredPermission,
13929                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
13930            Binder.restoreCallingIdentity(origId);
13931            return res;
13932        }
13933    }
13934
13935    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
13936        // Refuse possible leaked file descriptors
13937        if (intent != null && intent.hasFileDescriptors() == true) {
13938            throw new IllegalArgumentException("File descriptors passed in Intent");
13939        }
13940
13941        userId = handleIncomingUser(Binder.getCallingPid(),
13942                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
13943
13944        synchronized(this) {
13945            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
13946                    != PackageManager.PERMISSION_GRANTED) {
13947                String msg = "Permission Denial: unbroadcastIntent() from pid="
13948                        + Binder.getCallingPid()
13949                        + ", uid=" + Binder.getCallingUid()
13950                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13951                Slog.w(TAG, msg);
13952                throw new SecurityException(msg);
13953            }
13954            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13955            if (stickies != null) {
13956                ArrayList<Intent> list = stickies.get(intent.getAction());
13957                if (list != null) {
13958                    int N = list.size();
13959                    int i;
13960                    for (i=0; i<N; i++) {
13961                        if (intent.filterEquals(list.get(i))) {
13962                            list.remove(i);
13963                            break;
13964                        }
13965                    }
13966                    if (list.size() <= 0) {
13967                        stickies.remove(intent.getAction());
13968                    }
13969                }
13970                if (stickies.size() <= 0) {
13971                    mStickyBroadcasts.remove(userId);
13972                }
13973            }
13974        }
13975    }
13976
13977    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
13978            String resultData, Bundle resultExtras, boolean resultAbort) {
13979        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
13980        if (r == null) {
13981            Slog.w(TAG, "finishReceiver called but not found on queue");
13982            return false;
13983        }
13984
13985        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
13986    }
13987
13988    void backgroundServicesFinishedLocked(int userId) {
13989        for (BroadcastQueue queue : mBroadcastQueues) {
13990            queue.backgroundServicesFinishedLocked(userId);
13991        }
13992    }
13993
13994    public void finishReceiver(IBinder who, int resultCode, String resultData,
13995            Bundle resultExtras, boolean resultAbort) {
13996        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
13997
13998        // Refuse possible leaked file descriptors
13999        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14000            throw new IllegalArgumentException("File descriptors passed in Bundle");
14001        }
14002
14003        final long origId = Binder.clearCallingIdentity();
14004        try {
14005            boolean doNext = false;
14006            BroadcastRecord r;
14007
14008            synchronized(this) {
14009                r = broadcastRecordForReceiverLocked(who);
14010                if (r != null) {
14011                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14012                        resultData, resultExtras, resultAbort, true);
14013                }
14014            }
14015
14016            if (doNext) {
14017                r.queue.processNextBroadcast(false);
14018            }
14019            trimApplications();
14020        } finally {
14021            Binder.restoreCallingIdentity(origId);
14022        }
14023    }
14024
14025    // =========================================================
14026    // INSTRUMENTATION
14027    // =========================================================
14028
14029    public boolean startInstrumentation(ComponentName className,
14030            String profileFile, int flags, Bundle arguments,
14031            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14032            int userId) {
14033        enforceNotIsolatedCaller("startInstrumentation");
14034        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14035                userId, false, true, "startInstrumentation", null);
14036        // Refuse possible leaked file descriptors
14037        if (arguments != null && arguments.hasFileDescriptors()) {
14038            throw new IllegalArgumentException("File descriptors passed in Bundle");
14039        }
14040
14041        synchronized(this) {
14042            InstrumentationInfo ii = null;
14043            ApplicationInfo ai = null;
14044            try {
14045                ii = mContext.getPackageManager().getInstrumentationInfo(
14046                    className, STOCK_PM_FLAGS);
14047                ai = AppGlobals.getPackageManager().getApplicationInfo(
14048                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14049            } catch (PackageManager.NameNotFoundException e) {
14050            } catch (RemoteException e) {
14051            }
14052            if (ii == null) {
14053                reportStartInstrumentationFailure(watcher, className,
14054                        "Unable to find instrumentation info for: " + className);
14055                return false;
14056            }
14057            if (ai == null) {
14058                reportStartInstrumentationFailure(watcher, className,
14059                        "Unable to find instrumentation target package: " + ii.targetPackage);
14060                return false;
14061            }
14062
14063            int match = mContext.getPackageManager().checkSignatures(
14064                    ii.targetPackage, ii.packageName);
14065            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14066                String msg = "Permission Denial: starting instrumentation "
14067                        + className + " from pid="
14068                        + Binder.getCallingPid()
14069                        + ", uid=" + Binder.getCallingPid()
14070                        + " not allowed because package " + ii.packageName
14071                        + " does not have a signature matching the target "
14072                        + ii.targetPackage;
14073                reportStartInstrumentationFailure(watcher, className, msg);
14074                throw new SecurityException(msg);
14075            }
14076
14077            final long origId = Binder.clearCallingIdentity();
14078            // Instrumentation can kill and relaunch even persistent processes
14079            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14080                    "start instr");
14081            ProcessRecord app = addAppLocked(ai, false);
14082            app.instrumentationClass = className;
14083            app.instrumentationInfo = ai;
14084            app.instrumentationProfileFile = profileFile;
14085            app.instrumentationArguments = arguments;
14086            app.instrumentationWatcher = watcher;
14087            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14088            app.instrumentationResultClass = className;
14089            Binder.restoreCallingIdentity(origId);
14090        }
14091
14092        return true;
14093    }
14094
14095    /**
14096     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14097     * error to the logs, but if somebody is watching, send the report there too.  This enables
14098     * the "am" command to report errors with more information.
14099     *
14100     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14101     * @param cn The component name of the instrumentation.
14102     * @param report The error report.
14103     */
14104    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14105            ComponentName cn, String report) {
14106        Slog.w(TAG, report);
14107        try {
14108            if (watcher != null) {
14109                Bundle results = new Bundle();
14110                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14111                results.putString("Error", report);
14112                watcher.instrumentationStatus(cn, -1, results);
14113            }
14114        } catch (RemoteException e) {
14115            Slog.w(TAG, e);
14116        }
14117    }
14118
14119    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14120        if (app.instrumentationWatcher != null) {
14121            try {
14122                // NOTE:  IInstrumentationWatcher *must* be oneway here
14123                app.instrumentationWatcher.instrumentationFinished(
14124                    app.instrumentationClass,
14125                    resultCode,
14126                    results);
14127            } catch (RemoteException e) {
14128            }
14129        }
14130        if (app.instrumentationUiAutomationConnection != null) {
14131            try {
14132                app.instrumentationUiAutomationConnection.shutdown();
14133            } catch (RemoteException re) {
14134                /* ignore */
14135            }
14136            // Only a UiAutomation can set this flag and now that
14137            // it is finished we make sure it is reset to its default.
14138            mUserIsMonkey = false;
14139        }
14140        app.instrumentationWatcher = null;
14141        app.instrumentationUiAutomationConnection = null;
14142        app.instrumentationClass = null;
14143        app.instrumentationInfo = null;
14144        app.instrumentationProfileFile = null;
14145        app.instrumentationArguments = null;
14146
14147        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14148                "finished inst");
14149    }
14150
14151    public void finishInstrumentation(IApplicationThread target,
14152            int resultCode, Bundle results) {
14153        int userId = UserHandle.getCallingUserId();
14154        // Refuse possible leaked file descriptors
14155        if (results != null && results.hasFileDescriptors()) {
14156            throw new IllegalArgumentException("File descriptors passed in Intent");
14157        }
14158
14159        synchronized(this) {
14160            ProcessRecord app = getRecordForAppLocked(target);
14161            if (app == null) {
14162                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14163                return;
14164            }
14165            final long origId = Binder.clearCallingIdentity();
14166            finishInstrumentationLocked(app, resultCode, results);
14167            Binder.restoreCallingIdentity(origId);
14168        }
14169    }
14170
14171    // =========================================================
14172    // CONFIGURATION
14173    // =========================================================
14174
14175    public ConfigurationInfo getDeviceConfigurationInfo() {
14176        ConfigurationInfo config = new ConfigurationInfo();
14177        synchronized (this) {
14178            config.reqTouchScreen = mConfiguration.touchscreen;
14179            config.reqKeyboardType = mConfiguration.keyboard;
14180            config.reqNavigation = mConfiguration.navigation;
14181            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14182                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14183                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14184            }
14185            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14186                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14187                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14188            }
14189            config.reqGlEsVersion = GL_ES_VERSION;
14190        }
14191        return config;
14192    }
14193
14194    ActivityStack getFocusedStack() {
14195        return mStackSupervisor.getFocusedStack();
14196    }
14197
14198    public Configuration getConfiguration() {
14199        Configuration ci;
14200        synchronized(this) {
14201            ci = new Configuration(mConfiguration);
14202        }
14203        return ci;
14204    }
14205
14206    public void updatePersistentConfiguration(Configuration values) {
14207        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14208                "updateConfiguration()");
14209        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14210                "updateConfiguration()");
14211        if (values == null) {
14212            throw new NullPointerException("Configuration must not be null");
14213        }
14214
14215        synchronized(this) {
14216            final long origId = Binder.clearCallingIdentity();
14217            updateConfigurationLocked(values, null, true, false);
14218            Binder.restoreCallingIdentity(origId);
14219        }
14220    }
14221
14222    public void updateConfiguration(Configuration values) {
14223        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14224                "updateConfiguration()");
14225
14226        synchronized(this) {
14227            if (values == null && mWindowManager != null) {
14228                // sentinel: fetch the current configuration from the window manager
14229                values = mWindowManager.computeNewConfiguration();
14230            }
14231
14232            if (mWindowManager != null) {
14233                mProcessList.applyDisplaySize(mWindowManager);
14234            }
14235
14236            final long origId = Binder.clearCallingIdentity();
14237            if (values != null) {
14238                Settings.System.clearConfiguration(values);
14239            }
14240            updateConfigurationLocked(values, null, false, false);
14241            Binder.restoreCallingIdentity(origId);
14242        }
14243    }
14244
14245    /**
14246     * Do either or both things: (1) change the current configuration, and (2)
14247     * make sure the given activity is running with the (now) current
14248     * configuration.  Returns true if the activity has been left running, or
14249     * false if <var>starting</var> is being destroyed to match the new
14250     * configuration.
14251     * @param persistent TODO
14252     */
14253    boolean updateConfigurationLocked(Configuration values,
14254            ActivityRecord starting, boolean persistent, boolean initLocale) {
14255        int changes = 0;
14256
14257        if (values != null) {
14258            Configuration newConfig = new Configuration(mConfiguration);
14259            changes = newConfig.updateFrom(values);
14260            if (changes != 0) {
14261                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14262                    Slog.i(TAG, "Updating configuration to: " + values);
14263                }
14264
14265                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14266
14267                if (values.locale != null && !initLocale) {
14268                    saveLocaleLocked(values.locale,
14269                                     !values.locale.equals(mConfiguration.locale),
14270                                     values.userSetLocale);
14271                }
14272
14273                mConfigurationSeq++;
14274                if (mConfigurationSeq <= 0) {
14275                    mConfigurationSeq = 1;
14276                }
14277                newConfig.seq = mConfigurationSeq;
14278                mConfiguration = newConfig;
14279                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14280
14281                final Configuration configCopy = new Configuration(mConfiguration);
14282
14283                // TODO: If our config changes, should we auto dismiss any currently
14284                // showing dialogs?
14285                mShowDialogs = shouldShowDialogs(newConfig);
14286
14287                AttributeCache ac = AttributeCache.instance();
14288                if (ac != null) {
14289                    ac.updateConfiguration(configCopy);
14290                }
14291
14292                // Make sure all resources in our process are updated
14293                // right now, so that anyone who is going to retrieve
14294                // resource values after we return will be sure to get
14295                // the new ones.  This is especially important during
14296                // boot, where the first config change needs to guarantee
14297                // all resources have that config before following boot
14298                // code is executed.
14299                mSystemThread.applyConfigurationToResources(configCopy);
14300
14301                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14302                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14303                    msg.obj = new Configuration(configCopy);
14304                    mHandler.sendMessage(msg);
14305                }
14306
14307                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14308                    ProcessRecord app = mLruProcesses.get(i);
14309                    try {
14310                        if (app.thread != null) {
14311                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14312                                    + app.processName + " new config " + mConfiguration);
14313                            app.thread.scheduleConfigurationChanged(configCopy);
14314                        }
14315                    } catch (Exception e) {
14316                    }
14317                }
14318                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14319                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14320                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14321                        | Intent.FLAG_RECEIVER_FOREGROUND);
14322                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14323                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14324                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14325                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14326                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14327                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14328                    broadcastIntentLocked(null, null, intent,
14329                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14330                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14331                }
14332            }
14333        }
14334
14335        boolean kept = true;
14336        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14337        // mainStack is null during startup.
14338        if (mainStack != null) {
14339            if (changes != 0 && starting == null) {
14340                // If the configuration changed, and the caller is not already
14341                // in the process of starting an activity, then find the top
14342                // activity to check if its configuration needs to change.
14343                starting = mainStack.topRunningActivityLocked(null);
14344            }
14345
14346            if (starting != null) {
14347                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14348                // And we need to make sure at this point that all other activities
14349                // are made visible with the correct configuration.
14350                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14351            }
14352        }
14353
14354        if (values != null && mWindowManager != null) {
14355            mWindowManager.setNewConfiguration(mConfiguration);
14356        }
14357
14358        return kept;
14359    }
14360
14361    /**
14362     * Decide based on the configuration whether we should shouw the ANR,
14363     * crash, etc dialogs.  The idea is that if there is no affordnace to
14364     * press the on-screen buttons, we shouldn't show the dialog.
14365     *
14366     * A thought: SystemUI might also want to get told about this, the Power
14367     * dialog / global actions also might want different behaviors.
14368     */
14369    private static final boolean shouldShowDialogs(Configuration config) {
14370        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14371                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14372    }
14373
14374    /**
14375     * Save the locale.  You must be inside a synchronized (this) block.
14376     */
14377    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14378        if(isDiff) {
14379            SystemProperties.set("user.language", l.getLanguage());
14380            SystemProperties.set("user.region", l.getCountry());
14381        }
14382
14383        if(isPersist) {
14384            SystemProperties.set("persist.sys.language", l.getLanguage());
14385            SystemProperties.set("persist.sys.country", l.getCountry());
14386            SystemProperties.set("persist.sys.localevar", l.getVariant());
14387        }
14388    }
14389
14390    @Override
14391    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14392        ActivityRecord srec = ActivityRecord.forToken(token);
14393        return srec != null && srec.task.affinity != null &&
14394                srec.task.affinity.equals(destAffinity);
14395    }
14396
14397    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14398            Intent resultData) {
14399
14400        synchronized (this) {
14401            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14402            if (stack != null) {
14403                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14404            }
14405            return false;
14406        }
14407    }
14408
14409    public int getLaunchedFromUid(IBinder activityToken) {
14410        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14411        if (srec == null) {
14412            return -1;
14413        }
14414        return srec.launchedFromUid;
14415    }
14416
14417    public String getLaunchedFromPackage(IBinder activityToken) {
14418        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14419        if (srec == null) {
14420            return null;
14421        }
14422        return srec.launchedFromPackage;
14423    }
14424
14425    // =========================================================
14426    // LIFETIME MANAGEMENT
14427    // =========================================================
14428
14429    // Returns which broadcast queue the app is the current [or imminent] receiver
14430    // on, or 'null' if the app is not an active broadcast recipient.
14431    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14432        BroadcastRecord r = app.curReceiver;
14433        if (r != null) {
14434            return r.queue;
14435        }
14436
14437        // It's not the current receiver, but it might be starting up to become one
14438        synchronized (this) {
14439            for (BroadcastQueue queue : mBroadcastQueues) {
14440                r = queue.mPendingBroadcast;
14441                if (r != null && r.curApp == app) {
14442                    // found it; report which queue it's in
14443                    return queue;
14444                }
14445            }
14446        }
14447
14448        return null;
14449    }
14450
14451    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14452            boolean doingAll, long now) {
14453        if (mAdjSeq == app.adjSeq) {
14454            // This adjustment has already been computed.
14455            return app.curRawAdj;
14456        }
14457
14458        if (app.thread == null) {
14459            app.adjSeq = mAdjSeq;
14460            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14461            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14462            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14463        }
14464
14465        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14466        app.adjSource = null;
14467        app.adjTarget = null;
14468        app.empty = false;
14469        app.cached = false;
14470
14471        final int activitiesSize = app.activities.size();
14472
14473        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14474            // The max adjustment doesn't allow this app to be anything
14475            // below foreground, so it is not worth doing work for it.
14476            app.adjType = "fixed";
14477            app.adjSeq = mAdjSeq;
14478            app.curRawAdj = app.maxAdj;
14479            app.foregroundActivities = false;
14480            app.keeping = true;
14481            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14482            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14483            // System process can do UI, and when they do we want to have
14484            // them trim their memory after the user leaves the UI.  To
14485            // facilitate this, here we need to determine whether or not it
14486            // is currently showing UI.
14487            app.systemNoUi = true;
14488            if (app == TOP_APP) {
14489                app.systemNoUi = false;
14490            } else if (activitiesSize > 0) {
14491                for (int j = 0; j < activitiesSize; j++) {
14492                    final ActivityRecord r = app.activities.get(j);
14493                    if (r.visible) {
14494                        app.systemNoUi = false;
14495                    }
14496                }
14497            }
14498            if (!app.systemNoUi) {
14499                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14500            }
14501            return (app.curAdj=app.maxAdj);
14502        }
14503
14504        app.keeping = false;
14505        app.systemNoUi = false;
14506
14507        // Determine the importance of the process, starting with most
14508        // important to least, and assign an appropriate OOM adjustment.
14509        int adj;
14510        int schedGroup;
14511        int procState;
14512        boolean foregroundActivities = false;
14513        boolean interesting = false;
14514        BroadcastQueue queue;
14515        if (app == TOP_APP) {
14516            // The last app on the list is the foreground app.
14517            adj = ProcessList.FOREGROUND_APP_ADJ;
14518            schedGroup = Process.THREAD_GROUP_DEFAULT;
14519            app.adjType = "top-activity";
14520            foregroundActivities = true;
14521            interesting = true;
14522            procState = ActivityManager.PROCESS_STATE_TOP;
14523        } else if (app.instrumentationClass != null) {
14524            // Don't want to kill running instrumentation.
14525            adj = ProcessList.FOREGROUND_APP_ADJ;
14526            schedGroup = Process.THREAD_GROUP_DEFAULT;
14527            app.adjType = "instrumentation";
14528            interesting = true;
14529            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14530        } else if ((queue = isReceivingBroadcast(app)) != null) {
14531            // An app that is currently receiving a broadcast also
14532            // counts as being in the foreground for OOM killer purposes.
14533            // It's placed in a sched group based on the nature of the
14534            // broadcast as reflected by which queue it's active in.
14535            adj = ProcessList.FOREGROUND_APP_ADJ;
14536            schedGroup = (queue == mFgBroadcastQueue)
14537                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14538            app.adjType = "broadcast";
14539            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14540        } else if (app.executingServices.size() > 0) {
14541            // An app that is currently executing a service callback also
14542            // counts as being in the foreground.
14543            adj = ProcessList.FOREGROUND_APP_ADJ;
14544            schedGroup = app.execServicesFg ?
14545                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14546            app.adjType = "exec-service";
14547            procState = ActivityManager.PROCESS_STATE_SERVICE;
14548            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14549        } else {
14550            // As far as we know the process is empty.  We may change our mind later.
14551            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14552            // At this point we don't actually know the adjustment.  Use the cached adj
14553            // value that the caller wants us to.
14554            adj = cachedAdj;
14555            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14556            app.cached = true;
14557            app.empty = true;
14558            app.adjType = "cch-empty";
14559        }
14560
14561        // Examine all activities if not already foreground.
14562        if (!foregroundActivities && activitiesSize > 0) {
14563            for (int j = 0; j < activitiesSize; j++) {
14564                final ActivityRecord r = app.activities.get(j);
14565                if (r.app != app) {
14566                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14567                            + app + "?!?");
14568                    continue;
14569                }
14570                if (r.visible) {
14571                    // App has a visible activity; only upgrade adjustment.
14572                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14573                        adj = ProcessList.VISIBLE_APP_ADJ;
14574                        app.adjType = "visible";
14575                    }
14576                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14577                        procState = ActivityManager.PROCESS_STATE_TOP;
14578                    }
14579                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14580                    app.cached = false;
14581                    app.empty = false;
14582                    foregroundActivities = true;
14583                    break;
14584                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14585                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14586                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14587                        app.adjType = "pausing";
14588                    }
14589                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14590                        procState = ActivityManager.PROCESS_STATE_TOP;
14591                    }
14592                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14593                    app.cached = false;
14594                    app.empty = false;
14595                    foregroundActivities = true;
14596                } else if (r.state == ActivityState.STOPPING) {
14597                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14598                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14599                        app.adjType = "stopping";
14600                    }
14601                    // For the process state, we will at this point consider the
14602                    // process to be cached.  It will be cached either as an activity
14603                    // or empty depending on whether the activity is finishing.  We do
14604                    // this so that we can treat the process as cached for purposes of
14605                    // memory trimming (determing current memory level, trim command to
14606                    // send to process) since there can be an arbitrary number of stopping
14607                    // processes and they should soon all go into the cached state.
14608                    if (!r.finishing) {
14609                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14610                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14611                        }
14612                    }
14613                    app.cached = false;
14614                    app.empty = false;
14615                    foregroundActivities = true;
14616                } else {
14617                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14618                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14619                        app.adjType = "cch-act";
14620                    }
14621                }
14622            }
14623        }
14624
14625        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14626            if (app.foregroundServices) {
14627                // The user is aware of this app, so make it visible.
14628                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14629                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14630                app.cached = false;
14631                app.adjType = "fg-service";
14632                schedGroup = Process.THREAD_GROUP_DEFAULT;
14633            } else if (app.forcingToForeground != null) {
14634                // The user is aware of this app, so make it visible.
14635                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14636                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14637                app.cached = false;
14638                app.adjType = "force-fg";
14639                app.adjSource = app.forcingToForeground;
14640                schedGroup = Process.THREAD_GROUP_DEFAULT;
14641            }
14642        }
14643
14644        if (app.foregroundServices) {
14645            interesting = true;
14646        }
14647
14648        if (app == mHeavyWeightProcess) {
14649            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14650                // We don't want to kill the current heavy-weight process.
14651                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14652                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14653                app.cached = false;
14654                app.adjType = "heavy";
14655            }
14656            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14657                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14658            }
14659        }
14660
14661        if (app == mHomeProcess) {
14662            if (adj > ProcessList.HOME_APP_ADJ) {
14663                // This process is hosting what we currently consider to be the
14664                // home app, so we don't want to let it go into the background.
14665                adj = ProcessList.HOME_APP_ADJ;
14666                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14667                app.cached = false;
14668                app.adjType = "home";
14669            }
14670            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14671                procState = ActivityManager.PROCESS_STATE_HOME;
14672            }
14673        }
14674
14675        if (app == mPreviousProcess && app.activities.size() > 0) {
14676            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14677                // This was the previous process that showed UI to the user.
14678                // We want to try to keep it around more aggressively, to give
14679                // a good experience around switching between two apps.
14680                adj = ProcessList.PREVIOUS_APP_ADJ;
14681                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14682                app.cached = false;
14683                app.adjType = "previous";
14684            }
14685            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14686                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14687            }
14688        }
14689
14690        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14691                + " reason=" + app.adjType);
14692
14693        // By default, we use the computed adjustment.  It may be changed if
14694        // there are applications dependent on our services or providers, but
14695        // this gives us a baseline and makes sure we don't get into an
14696        // infinite recursion.
14697        app.adjSeq = mAdjSeq;
14698        app.curRawAdj = adj;
14699        app.hasStartedServices = false;
14700
14701        if (mBackupTarget != null && app == mBackupTarget.app) {
14702            // If possible we want to avoid killing apps while they're being backed up
14703            if (adj > ProcessList.BACKUP_APP_ADJ) {
14704                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14705                adj = ProcessList.BACKUP_APP_ADJ;
14706                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14707                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14708                }
14709                app.adjType = "backup";
14710                app.cached = false;
14711            }
14712            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14713                procState = ActivityManager.PROCESS_STATE_BACKUP;
14714            }
14715        }
14716
14717        boolean mayBeTop = false;
14718
14719        for (int is = app.services.size()-1;
14720                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14721                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14722                        || procState > ActivityManager.PROCESS_STATE_TOP);
14723                is--) {
14724            ServiceRecord s = app.services.valueAt(is);
14725            if (s.startRequested) {
14726                app.hasStartedServices = true;
14727                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14728                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14729                }
14730                if (app.hasShownUi && app != mHomeProcess) {
14731                    // If this process has shown some UI, let it immediately
14732                    // go to the LRU list because it may be pretty heavy with
14733                    // UI stuff.  We'll tag it with a label just to help
14734                    // debug and understand what is going on.
14735                    if (adj > ProcessList.SERVICE_ADJ) {
14736                        app.adjType = "cch-started-ui-services";
14737                    }
14738                } else {
14739                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14740                        // This service has seen some activity within
14741                        // recent memory, so we will keep its process ahead
14742                        // of the background processes.
14743                        if (adj > ProcessList.SERVICE_ADJ) {
14744                            adj = ProcessList.SERVICE_ADJ;
14745                            app.adjType = "started-services";
14746                            app.cached = false;
14747                        }
14748                    }
14749                    // If we have let the service slide into the background
14750                    // state, still have some text describing what it is doing
14751                    // even though the service no longer has an impact.
14752                    if (adj > ProcessList.SERVICE_ADJ) {
14753                        app.adjType = "cch-started-services";
14754                    }
14755                }
14756                // Don't kill this process because it is doing work; it
14757                // has said it is doing work.
14758                app.keeping = true;
14759            }
14760            for (int conni = s.connections.size()-1;
14761                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14762                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14763                            || procState > ActivityManager.PROCESS_STATE_TOP);
14764                    conni--) {
14765                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14766                for (int i = 0;
14767                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14768                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14769                                || procState > ActivityManager.PROCESS_STATE_TOP);
14770                        i++) {
14771                    // XXX should compute this based on the max of
14772                    // all connected clients.
14773                    ConnectionRecord cr = clist.get(i);
14774                    if (cr.binding.client == app) {
14775                        // Binding to ourself is not interesting.
14776                        continue;
14777                    }
14778                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14779                        ProcessRecord client = cr.binding.client;
14780                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14781                                TOP_APP, doingAll, now);
14782                        int clientProcState = client.curProcState;
14783                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14784                            // If the other app is cached for any reason, for purposes here
14785                            // we are going to consider it empty.  The specific cached state
14786                            // doesn't propagate except under certain conditions.
14787                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14788                        }
14789                        String adjType = null;
14790                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14791                            // Not doing bind OOM management, so treat
14792                            // this guy more like a started service.
14793                            if (app.hasShownUi && app != mHomeProcess) {
14794                                // If this process has shown some UI, let it immediately
14795                                // go to the LRU list because it may be pretty heavy with
14796                                // UI stuff.  We'll tag it with a label just to help
14797                                // debug and understand what is going on.
14798                                if (adj > clientAdj) {
14799                                    adjType = "cch-bound-ui-services";
14800                                }
14801                                app.cached = false;
14802                                clientAdj = adj;
14803                                clientProcState = procState;
14804                            } else {
14805                                if (now >= (s.lastActivity
14806                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14807                                    // This service has not seen activity within
14808                                    // recent memory, so allow it to drop to the
14809                                    // LRU list if there is no other reason to keep
14810                                    // it around.  We'll also tag it with a label just
14811                                    // to help debug and undertand what is going on.
14812                                    if (adj > clientAdj) {
14813                                        adjType = "cch-bound-services";
14814                                    }
14815                                    clientAdj = adj;
14816                                }
14817                            }
14818                        }
14819                        if (adj > clientAdj) {
14820                            // If this process has recently shown UI, and
14821                            // the process that is binding to it is less
14822                            // important than being visible, then we don't
14823                            // care about the binding as much as we care
14824                            // about letting this process get into the LRU
14825                            // list to be killed and restarted if needed for
14826                            // memory.
14827                            if (app.hasShownUi && app != mHomeProcess
14828                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14829                                adjType = "cch-bound-ui-services";
14830                            } else {
14831                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14832                                        |Context.BIND_IMPORTANT)) != 0) {
14833                                    adj = clientAdj;
14834                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14835                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14836                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14837                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14838                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
14839                                    adj = clientAdj;
14840                                } else {
14841                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14842                                        adj = ProcessList.VISIBLE_APP_ADJ;
14843                                    }
14844                                }
14845                                if (!client.cached) {
14846                                    app.cached = false;
14847                                }
14848                                if (client.keeping) {
14849                                    app.keeping = true;
14850                                }
14851                                adjType = "service";
14852                            }
14853                        }
14854                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14855                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14856                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14857                            }
14858                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14859                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14860                                    // Special handling of clients who are in the top state.
14861                                    // We *may* want to consider this process to be in the
14862                                    // top state as well, but only if there is not another
14863                                    // reason for it to be running.  Being on the top is a
14864                                    // special state, meaning you are specifically running
14865                                    // for the current top app.  If the process is already
14866                                    // running in the background for some other reason, it
14867                                    // is more important to continue considering it to be
14868                                    // in the background state.
14869                                    mayBeTop = true;
14870                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14871                                } else {
14872                                    // Special handling for above-top states (persistent
14873                                    // processes).  These should not bring the current process
14874                                    // into the top state, since they are not on top.  Instead
14875                                    // give them the best state after that.
14876                                    clientProcState =
14877                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14878                                }
14879                            }
14880                        } else {
14881                            if (clientProcState <
14882                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14883                                clientProcState =
14884                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14885                            }
14886                        }
14887                        if (procState > clientProcState) {
14888                            procState = clientProcState;
14889                        }
14890                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
14891                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
14892                            app.pendingUiClean = true;
14893                        }
14894                        if (adjType != null) {
14895                            app.adjType = adjType;
14896                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14897                                    .REASON_SERVICE_IN_USE;
14898                            app.adjSource = cr.binding.client;
14899                            app.adjSourceOom = clientAdj;
14900                            app.adjTarget = s.name;
14901                        }
14902                    }
14903                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
14904                        app.treatLikeActivity = true;
14905                    }
14906                    final ActivityRecord a = cr.activity;
14907                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
14908                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
14909                                (a.visible || a.state == ActivityState.RESUMED
14910                                 || a.state == ActivityState.PAUSING)) {
14911                            adj = ProcessList.FOREGROUND_APP_ADJ;
14912                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14913                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14914                            }
14915                            app.cached = false;
14916                            app.adjType = "service";
14917                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14918                                    .REASON_SERVICE_IN_USE;
14919                            app.adjSource = a;
14920                            app.adjSourceOom = adj;
14921                            app.adjTarget = s.name;
14922                        }
14923                    }
14924                }
14925            }
14926        }
14927
14928        for (int provi = app.pubProviders.size()-1;
14929                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14930                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14931                        || procState > ActivityManager.PROCESS_STATE_TOP);
14932                provi--) {
14933            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
14934            for (int i = cpr.connections.size()-1;
14935                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14936                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14937                            || procState > ActivityManager.PROCESS_STATE_TOP);
14938                    i--) {
14939                ContentProviderConnection conn = cpr.connections.get(i);
14940                ProcessRecord client = conn.client;
14941                if (client == app) {
14942                    // Being our own client is not interesting.
14943                    continue;
14944                }
14945                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
14946                int clientProcState = client.curProcState;
14947                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14948                    // If the other app is cached for any reason, for purposes here
14949                    // we are going to consider it empty.
14950                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14951                }
14952                if (adj > clientAdj) {
14953                    if (app.hasShownUi && app != mHomeProcess
14954                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14955                        app.adjType = "cch-ui-provider";
14956                    } else {
14957                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
14958                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
14959                        app.adjType = "provider";
14960                    }
14961                    app.cached &= client.cached;
14962                    app.keeping |= client.keeping;
14963                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14964                            .REASON_PROVIDER_IN_USE;
14965                    app.adjSource = client;
14966                    app.adjSourceOom = clientAdj;
14967                    app.adjTarget = cpr.name;
14968                }
14969                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14970                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14971                        // Special handling of clients who are in the top state.
14972                        // We *may* want to consider this process to be in the
14973                        // top state as well, but only if there is not another
14974                        // reason for it to be running.  Being on the top is a
14975                        // special state, meaning you are specifically running
14976                        // for the current top app.  If the process is already
14977                        // running in the background for some other reason, it
14978                        // is more important to continue considering it to be
14979                        // in the background state.
14980                        mayBeTop = true;
14981                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14982                    } else {
14983                        // Special handling for above-top states (persistent
14984                        // processes).  These should not bring the current process
14985                        // into the top state, since they are not on top.  Instead
14986                        // give them the best state after that.
14987                        clientProcState =
14988                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14989                    }
14990                }
14991                if (procState > clientProcState) {
14992                    procState = clientProcState;
14993                }
14994                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14995                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14996                }
14997            }
14998            // If the provider has external (non-framework) process
14999            // dependencies, ensure that its adjustment is at least
15000            // FOREGROUND_APP_ADJ.
15001            if (cpr.hasExternalProcessHandles()) {
15002                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15003                    adj = ProcessList.FOREGROUND_APP_ADJ;
15004                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15005                    app.cached = false;
15006                    app.keeping = true;
15007                    app.adjType = "provider";
15008                    app.adjTarget = cpr.name;
15009                }
15010                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15011                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15012                }
15013            }
15014        }
15015
15016        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15017            // A client of one of our services or providers is in the top state.  We
15018            // *may* want to be in the top state, but not if we are already running in
15019            // the background for some other reason.  For the decision here, we are going
15020            // to pick out a few specific states that we want to remain in when a client
15021            // is top (states that tend to be longer-term) and otherwise allow it to go
15022            // to the top state.
15023            switch (procState) {
15024                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15025                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15026                case ActivityManager.PROCESS_STATE_SERVICE:
15027                    // These all are longer-term states, so pull them up to the top
15028                    // of the background states, but not all the way to the top state.
15029                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15030                    break;
15031                default:
15032                    // Otherwise, top is a better choice, so take it.
15033                    procState = ActivityManager.PROCESS_STATE_TOP;
15034                    break;
15035            }
15036        }
15037
15038        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15039            if (app.hasClientActivities) {
15040                // This is a cached process, but with client activities.  Mark it so.
15041                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15042                app.adjType = "cch-client-act";
15043            } else if (app.treatLikeActivity) {
15044                // This is a cached process, but somebody wants us to treat it like it has
15045                // an activity, okay!
15046                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15047                app.adjType = "cch-as-act";
15048            }
15049        }
15050
15051        if (adj == ProcessList.SERVICE_ADJ) {
15052            if (doingAll) {
15053                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15054                mNewNumServiceProcs++;
15055                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15056                if (!app.serviceb) {
15057                    // This service isn't far enough down on the LRU list to
15058                    // normally be a B service, but if we are low on RAM and it
15059                    // is large we want to force it down since we would prefer to
15060                    // keep launcher over it.
15061                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15062                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15063                        app.serviceHighRam = true;
15064                        app.serviceb = true;
15065                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15066                    } else {
15067                        mNewNumAServiceProcs++;
15068                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15069                    }
15070                } else {
15071                    app.serviceHighRam = false;
15072                }
15073            }
15074            if (app.serviceb) {
15075                adj = ProcessList.SERVICE_B_ADJ;
15076            }
15077        }
15078
15079        app.curRawAdj = adj;
15080
15081        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15082        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15083        if (adj > app.maxAdj) {
15084            adj = app.maxAdj;
15085            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15086                schedGroup = Process.THREAD_GROUP_DEFAULT;
15087            }
15088        }
15089        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15090            app.keeping = true;
15091        }
15092
15093        // Do final modification to adj.  Everything we do between here and applying
15094        // the final setAdj must be done in this function, because we will also use
15095        // it when computing the final cached adj later.  Note that we don't need to
15096        // worry about this for max adj above, since max adj will always be used to
15097        // keep it out of the cached vaues.
15098        adj = app.modifyRawOomAdj(adj);
15099
15100        app.curProcState = procState;
15101
15102        int importance = app.memImportance;
15103        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
15104            app.curAdj = adj;
15105            app.curSchedGroup = schedGroup;
15106            if (!interesting) {
15107                // For this reporting, if there is not something explicitly
15108                // interesting in this process then we will push it to the
15109                // background importance.
15110                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
15111            } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
15112                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
15113            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
15114                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
15115            } else if (adj >= ProcessList.HOME_APP_ADJ) {
15116                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
15117            } else if (adj >= ProcessList.SERVICE_ADJ) {
15118                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
15119            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15120                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
15121            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
15122                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
15123            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
15124                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
15125            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
15126                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
15127            } else {
15128                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
15129            }
15130        }
15131
15132        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
15133        if (foregroundActivities != app.foregroundActivities) {
15134            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15135        }
15136        if (changes != 0) {
15137            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15138            app.memImportance = importance;
15139            app.foregroundActivities = foregroundActivities;
15140            int i = mPendingProcessChanges.size()-1;
15141            ProcessChangeItem item = null;
15142            while (i >= 0) {
15143                item = mPendingProcessChanges.get(i);
15144                if (item.pid == app.pid) {
15145                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15146                    break;
15147                }
15148                i--;
15149            }
15150            if (i < 0) {
15151                // No existing item in pending changes; need a new one.
15152                final int NA = mAvailProcessChanges.size();
15153                if (NA > 0) {
15154                    item = mAvailProcessChanges.remove(NA-1);
15155                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15156                } else {
15157                    item = new ProcessChangeItem();
15158                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15159                }
15160                item.changes = 0;
15161                item.pid = app.pid;
15162                item.uid = app.info.uid;
15163                if (mPendingProcessChanges.size() == 0) {
15164                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15165                            "*** Enqueueing dispatch processes changed!");
15166                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15167                }
15168                mPendingProcessChanges.add(item);
15169            }
15170            item.changes |= changes;
15171            item.importance = importance;
15172            item.foregroundActivities = foregroundActivities;
15173            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
15174                    + Integer.toHexString(System.identityHashCode(item))
15175                    + " " + app.toShortString() + ": changes=" + item.changes
15176                    + " importance=" + item.importance
15177                    + " foreground=" + item.foregroundActivities
15178                    + " type=" + app.adjType + " source=" + app.adjSource
15179                    + " target=" + app.adjTarget);
15180        }
15181
15182        return app.curRawAdj;
15183    }
15184
15185    /**
15186     * Schedule PSS collection of a process.
15187     */
15188    void requestPssLocked(ProcessRecord proc, int procState) {
15189        if (mPendingPssProcesses.contains(proc)) {
15190            return;
15191        }
15192        if (mPendingPssProcesses.size() == 0) {
15193            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15194        }
15195        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15196        proc.pssProcState = procState;
15197        mPendingPssProcesses.add(proc);
15198    }
15199
15200    /**
15201     * Schedule PSS collection of all processes.
15202     */
15203    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15204        if (!always) {
15205            if (now < (mLastFullPssTime +
15206                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15207                return;
15208            }
15209        }
15210        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15211        mLastFullPssTime = now;
15212        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15213        mPendingPssProcesses.clear();
15214        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15215            ProcessRecord app = mLruProcesses.get(i);
15216            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15217                app.pssProcState = app.setProcState;
15218                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15219                        mSleeping, now);
15220                mPendingPssProcesses.add(app);
15221            }
15222        }
15223        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15224    }
15225
15226    /**
15227     * Ask a given process to GC right now.
15228     */
15229    final void performAppGcLocked(ProcessRecord app) {
15230        try {
15231            app.lastRequestedGc = SystemClock.uptimeMillis();
15232            if (app.thread != null) {
15233                if (app.reportLowMemory) {
15234                    app.reportLowMemory = false;
15235                    app.thread.scheduleLowMemory();
15236                } else {
15237                    app.thread.processInBackground();
15238                }
15239            }
15240        } catch (Exception e) {
15241            // whatever.
15242        }
15243    }
15244
15245    /**
15246     * Returns true if things are idle enough to perform GCs.
15247     */
15248    private final boolean canGcNowLocked() {
15249        boolean processingBroadcasts = false;
15250        for (BroadcastQueue q : mBroadcastQueues) {
15251            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15252                processingBroadcasts = true;
15253            }
15254        }
15255        return !processingBroadcasts
15256                && (mSleeping || mStackSupervisor.allResumedActivitiesIdle());
15257    }
15258
15259    /**
15260     * Perform GCs on all processes that are waiting for it, but only
15261     * if things are idle.
15262     */
15263    final void performAppGcsLocked() {
15264        final int N = mProcessesToGc.size();
15265        if (N <= 0) {
15266            return;
15267        }
15268        if (canGcNowLocked()) {
15269            while (mProcessesToGc.size() > 0) {
15270                ProcessRecord proc = mProcessesToGc.remove(0);
15271                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15272                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15273                            <= SystemClock.uptimeMillis()) {
15274                        // To avoid spamming the system, we will GC processes one
15275                        // at a time, waiting a few seconds between each.
15276                        performAppGcLocked(proc);
15277                        scheduleAppGcsLocked();
15278                        return;
15279                    } else {
15280                        // It hasn't been long enough since we last GCed this
15281                        // process...  put it in the list to wait for its time.
15282                        addProcessToGcListLocked(proc);
15283                        break;
15284                    }
15285                }
15286            }
15287
15288            scheduleAppGcsLocked();
15289        }
15290    }
15291
15292    /**
15293     * If all looks good, perform GCs on all processes waiting for them.
15294     */
15295    final void performAppGcsIfAppropriateLocked() {
15296        if (canGcNowLocked()) {
15297            performAppGcsLocked();
15298            return;
15299        }
15300        // Still not idle, wait some more.
15301        scheduleAppGcsLocked();
15302    }
15303
15304    /**
15305     * Schedule the execution of all pending app GCs.
15306     */
15307    final void scheduleAppGcsLocked() {
15308        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15309
15310        if (mProcessesToGc.size() > 0) {
15311            // Schedule a GC for the time to the next process.
15312            ProcessRecord proc = mProcessesToGc.get(0);
15313            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15314
15315            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15316            long now = SystemClock.uptimeMillis();
15317            if (when < (now+GC_TIMEOUT)) {
15318                when = now + GC_TIMEOUT;
15319            }
15320            mHandler.sendMessageAtTime(msg, when);
15321        }
15322    }
15323
15324    /**
15325     * Add a process to the array of processes waiting to be GCed.  Keeps the
15326     * list in sorted order by the last GC time.  The process can't already be
15327     * on the list.
15328     */
15329    final void addProcessToGcListLocked(ProcessRecord proc) {
15330        boolean added = false;
15331        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15332            if (mProcessesToGc.get(i).lastRequestedGc <
15333                    proc.lastRequestedGc) {
15334                added = true;
15335                mProcessesToGc.add(i+1, proc);
15336                break;
15337            }
15338        }
15339        if (!added) {
15340            mProcessesToGc.add(0, proc);
15341        }
15342    }
15343
15344    /**
15345     * Set up to ask a process to GC itself.  This will either do it
15346     * immediately, or put it on the list of processes to gc the next
15347     * time things are idle.
15348     */
15349    final void scheduleAppGcLocked(ProcessRecord app) {
15350        long now = SystemClock.uptimeMillis();
15351        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15352            return;
15353        }
15354        if (!mProcessesToGc.contains(app)) {
15355            addProcessToGcListLocked(app);
15356            scheduleAppGcsLocked();
15357        }
15358    }
15359
15360    final void checkExcessivePowerUsageLocked(boolean doKills) {
15361        updateCpuStatsNow();
15362
15363        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15364        boolean doWakeKills = doKills;
15365        boolean doCpuKills = doKills;
15366        if (mLastPowerCheckRealtime == 0) {
15367            doWakeKills = false;
15368        }
15369        if (mLastPowerCheckUptime == 0) {
15370            doCpuKills = false;
15371        }
15372        if (stats.isScreenOn()) {
15373            doWakeKills = false;
15374        }
15375        final long curRealtime = SystemClock.elapsedRealtime();
15376        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15377        final long curUptime = SystemClock.uptimeMillis();
15378        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15379        mLastPowerCheckRealtime = curRealtime;
15380        mLastPowerCheckUptime = curUptime;
15381        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15382            doWakeKills = false;
15383        }
15384        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15385            doCpuKills = false;
15386        }
15387        int i = mLruProcesses.size();
15388        while (i > 0) {
15389            i--;
15390            ProcessRecord app = mLruProcesses.get(i);
15391            if (!app.keeping) {
15392                long wtime;
15393                synchronized (stats) {
15394                    wtime = stats.getProcessWakeTime(app.info.uid,
15395                            app.pid, curRealtime);
15396                }
15397                long wtimeUsed = wtime - app.lastWakeTime;
15398                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15399                if (DEBUG_POWER) {
15400                    StringBuilder sb = new StringBuilder(128);
15401                    sb.append("Wake for ");
15402                    app.toShortString(sb);
15403                    sb.append(": over ");
15404                    TimeUtils.formatDuration(realtimeSince, sb);
15405                    sb.append(" used ");
15406                    TimeUtils.formatDuration(wtimeUsed, sb);
15407                    sb.append(" (");
15408                    sb.append((wtimeUsed*100)/realtimeSince);
15409                    sb.append("%)");
15410                    Slog.i(TAG, sb.toString());
15411                    sb.setLength(0);
15412                    sb.append("CPU for ");
15413                    app.toShortString(sb);
15414                    sb.append(": over ");
15415                    TimeUtils.formatDuration(uptimeSince, sb);
15416                    sb.append(" used ");
15417                    TimeUtils.formatDuration(cputimeUsed, sb);
15418                    sb.append(" (");
15419                    sb.append((cputimeUsed*100)/uptimeSince);
15420                    sb.append("%)");
15421                    Slog.i(TAG, sb.toString());
15422                }
15423                // If a process has held a wake lock for more
15424                // than 50% of the time during this period,
15425                // that sounds bad.  Kill!
15426                if (doWakeKills && realtimeSince > 0
15427                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15428                    synchronized (stats) {
15429                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15430                                realtimeSince, wtimeUsed);
15431                    }
15432                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15433                            + " during " + realtimeSince);
15434                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15435                } else if (doCpuKills && uptimeSince > 0
15436                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15437                    synchronized (stats) {
15438                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15439                                uptimeSince, cputimeUsed);
15440                    }
15441                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15442                            + " during " + uptimeSince);
15443                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15444                } else {
15445                    app.lastWakeTime = wtime;
15446                    app.lastCpuTime = app.curCpuTime;
15447                }
15448            }
15449        }
15450    }
15451
15452    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15453            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15454        boolean success = true;
15455
15456        if (app.curRawAdj != app.setRawAdj) {
15457            if (wasKeeping && !app.keeping) {
15458                // This app is no longer something we want to keep.  Note
15459                // its current wake lock time to later know to kill it if
15460                // it is not behaving well.
15461                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15462                synchronized (stats) {
15463                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15464                            app.pid, SystemClock.elapsedRealtime());
15465                }
15466                app.lastCpuTime = app.curCpuTime;
15467            }
15468
15469            app.setRawAdj = app.curRawAdj;
15470        }
15471
15472        if (app.curAdj != app.setAdj) {
15473            ProcessList.setOomAdj(app.pid, app.curAdj);
15474            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15475                TAG, "Set " + app.pid + " " + app.processName +
15476                " adj " + app.curAdj + ": " + app.adjType);
15477            app.setAdj = app.curAdj;
15478        }
15479
15480        if (app.setSchedGroup != app.curSchedGroup) {
15481            app.setSchedGroup = app.curSchedGroup;
15482            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15483                    "Setting process group of " + app.processName
15484                    + " to " + app.curSchedGroup);
15485            if (app.waitingToKill != null &&
15486                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15487                killUnneededProcessLocked(app, app.waitingToKill);
15488                success = false;
15489            } else {
15490                if (true) {
15491                    long oldId = Binder.clearCallingIdentity();
15492                    try {
15493                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15494                    } catch (Exception e) {
15495                        Slog.w(TAG, "Failed setting process group of " + app.pid
15496                                + " to " + app.curSchedGroup);
15497                        e.printStackTrace();
15498                    } finally {
15499                        Binder.restoreCallingIdentity(oldId);
15500                    }
15501                } else {
15502                    if (app.thread != null) {
15503                        try {
15504                            app.thread.setSchedulingGroup(app.curSchedGroup);
15505                        } catch (RemoteException e) {
15506                        }
15507                    }
15508                }
15509                Process.setSwappiness(app.pid,
15510                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15511            }
15512        }
15513        if (app.repProcState != app.curProcState) {
15514            app.repProcState = app.curProcState;
15515            if (!reportingProcessState && app.thread != null) {
15516                try {
15517                    if (false) {
15518                        //RuntimeException h = new RuntimeException("here");
15519                        Slog.i(TAG, "Sending new process state " + app.repProcState
15520                                + " to " + app /*, h*/);
15521                    }
15522                    app.thread.setProcessState(app.repProcState);
15523                } catch (RemoteException e) {
15524                }
15525            }
15526        }
15527        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15528                app.setProcState)) {
15529            app.lastStateTime = now;
15530            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15531                    mSleeping, now);
15532            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15533                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15534                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15535                    + (app.nextPssTime-now) + ": " + app);
15536        } else {
15537            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15538                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15539                requestPssLocked(app, app.setProcState);
15540                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15541                        mSleeping, now);
15542            } else if (false && DEBUG_PSS) {
15543                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15544            }
15545        }
15546        if (app.setProcState != app.curProcState) {
15547            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15548                    "Proc state change of " + app.processName
15549                    + " to " + app.curProcState);
15550            app.setProcState = app.curProcState;
15551            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15552                app.notCachedSinceIdle = false;
15553            }
15554            if (!doingAll) {
15555                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15556            } else {
15557                app.procStateChanged = true;
15558            }
15559        }
15560        return success;
15561    }
15562
15563    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15564        if (proc.thread != null && proc.baseProcessTracker != null) {
15565            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15566        }
15567    }
15568
15569    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15570            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15571        if (app.thread == null) {
15572            return false;
15573        }
15574
15575        final boolean wasKeeping = app.keeping;
15576
15577        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15578
15579        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll,
15580                reportingProcessState, now);
15581    }
15582
15583    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15584            boolean oomAdj) {
15585        if (isForeground != proc.foregroundServices) {
15586            proc.foregroundServices = isForeground;
15587            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15588                    proc.info.uid);
15589            if (isForeground) {
15590                if (curProcs == null) {
15591                    curProcs = new ArrayList<ProcessRecord>();
15592                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15593                }
15594                if (!curProcs.contains(proc)) {
15595                    curProcs.add(proc);
15596                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15597                            proc.info.packageName, proc.info.uid);
15598                }
15599            } else {
15600                if (curProcs != null) {
15601                    if (curProcs.remove(proc)) {
15602                        mBatteryStatsService.noteEvent(
15603                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15604                                proc.info.packageName, proc.info.uid);
15605                        if (curProcs.size() <= 0) {
15606                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15607                        }
15608                    }
15609                }
15610            }
15611            if (oomAdj) {
15612                updateOomAdjLocked();
15613            }
15614        }
15615    }
15616
15617    private final ActivityRecord resumedAppLocked() {
15618        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15619        String pkg;
15620        int uid;
15621        if (act != null) {
15622            pkg = act.packageName;
15623            uid = act.info.applicationInfo.uid;
15624        } else {
15625            pkg = null;
15626            uid = -1;
15627        }
15628        // Has the UID or resumed package name changed?
15629        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15630                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15631            if (mCurResumedPackage != null) {
15632                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15633                        mCurResumedPackage, mCurResumedUid);
15634            }
15635            mCurResumedPackage = pkg;
15636            mCurResumedUid = uid;
15637            if (mCurResumedPackage != null) {
15638                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15639                        mCurResumedPackage, mCurResumedUid);
15640            }
15641        }
15642        return act;
15643    }
15644
15645    final boolean updateOomAdjLocked(ProcessRecord app) {
15646        return updateOomAdjLocked(app, false);
15647    }
15648
15649    final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) {
15650        final ActivityRecord TOP_ACT = resumedAppLocked();
15651        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15652        final boolean wasCached = app.cached;
15653
15654        mAdjSeq++;
15655
15656        // This is the desired cached adjusment we want to tell it to use.
15657        // If our app is currently cached, we know it, and that is it.  Otherwise,
15658        // we don't know it yet, and it needs to now be cached we will then
15659        // need to do a complete oom adj.
15660        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15661                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15662        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState,
15663                SystemClock.uptimeMillis());
15664        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15665            // Changed to/from cached state, so apps after it in the LRU
15666            // list may also be changed.
15667            updateOomAdjLocked();
15668        }
15669        return success;
15670    }
15671
15672    final void updateOomAdjLocked() {
15673        final ActivityRecord TOP_ACT = resumedAppLocked();
15674        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15675        final long now = SystemClock.uptimeMillis();
15676        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15677        final int N = mLruProcesses.size();
15678
15679        if (false) {
15680            RuntimeException e = new RuntimeException();
15681            e.fillInStackTrace();
15682            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15683        }
15684
15685        mAdjSeq++;
15686        mNewNumServiceProcs = 0;
15687        mNewNumAServiceProcs = 0;
15688
15689        final int emptyProcessLimit;
15690        final int cachedProcessLimit;
15691        if (mProcessLimit <= 0) {
15692            emptyProcessLimit = cachedProcessLimit = 0;
15693        } else if (mProcessLimit == 1) {
15694            emptyProcessLimit = 1;
15695            cachedProcessLimit = 0;
15696        } else {
15697            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15698            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15699        }
15700
15701        // Let's determine how many processes we have running vs.
15702        // how many slots we have for background processes; we may want
15703        // to put multiple processes in a slot of there are enough of
15704        // them.
15705        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15706                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15707        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15708        if (numEmptyProcs > cachedProcessLimit) {
15709            // If there are more empty processes than our limit on cached
15710            // processes, then use the cached process limit for the factor.
15711            // This ensures that the really old empty processes get pushed
15712            // down to the bottom, so if we are running low on memory we will
15713            // have a better chance at keeping around more cached processes
15714            // instead of a gazillion empty processes.
15715            numEmptyProcs = cachedProcessLimit;
15716        }
15717        int emptyFactor = numEmptyProcs/numSlots;
15718        if (emptyFactor < 1) emptyFactor = 1;
15719        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15720        if (cachedFactor < 1) cachedFactor = 1;
15721        int stepCached = 0;
15722        int stepEmpty = 0;
15723        int numCached = 0;
15724        int numEmpty = 0;
15725        int numTrimming = 0;
15726
15727        mNumNonCachedProcs = 0;
15728        mNumCachedHiddenProcs = 0;
15729
15730        // First update the OOM adjustment for each of the
15731        // application processes based on their current state.
15732        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15733        int nextCachedAdj = curCachedAdj+1;
15734        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15735        int nextEmptyAdj = curEmptyAdj+2;
15736        for (int i=N-1; i>=0; i--) {
15737            ProcessRecord app = mLruProcesses.get(i);
15738            if (!app.killedByAm && app.thread != null) {
15739                app.procStateChanged = false;
15740                final boolean wasKeeping = app.keeping;
15741                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15742
15743                // If we haven't yet assigned the final cached adj
15744                // to the process, do that now.
15745                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15746                    switch (app.curProcState) {
15747                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15748                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15749                            // This process is a cached process holding activities...
15750                            // assign it the next cached value for that type, and then
15751                            // step that cached level.
15752                            app.curRawAdj = curCachedAdj;
15753                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15754                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15755                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15756                                    + ")");
15757                            if (curCachedAdj != nextCachedAdj) {
15758                                stepCached++;
15759                                if (stepCached >= cachedFactor) {
15760                                    stepCached = 0;
15761                                    curCachedAdj = nextCachedAdj;
15762                                    nextCachedAdj += 2;
15763                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15764                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15765                                    }
15766                                }
15767                            }
15768                            break;
15769                        default:
15770                            // For everything else, assign next empty cached process
15771                            // level and bump that up.  Note that this means that
15772                            // long-running services that have dropped down to the
15773                            // cached level will be treated as empty (since their process
15774                            // state is still as a service), which is what we want.
15775                            app.curRawAdj = curEmptyAdj;
15776                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15777                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15778                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15779                                    + ")");
15780                            if (curEmptyAdj != nextEmptyAdj) {
15781                                stepEmpty++;
15782                                if (stepEmpty >= emptyFactor) {
15783                                    stepEmpty = 0;
15784                                    curEmptyAdj = nextEmptyAdj;
15785                                    nextEmptyAdj += 2;
15786                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15787                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15788                                    }
15789                                }
15790                            }
15791                            break;
15792                    }
15793                }
15794
15795                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now);
15796
15797                // Count the number of process types.
15798                switch (app.curProcState) {
15799                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15800                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15801                        mNumCachedHiddenProcs++;
15802                        numCached++;
15803                        if (numCached > cachedProcessLimit) {
15804                            killUnneededProcessLocked(app, "cached #" + numCached);
15805                        }
15806                        break;
15807                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15808                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15809                                && app.lastActivityTime < oldTime) {
15810                            killUnneededProcessLocked(app, "empty for "
15811                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15812                                    / 1000) + "s");
15813                        } else {
15814                            numEmpty++;
15815                            if (numEmpty > emptyProcessLimit) {
15816                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15817                            }
15818                        }
15819                        break;
15820                    default:
15821                        mNumNonCachedProcs++;
15822                        break;
15823                }
15824
15825                if (app.isolated && app.services.size() <= 0) {
15826                    // If this is an isolated process, and there are no
15827                    // services running in it, then the process is no longer
15828                    // needed.  We agressively kill these because we can by
15829                    // definition not re-use the same process again, and it is
15830                    // good to avoid having whatever code was running in them
15831                    // left sitting around after no longer needed.
15832                    killUnneededProcessLocked(app, "isolated not needed");
15833                }
15834
15835                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15836                        && !app.killedByAm) {
15837                    numTrimming++;
15838                }
15839            }
15840        }
15841
15842        mNumServiceProcs = mNewNumServiceProcs;
15843
15844        // Now determine the memory trimming level of background processes.
15845        // Unfortunately we need to start at the back of the list to do this
15846        // properly.  We only do this if the number of background apps we
15847        // are managing to keep around is less than half the maximum we desire;
15848        // if we are keeping a good number around, we'll let them use whatever
15849        // memory they want.
15850        final int numCachedAndEmpty = numCached + numEmpty;
15851        int memFactor;
15852        if (numCached <= ProcessList.TRIM_CACHED_APPS
15853                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
15854            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
15855                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
15856            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
15857                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
15858            } else {
15859                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
15860            }
15861        } else {
15862            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
15863        }
15864        // We always allow the memory level to go up (better).  We only allow it to go
15865        // down if we are in a state where that is allowed, *and* the total number of processes
15866        // has gone down since last time.
15867        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
15868                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
15869                + " last=" + mLastNumProcesses);
15870        if (memFactor > mLastMemoryLevel) {
15871            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
15872                memFactor = mLastMemoryLevel;
15873                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
15874            }
15875        }
15876        mLastMemoryLevel = memFactor;
15877        mLastNumProcesses = mLruProcesses.size();
15878        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now);
15879        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
15880        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
15881            if (mLowRamStartTime == 0) {
15882                mLowRamStartTime = now;
15883            }
15884            int step = 0;
15885            int fgTrimLevel;
15886            switch (memFactor) {
15887                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15888                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
15889                    break;
15890                case ProcessStats.ADJ_MEM_FACTOR_LOW:
15891                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
15892                    break;
15893                default:
15894                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
15895                    break;
15896            }
15897            int factor = numTrimming/3;
15898            int minFactor = 2;
15899            if (mHomeProcess != null) minFactor++;
15900            if (mPreviousProcess != null) minFactor++;
15901            if (factor < minFactor) factor = minFactor;
15902            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
15903            for (int i=N-1; i>=0; i--) {
15904                ProcessRecord app = mLruProcesses.get(i);
15905                if (allChanged || app.procStateChanged) {
15906                    setProcessTrackerState(app, trackerMemFactor, now);
15907                    app.procStateChanged = false;
15908                }
15909                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15910                        && !app.killedByAm) {
15911                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
15912                        try {
15913                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15914                                    "Trimming memory of " + app.processName
15915                                    + " to " + curLevel);
15916                            app.thread.scheduleTrimMemory(curLevel);
15917                        } catch (RemoteException e) {
15918                        }
15919                        if (false) {
15920                            // For now we won't do this; our memory trimming seems
15921                            // to be good enough at this point that destroying
15922                            // activities causes more harm than good.
15923                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
15924                                    && app != mHomeProcess && app != mPreviousProcess) {
15925                                // Need to do this on its own message because the stack may not
15926                                // be in a consistent state at this point.
15927                                // For these apps we will also finish their activities
15928                                // to help them free memory.
15929                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
15930                            }
15931                        }
15932                    }
15933                    app.trimMemoryLevel = curLevel;
15934                    step++;
15935                    if (step >= factor) {
15936                        step = 0;
15937                        switch (curLevel) {
15938                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
15939                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
15940                                break;
15941                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
15942                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15943                                break;
15944                        }
15945                    }
15946                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15947                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
15948                            && app.thread != null) {
15949                        try {
15950                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15951                                    "Trimming memory of heavy-weight " + app.processName
15952                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15953                            app.thread.scheduleTrimMemory(
15954                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15955                        } catch (RemoteException e) {
15956                        }
15957                    }
15958                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15959                } else {
15960                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15961                            || app.systemNoUi) && app.pendingUiClean) {
15962                        // If this application is now in the background and it
15963                        // had done UI, then give it the special trim level to
15964                        // have it free UI resources.
15965                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
15966                        if (app.trimMemoryLevel < level && app.thread != null) {
15967                            try {
15968                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15969                                        "Trimming memory of bg-ui " + app.processName
15970                                        + " to " + level);
15971                                app.thread.scheduleTrimMemory(level);
15972                            } catch (RemoteException e) {
15973                            }
15974                        }
15975                        app.pendingUiClean = false;
15976                    }
15977                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
15978                        try {
15979                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15980                                    "Trimming memory of fg " + app.processName
15981                                    + " to " + fgTrimLevel);
15982                            app.thread.scheduleTrimMemory(fgTrimLevel);
15983                        } catch (RemoteException e) {
15984                        }
15985                    }
15986                    app.trimMemoryLevel = fgTrimLevel;
15987                }
15988            }
15989        } else {
15990            if (mLowRamStartTime != 0) {
15991                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
15992                mLowRamStartTime = 0;
15993            }
15994            for (int i=N-1; i>=0; i--) {
15995                ProcessRecord app = mLruProcesses.get(i);
15996                if (allChanged || app.procStateChanged) {
15997                    setProcessTrackerState(app, trackerMemFactor, now);
15998                    app.procStateChanged = false;
15999                }
16000                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16001                        || app.systemNoUi) && app.pendingUiClean) {
16002                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16003                            && app.thread != null) {
16004                        try {
16005                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16006                                    "Trimming memory of ui hidden " + app.processName
16007                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16008                            app.thread.scheduleTrimMemory(
16009                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16010                        } catch (RemoteException e) {
16011                        }
16012                    }
16013                    app.pendingUiClean = false;
16014                }
16015                app.trimMemoryLevel = 0;
16016            }
16017        }
16018
16019        if (mAlwaysFinishActivities) {
16020            // Need to do this on its own message because the stack may not
16021            // be in a consistent state at this point.
16022            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16023        }
16024
16025        if (allChanged) {
16026            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16027        }
16028
16029        if (mProcessStats.shouldWriteNowLocked(now)) {
16030            mHandler.post(new Runnable() {
16031                @Override public void run() {
16032                    synchronized (ActivityManagerService.this) {
16033                        mProcessStats.writeStateAsyncLocked();
16034                    }
16035                }
16036            });
16037        }
16038
16039        if (DEBUG_OOM_ADJ) {
16040            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16041        }
16042    }
16043
16044    final void trimApplications() {
16045        synchronized (this) {
16046            int i;
16047
16048            // First remove any unused application processes whose package
16049            // has been removed.
16050            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16051                final ProcessRecord app = mRemovedProcesses.get(i);
16052                if (app.activities.size() == 0
16053                        && app.curReceiver == null && app.services.size() == 0) {
16054                    Slog.i(
16055                        TAG, "Exiting empty application process "
16056                        + app.processName + " ("
16057                        + (app.thread != null ? app.thread.asBinder() : null)
16058                        + ")\n");
16059                    if (app.pid > 0 && app.pid != MY_PID) {
16060                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16061                                app.processName, app.setAdj, "empty");
16062                        app.killedByAm = true;
16063                        Process.killProcessQuiet(app.pid);
16064                    } else {
16065                        try {
16066                            app.thread.scheduleExit();
16067                        } catch (Exception e) {
16068                            // Ignore exceptions.
16069                        }
16070                    }
16071                    cleanUpApplicationRecordLocked(app, false, true, -1);
16072                    mRemovedProcesses.remove(i);
16073
16074                    if (app.persistent) {
16075                        if (app.persistent) {
16076                            addAppLocked(app.info, false);
16077                        }
16078                    }
16079                }
16080            }
16081
16082            // Now update the oom adj for all processes.
16083            updateOomAdjLocked();
16084        }
16085    }
16086
16087    /** This method sends the specified signal to each of the persistent apps */
16088    public void signalPersistentProcesses(int sig) throws RemoteException {
16089        if (sig != Process.SIGNAL_USR1) {
16090            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16091        }
16092
16093        synchronized (this) {
16094            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16095                    != PackageManager.PERMISSION_GRANTED) {
16096                throw new SecurityException("Requires permission "
16097                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16098            }
16099
16100            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16101                ProcessRecord r = mLruProcesses.get(i);
16102                if (r.thread != null && r.persistent) {
16103                    Process.sendSignal(r.pid, sig);
16104                }
16105            }
16106        }
16107    }
16108
16109    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16110        if (proc == null || proc == mProfileProc) {
16111            proc = mProfileProc;
16112            path = mProfileFile;
16113            profileType = mProfileType;
16114            clearProfilerLocked();
16115        }
16116        if (proc == null) {
16117            return;
16118        }
16119        try {
16120            proc.thread.profilerControl(false, path, null, profileType);
16121        } catch (RemoteException e) {
16122            throw new IllegalStateException("Process disappeared");
16123        }
16124    }
16125
16126    private void clearProfilerLocked() {
16127        if (mProfileFd != null) {
16128            try {
16129                mProfileFd.close();
16130            } catch (IOException e) {
16131            }
16132        }
16133        mProfileApp = null;
16134        mProfileProc = null;
16135        mProfileFile = null;
16136        mProfileType = 0;
16137        mAutoStopProfiler = false;
16138    }
16139
16140    public boolean profileControl(String process, int userId, boolean start,
16141            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16142
16143        try {
16144            synchronized (this) {
16145                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16146                // its own permission.
16147                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16148                        != PackageManager.PERMISSION_GRANTED) {
16149                    throw new SecurityException("Requires permission "
16150                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16151                }
16152
16153                if (start && fd == null) {
16154                    throw new IllegalArgumentException("null fd");
16155                }
16156
16157                ProcessRecord proc = null;
16158                if (process != null) {
16159                    proc = findProcessLocked(process, userId, "profileControl");
16160                }
16161
16162                if (start && (proc == null || proc.thread == null)) {
16163                    throw new IllegalArgumentException("Unknown process: " + process);
16164                }
16165
16166                if (start) {
16167                    stopProfilerLocked(null, null, 0);
16168                    setProfileApp(proc.info, proc.processName, path, fd, false);
16169                    mProfileProc = proc;
16170                    mProfileType = profileType;
16171                    try {
16172                        fd = fd.dup();
16173                    } catch (IOException e) {
16174                        fd = null;
16175                    }
16176                    proc.thread.profilerControl(start, path, fd, profileType);
16177                    fd = null;
16178                    mProfileFd = null;
16179                } else {
16180                    stopProfilerLocked(proc, path, profileType);
16181                    if (fd != null) {
16182                        try {
16183                            fd.close();
16184                        } catch (IOException e) {
16185                        }
16186                    }
16187                }
16188
16189                return true;
16190            }
16191        } catch (RemoteException e) {
16192            throw new IllegalStateException("Process disappeared");
16193        } finally {
16194            if (fd != null) {
16195                try {
16196                    fd.close();
16197                } catch (IOException e) {
16198                }
16199            }
16200        }
16201    }
16202
16203    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16204        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16205                userId, true, true, callName, null);
16206        ProcessRecord proc = null;
16207        try {
16208            int pid = Integer.parseInt(process);
16209            synchronized (mPidsSelfLocked) {
16210                proc = mPidsSelfLocked.get(pid);
16211            }
16212        } catch (NumberFormatException e) {
16213        }
16214
16215        if (proc == null) {
16216            ArrayMap<String, SparseArray<ProcessRecord>> all
16217                    = mProcessNames.getMap();
16218            SparseArray<ProcessRecord> procs = all.get(process);
16219            if (procs != null && procs.size() > 0) {
16220                proc = procs.valueAt(0);
16221                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16222                    for (int i=1; i<procs.size(); i++) {
16223                        ProcessRecord thisProc = procs.valueAt(i);
16224                        if (thisProc.userId == userId) {
16225                            proc = thisProc;
16226                            break;
16227                        }
16228                    }
16229                }
16230            }
16231        }
16232
16233        return proc;
16234    }
16235
16236    public boolean dumpHeap(String process, int userId, boolean managed,
16237            String path, ParcelFileDescriptor fd) throws RemoteException {
16238
16239        try {
16240            synchronized (this) {
16241                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16242                // its own permission (same as profileControl).
16243                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16244                        != PackageManager.PERMISSION_GRANTED) {
16245                    throw new SecurityException("Requires permission "
16246                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16247                }
16248
16249                if (fd == null) {
16250                    throw new IllegalArgumentException("null fd");
16251                }
16252
16253                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16254                if (proc == null || proc.thread == null) {
16255                    throw new IllegalArgumentException("Unknown process: " + process);
16256                }
16257
16258                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16259                if (!isDebuggable) {
16260                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16261                        throw new SecurityException("Process not debuggable: " + proc);
16262                    }
16263                }
16264
16265                proc.thread.dumpHeap(managed, path, fd);
16266                fd = null;
16267                return true;
16268            }
16269        } catch (RemoteException e) {
16270            throw new IllegalStateException("Process disappeared");
16271        } finally {
16272            if (fd != null) {
16273                try {
16274                    fd.close();
16275                } catch (IOException e) {
16276                }
16277            }
16278        }
16279    }
16280
16281    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16282    public void monitor() {
16283        synchronized (this) { }
16284    }
16285
16286    void onCoreSettingsChange(Bundle settings) {
16287        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16288            ProcessRecord processRecord = mLruProcesses.get(i);
16289            try {
16290                if (processRecord.thread != null) {
16291                    processRecord.thread.setCoreSettings(settings);
16292                }
16293            } catch (RemoteException re) {
16294                /* ignore */
16295            }
16296        }
16297    }
16298
16299    // Multi-user methods
16300
16301    /**
16302     * Start user, if its not already running, but don't bring it to foreground.
16303     */
16304    @Override
16305    public boolean startUserInBackground(final int userId) {
16306        return startUser(userId, /* foreground */ false);
16307    }
16308
16309    /**
16310     * Refreshes the list of users related to the current user when either a
16311     * user switch happens or when a new related user is started in the
16312     * background.
16313     */
16314    private void updateRelatedUserIdsLocked() {
16315        final List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(mCurrentUserId);
16316        int[] relatedUserIds = new int[relatedUsers.size()]; // relatedUsers will not be null
16317        for (int i = 0; i < relatedUserIds.length; i++) {
16318            relatedUserIds[i] = relatedUsers.get(i).id;
16319        }
16320        mRelatedUserIds = relatedUserIds;
16321    }
16322
16323    private Set getRelatedUsersLocked(int userId) {
16324        Set userIds = new HashSet<Integer>();
16325        final List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(userId);
16326        for (UserInfo user : relatedUsers) {
16327            userIds.add(Integer.valueOf(user.id));
16328        }
16329        return userIds;
16330    }
16331
16332    @Override
16333    public boolean switchUser(final int userId) {
16334        return startUser(userId, /* foregound */ true);
16335    }
16336
16337    private boolean startUser(final int userId, boolean foreground) {
16338        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16339                != PackageManager.PERMISSION_GRANTED) {
16340            String msg = "Permission Denial: switchUser() from pid="
16341                    + Binder.getCallingPid()
16342                    + ", uid=" + Binder.getCallingUid()
16343                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16344            Slog.w(TAG, msg);
16345            throw new SecurityException(msg);
16346        }
16347
16348        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16349
16350        final long ident = Binder.clearCallingIdentity();
16351        try {
16352            synchronized (this) {
16353                final int oldUserId = mCurrentUserId;
16354                if (oldUserId == userId) {
16355                    return true;
16356                }
16357
16358                mStackSupervisor.setLockTaskModeLocked(null);
16359
16360                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16361                if (userInfo == null) {
16362                    Slog.w(TAG, "No user info for user #" + userId);
16363                    return false;
16364                }
16365
16366                if (foreground) {
16367                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16368                            R.anim.screen_user_enter);
16369                }
16370
16371                boolean needStart = false;
16372
16373                // If the user we are switching to is not currently started, then
16374                // we need to start it now.
16375                if (mStartedUsers.get(userId) == null) {
16376                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16377                    updateStartedUserArrayLocked();
16378                    needStart = true;
16379                }
16380
16381                final Integer userIdInt = Integer.valueOf(userId);
16382                mUserLru.remove(userIdInt);
16383                mUserLru.add(userIdInt);
16384
16385                if (foreground) {
16386                    mCurrentUserId = userId;
16387                    updateRelatedUserIdsLocked();
16388                    mWindowManager.setCurrentUser(userId, mRelatedUserIds);
16389                    // Once the internal notion of the active user has switched, we lock the device
16390                    // with the option to show the user switcher on the keyguard.
16391                    mWindowManager.lockNow(null);
16392                } else {
16393                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16394                    updateRelatedUserIdsLocked();
16395                    mWindowManager.updateRelatedUserIds(mRelatedUserIds);
16396                    mUserLru.remove(currentUserIdInt);
16397                    mUserLru.add(currentUserIdInt);
16398                }
16399
16400                final UserStartedState uss = mStartedUsers.get(userId);
16401
16402                // Make sure user is in the started state.  If it is currently
16403                // stopping, we need to knock that off.
16404                if (uss.mState == UserStartedState.STATE_STOPPING) {
16405                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16406                    // so we can just fairly silently bring the user back from
16407                    // the almost-dead.
16408                    uss.mState = UserStartedState.STATE_RUNNING;
16409                    updateStartedUserArrayLocked();
16410                    needStart = true;
16411                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16412                    // This means ACTION_SHUTDOWN has been sent, so we will
16413                    // need to treat this as a new boot of the user.
16414                    uss.mState = UserStartedState.STATE_BOOTING;
16415                    updateStartedUserArrayLocked();
16416                    needStart = true;
16417                }
16418
16419                if (foreground) {
16420                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16421                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16422                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16423                            oldUserId, userId, uss));
16424                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16425                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16426                }
16427
16428                if (needStart) {
16429                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16430                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16431                            | Intent.FLAG_RECEIVER_FOREGROUND);
16432                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16433                    broadcastIntentLocked(null, null, intent,
16434                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16435                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16436                }
16437
16438                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16439                    if (userId != 0) {
16440                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16441                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16442                        broadcastIntentLocked(null, null, intent, null,
16443                                new IIntentReceiver.Stub() {
16444                                    public void performReceive(Intent intent, int resultCode,
16445                                            String data, Bundle extras, boolean ordered,
16446                                            boolean sticky, int sendingUser) {
16447                                        userInitialized(uss, userId);
16448                                    }
16449                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16450                                true, false, MY_PID, Process.SYSTEM_UID,
16451                                userId);
16452                        uss.initializing = true;
16453                    } else {
16454                        getUserManagerLocked().makeInitialized(userInfo.id);
16455                    }
16456                }
16457
16458                if (foreground) {
16459                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16460                    if (homeInFront) {
16461                        startHomeActivityLocked(userId);
16462                    } else {
16463                        mStackSupervisor.resumeTopActivitiesLocked();
16464                    }
16465                    EventLogTags.writeAmSwitchUser(userId);
16466                    getUserManagerLocked().userForeground(userId);
16467                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16468                }
16469
16470                if (needStart) {
16471                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16472                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16473                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16474                    broadcastIntentLocked(null, null, intent,
16475                            null, new IIntentReceiver.Stub() {
16476                                @Override
16477                                public void performReceive(Intent intent, int resultCode, String data,
16478                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16479                                        throws RemoteException {
16480                                }
16481                            }, 0, null, null,
16482                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16483                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16484                }
16485            }
16486        } finally {
16487            Binder.restoreCallingIdentity(ident);
16488        }
16489
16490        return true;
16491    }
16492
16493    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16494        long ident = Binder.clearCallingIdentity();
16495        try {
16496            Intent intent;
16497            if (oldUserId >= 0) {
16498                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16499                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16500                        | Intent.FLAG_RECEIVER_FOREGROUND);
16501                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16502                broadcastIntentLocked(null, null, intent,
16503                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16504                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16505            }
16506            if (newUserId >= 0) {
16507                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16508                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16509                        | Intent.FLAG_RECEIVER_FOREGROUND);
16510                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16511                broadcastIntentLocked(null, null, intent,
16512                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16513                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16514                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16515                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16516                        | Intent.FLAG_RECEIVER_FOREGROUND);
16517                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16518                broadcastIntentLocked(null, null, intent,
16519                        null, null, 0, null, null,
16520                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16521                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16522            }
16523        } finally {
16524            Binder.restoreCallingIdentity(ident);
16525        }
16526    }
16527
16528    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16529            final int newUserId) {
16530        final int N = mUserSwitchObservers.beginBroadcast();
16531        if (N > 0) {
16532            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16533                int mCount = 0;
16534                @Override
16535                public void sendResult(Bundle data) throws RemoteException {
16536                    synchronized (ActivityManagerService.this) {
16537                        if (mCurUserSwitchCallback == this) {
16538                            mCount++;
16539                            if (mCount == N) {
16540                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16541                            }
16542                        }
16543                    }
16544                }
16545            };
16546            synchronized (this) {
16547                uss.switching = true;
16548                mCurUserSwitchCallback = callback;
16549            }
16550            for (int i=0; i<N; i++) {
16551                try {
16552                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16553                            newUserId, callback);
16554                } catch (RemoteException e) {
16555                }
16556            }
16557        } else {
16558            synchronized (this) {
16559                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16560            }
16561        }
16562        mUserSwitchObservers.finishBroadcast();
16563    }
16564
16565    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16566        synchronized (this) {
16567            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16568            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16569        }
16570    }
16571
16572    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16573        mCurUserSwitchCallback = null;
16574        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16575        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16576                oldUserId, newUserId, uss));
16577    }
16578
16579    void userInitialized(UserStartedState uss, int newUserId) {
16580        completeSwitchAndInitalize(uss, newUserId, true, false);
16581    }
16582
16583    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16584        completeSwitchAndInitalize(uss, newUserId, false, true);
16585    }
16586
16587    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16588            boolean clearInitializing, boolean clearSwitching) {
16589        boolean unfrozen = false;
16590        synchronized (this) {
16591            if (clearInitializing) {
16592                uss.initializing = false;
16593                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16594            }
16595            if (clearSwitching) {
16596                uss.switching = false;
16597            }
16598            if (!uss.switching && !uss.initializing) {
16599                mWindowManager.stopFreezingScreen();
16600                unfrozen = true;
16601            }
16602        }
16603        if (unfrozen) {
16604            final int N = mUserSwitchObservers.beginBroadcast();
16605            for (int i=0; i<N; i++) {
16606                try {
16607                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16608                } catch (RemoteException e) {
16609                }
16610            }
16611            mUserSwitchObservers.finishBroadcast();
16612        }
16613    }
16614
16615    void scheduleStartRelatedUsersLocked() {
16616        if (!mHandler.hasMessages(START_RELATED_USERS_MSG)) {
16617            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_RELATED_USERS_MSG),
16618                    DateUtils.SECOND_IN_MILLIS);
16619        }
16620    }
16621
16622    void startRelatedUsersLocked() {
16623        if (DEBUG_MU) Slog.i(TAG_MU, "startRelatedUsersLocked");
16624        List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(mCurrentUserId);
16625        List<UserInfo> toStart = new ArrayList<UserInfo>(relatedUsers.size());
16626        for (UserInfo relatedUser : relatedUsers) {
16627            if ((relatedUser.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED) {
16628                toStart.add(relatedUser);
16629            }
16630        }
16631        final int n = toStart.size();
16632        int i = 0;
16633        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
16634            startUserInBackground(toStart.get(i).id);
16635        }
16636        if (i < n) {
16637            Slog.w(TAG_MU, "More related users than MAX_RUNNING_USERS");
16638        }
16639    }
16640
16641    void finishUserSwitch(UserStartedState uss) {
16642        synchronized (this) {
16643            if (uss.mState == UserStartedState.STATE_BOOTING
16644                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16645                uss.mState = UserStartedState.STATE_RUNNING;
16646                final int userId = uss.mHandle.getIdentifier();
16647                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16648                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16649                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16650                broadcastIntentLocked(null, null, intent,
16651                        null, null, 0, null, null,
16652                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16653                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16654            }
16655
16656            startRelatedUsersLocked();
16657
16658            int num = mUserLru.size();
16659            int i = 0;
16660            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16661                Integer oldUserId = mUserLru.get(i);
16662                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16663                if (oldUss == null) {
16664                    // Shouldn't happen, but be sane if it does.
16665                    mUserLru.remove(i);
16666                    num--;
16667                    continue;
16668                }
16669                if (oldUss.mState == UserStartedState.STATE_STOPPING
16670                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16671                    // This user is already stopping, doesn't count.
16672                    num--;
16673                    i++;
16674                    continue;
16675                }
16676                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16677                    // Owner and current can't be stopped, but count as running.
16678                    i++;
16679                    continue;
16680                }
16681                // This is a user to be stopped.
16682                stopUserLocked(oldUserId, null);
16683                num--;
16684                i++;
16685            }
16686        }
16687    }
16688
16689    @Override
16690    public int stopUser(final int userId, final IStopUserCallback callback) {
16691        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16692                != PackageManager.PERMISSION_GRANTED) {
16693            String msg = "Permission Denial: switchUser() from pid="
16694                    + Binder.getCallingPid()
16695                    + ", uid=" + Binder.getCallingUid()
16696                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16697            Slog.w(TAG, msg);
16698            throw new SecurityException(msg);
16699        }
16700        if (userId <= 0) {
16701            throw new IllegalArgumentException("Can't stop primary user " + userId);
16702        }
16703        synchronized (this) {
16704            return stopUserLocked(userId, callback);
16705        }
16706    }
16707
16708    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16709        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
16710        if (mCurrentUserId == userId) {
16711            return ActivityManager.USER_OP_IS_CURRENT;
16712        }
16713
16714        final UserStartedState uss = mStartedUsers.get(userId);
16715        if (uss == null) {
16716            // User is not started, nothing to do...  but we do need to
16717            // callback if requested.
16718            if (callback != null) {
16719                mHandler.post(new Runnable() {
16720                    @Override
16721                    public void run() {
16722                        try {
16723                            callback.userStopped(userId);
16724                        } catch (RemoteException e) {
16725                        }
16726                    }
16727                });
16728            }
16729            return ActivityManager.USER_OP_SUCCESS;
16730        }
16731
16732        if (callback != null) {
16733            uss.mStopCallbacks.add(callback);
16734        }
16735
16736        if (uss.mState != UserStartedState.STATE_STOPPING
16737                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16738            uss.mState = UserStartedState.STATE_STOPPING;
16739            updateStartedUserArrayLocked();
16740
16741            long ident = Binder.clearCallingIdentity();
16742            try {
16743                // We are going to broadcast ACTION_USER_STOPPING and then
16744                // once that is done send a final ACTION_SHUTDOWN and then
16745                // stop the user.
16746                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16747                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16748                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16749                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16750                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16751                // This is the result receiver for the final shutdown broadcast.
16752                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16753                    @Override
16754                    public void performReceive(Intent intent, int resultCode, String data,
16755                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16756                        finishUserStop(uss);
16757                    }
16758                };
16759                // This is the result receiver for the initial stopping broadcast.
16760                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16761                    @Override
16762                    public void performReceive(Intent intent, int resultCode, String data,
16763                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16764                        // On to the next.
16765                        synchronized (ActivityManagerService.this) {
16766                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16767                                // Whoops, we are being started back up.  Abort, abort!
16768                                return;
16769                            }
16770                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16771                        }
16772                        broadcastIntentLocked(null, null, shutdownIntent,
16773                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16774                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16775                    }
16776                };
16777                // Kick things off.
16778                broadcastIntentLocked(null, null, stoppingIntent,
16779                        null, stoppingReceiver, 0, null, null,
16780                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16781                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16782            } finally {
16783                Binder.restoreCallingIdentity(ident);
16784            }
16785        }
16786
16787        return ActivityManager.USER_OP_SUCCESS;
16788    }
16789
16790    void finishUserStop(UserStartedState uss) {
16791        final int userId = uss.mHandle.getIdentifier();
16792        boolean stopped;
16793        ArrayList<IStopUserCallback> callbacks;
16794        synchronized (this) {
16795            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16796            if (mStartedUsers.get(userId) != uss) {
16797                stopped = false;
16798            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16799                stopped = false;
16800            } else {
16801                stopped = true;
16802                // User can no longer run.
16803                mStartedUsers.remove(userId);
16804                mUserLru.remove(Integer.valueOf(userId));
16805                updateStartedUserArrayLocked();
16806
16807                // Clean up all state and processes associated with the user.
16808                // Kill all the processes for the user.
16809                forceStopUserLocked(userId, "finish user");
16810            }
16811        }
16812
16813        for (int i=0; i<callbacks.size(); i++) {
16814            try {
16815                if (stopped) callbacks.get(i).userStopped(userId);
16816                else callbacks.get(i).userStopAborted(userId);
16817            } catch (RemoteException e) {
16818            }
16819        }
16820
16821        mStackSupervisor.removeUserLocked(userId);
16822    }
16823
16824    @Override
16825    public UserInfo getCurrentUser() {
16826        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16827                != PackageManager.PERMISSION_GRANTED) && (
16828                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16829                != PackageManager.PERMISSION_GRANTED)) {
16830            String msg = "Permission Denial: getCurrentUser() from pid="
16831                    + Binder.getCallingPid()
16832                    + ", uid=" + Binder.getCallingUid()
16833                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16834            Slog.w(TAG, msg);
16835            throw new SecurityException(msg);
16836        }
16837        synchronized (this) {
16838            return getUserManagerLocked().getUserInfo(mCurrentUserId);
16839        }
16840    }
16841
16842    int getCurrentUserIdLocked() {
16843        return mCurrentUserId;
16844    }
16845
16846    @Override
16847    public boolean isUserRunning(int userId, boolean orStopped) {
16848        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16849                != PackageManager.PERMISSION_GRANTED) {
16850            String msg = "Permission Denial: isUserRunning() from pid="
16851                    + Binder.getCallingPid()
16852                    + ", uid=" + Binder.getCallingUid()
16853                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16854            Slog.w(TAG, msg);
16855            throw new SecurityException(msg);
16856        }
16857        synchronized (this) {
16858            return isUserRunningLocked(userId, orStopped);
16859        }
16860    }
16861
16862    boolean isUserRunningLocked(int userId, boolean orStopped) {
16863        UserStartedState state = mStartedUsers.get(userId);
16864        if (state == null) {
16865            return false;
16866        }
16867        if (orStopped) {
16868            return true;
16869        }
16870        return state.mState != UserStartedState.STATE_STOPPING
16871                && state.mState != UserStartedState.STATE_SHUTDOWN;
16872    }
16873
16874    @Override
16875    public int[] getRunningUserIds() {
16876        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16877                != PackageManager.PERMISSION_GRANTED) {
16878            String msg = "Permission Denial: isUserRunning() from pid="
16879                    + Binder.getCallingPid()
16880                    + ", uid=" + Binder.getCallingUid()
16881                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16882            Slog.w(TAG, msg);
16883            throw new SecurityException(msg);
16884        }
16885        synchronized (this) {
16886            return mStartedUserArray;
16887        }
16888    }
16889
16890    private void updateStartedUserArrayLocked() {
16891        int num = 0;
16892        for (int i=0; i<mStartedUsers.size();  i++) {
16893            UserStartedState uss = mStartedUsers.valueAt(i);
16894            // This list does not include stopping users.
16895            if (uss.mState != UserStartedState.STATE_STOPPING
16896                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16897                num++;
16898            }
16899        }
16900        mStartedUserArray = new int[num];
16901        num = 0;
16902        for (int i=0; i<mStartedUsers.size();  i++) {
16903            UserStartedState uss = mStartedUsers.valueAt(i);
16904            if (uss.mState != UserStartedState.STATE_STOPPING
16905                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16906                mStartedUserArray[num] = mStartedUsers.keyAt(i);
16907                num++;
16908            }
16909        }
16910    }
16911
16912    @Override
16913    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
16914        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16915                != PackageManager.PERMISSION_GRANTED) {
16916            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
16917                    + Binder.getCallingPid()
16918                    + ", uid=" + Binder.getCallingUid()
16919                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16920            Slog.w(TAG, msg);
16921            throw new SecurityException(msg);
16922        }
16923
16924        mUserSwitchObservers.register(observer);
16925    }
16926
16927    @Override
16928    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
16929        mUserSwitchObservers.unregister(observer);
16930    }
16931
16932    private boolean userExists(int userId) {
16933        if (userId == 0) {
16934            return true;
16935        }
16936        UserManagerService ums = getUserManagerLocked();
16937        return ums != null ? (ums.getUserInfo(userId) != null) : false;
16938    }
16939
16940    int[] getUsersLocked() {
16941        UserManagerService ums = getUserManagerLocked();
16942        return ums != null ? ums.getUserIds() : new int[] { 0 };
16943    }
16944
16945    UserManagerService getUserManagerLocked() {
16946        if (mUserManager == null) {
16947            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
16948            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
16949        }
16950        return mUserManager;
16951    }
16952
16953    private int applyUserId(int uid, int userId) {
16954        return UserHandle.getUid(userId, uid);
16955    }
16956
16957    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
16958        if (info == null) return null;
16959        ApplicationInfo newInfo = new ApplicationInfo(info);
16960        newInfo.uid = applyUserId(info.uid, userId);
16961        newInfo.dataDir = USER_DATA_DIR + userId + "/"
16962                + info.packageName;
16963        return newInfo;
16964    }
16965
16966    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
16967        if (aInfo == null
16968                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
16969            return aInfo;
16970        }
16971
16972        ActivityInfo info = new ActivityInfo(aInfo);
16973        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
16974        return info;
16975    }
16976}
16977